/Lib/test/test_traceback.py

http://unladen-swallow.googlecode.com/ · Python · 180 lines · 120 code · 30 blank · 30 comment · 16 complexity · 5b796abfe89659459cffad949e1c7d79 MD5 · raw file

  1. """Test cases for traceback module"""
  2. from _testcapi import traceback_print
  3. from StringIO import StringIO
  4. import sys
  5. import unittest
  6. from test.test_support import run_unittest, is_jython, Error
  7. import traceback
  8. try:
  9. raise KeyError
  10. except KeyError:
  11. type_, value, tb = sys.exc_info()
  12. file_ = StringIO()
  13. traceback_print(tb, file_)
  14. example_traceback = file_.getvalue()
  15. else:
  16. raise Error("unable to create test traceback string")
  17. class TracebackCases(unittest.TestCase):
  18. # For now, a very minimal set of tests. I want to be sure that
  19. # formatting of SyntaxErrors works based on changes for 2.1.
  20. def get_exception_format(self, func, exc):
  21. try:
  22. func()
  23. except exc, value:
  24. return traceback.format_exception_only(exc, value)
  25. else:
  26. raise ValueError, "call did not raise exception"
  27. def syntax_error_with_caret(self):
  28. compile("def fact(x):\n\treturn x!\n", "?", "exec")
  29. def syntax_error_without_caret(self):
  30. # XXX why doesn't compile raise the same traceback?
  31. import test.badsyntax_nocaret
  32. def syntax_error_bad_indentation(self):
  33. compile("def spam():\n print 1\n print 2", "?", "exec")
  34. def test_caret(self):
  35. err = self.get_exception_format(self.syntax_error_with_caret,
  36. SyntaxError)
  37. self.assert_(len(err) == 4)
  38. self.assert_(err[1].strip() == "return x!")
  39. self.assert_("^" in err[2]) # third line has caret
  40. self.assert_(err[1].find("!") == err[2].find("^")) # in the right place
  41. def test_nocaret(self):
  42. if is_jython:
  43. # jython adds a caret in this case (why shouldn't it?)
  44. return
  45. err = self.get_exception_format(self.syntax_error_without_caret,
  46. SyntaxError)
  47. self.assert_(len(err) == 3)
  48. self.assert_(err[1].strip() == "[x for x in x] = x")
  49. def test_bad_indentation(self):
  50. err = self.get_exception_format(self.syntax_error_bad_indentation,
  51. IndentationError)
  52. self.assert_(len(err) == 4)
  53. self.assert_(err[1].strip() == "print 2")
  54. self.assert_("^" in err[2])
  55. self.assert_(err[1].find("2") == err[2].find("^"))
  56. def test_bug737473(self):
  57. import sys, os, tempfile, time
  58. savedpath = sys.path[:]
  59. testdir = tempfile.mkdtemp()
  60. try:
  61. sys.path.insert(0, testdir)
  62. testfile = os.path.join(testdir, 'test_bug737473.py')
  63. print >> open(testfile, 'w'), """
  64. def test():
  65. raise ValueError"""
  66. if 'test_bug737473' in sys.modules:
  67. del sys.modules['test_bug737473']
  68. import test_bug737473
  69. try:
  70. test_bug737473.test()
  71. except ValueError:
  72. # this loads source code to linecache
  73. traceback.extract_tb(sys.exc_traceback)
  74. # If this test runs too quickly, test_bug737473.py's mtime
  75. # attribute will remain unchanged even if the file is rewritten.
  76. # Consequently, the file would not reload. So, added a sleep()
  77. # delay to assure that a new, distinct timestamp is written.
  78. # Since WinME with FAT32 has multisecond resolution, more than
  79. # three seconds are needed for this test to pass reliably :-(
  80. time.sleep(4)
  81. print >> open(testfile, 'w'), """
  82. def test():
  83. raise NotImplementedError"""
  84. reload(test_bug737473)
  85. try:
  86. test_bug737473.test()
  87. except NotImplementedError:
  88. src = traceback.extract_tb(sys.exc_traceback)[-1][-1]
  89. self.failUnlessEqual(src, 'raise NotImplementedError')
  90. finally:
  91. sys.path[:] = savedpath
  92. for f in os.listdir(testdir):
  93. os.unlink(os.path.join(testdir, f))
  94. os.rmdir(testdir)
  95. def test_base_exception(self):
  96. # Test that exceptions derived from BaseException are formatted right
  97. e = KeyboardInterrupt()
  98. lst = traceback.format_exception_only(e.__class__, e)
  99. self.assertEqual(lst, ['KeyboardInterrupt\n'])
  100. # String exceptions are deprecated, but legal. The quirky form with
  101. # separate "type" and "value" tends to break things, because
  102. # not isinstance(value, type)
  103. # and a string cannot be the first argument to issubclass.
  104. #
  105. # Note that sys.last_type and sys.last_value do not get set if an
  106. # exception is caught, so we sort of cheat and just emulate them.
  107. #
  108. # test_string_exception1 is equivalent to
  109. #
  110. # >>> raise "String Exception"
  111. #
  112. # test_string_exception2 is equivalent to
  113. #
  114. # >>> raise "String Exception", "String Value"
  115. #
  116. def test_string_exception1(self):
  117. str_type = "String Exception"
  118. err = traceback.format_exception_only(str_type, None)
  119. self.assertEqual(len(err), 1)
  120. self.assertEqual(err[0], str_type + '\n')
  121. def test_string_exception2(self):
  122. str_type = "String Exception"
  123. str_value = "String Value"
  124. err = traceback.format_exception_only(str_type, str_value)
  125. self.assertEqual(len(err), 1)
  126. self.assertEqual(err[0], str_type + ': ' + str_value + '\n')
  127. def test_format_exception_only_bad__str__(self):
  128. class X(Exception):
  129. def __str__(self):
  130. 1/0
  131. err = traceback.format_exception_only(X, X())
  132. self.assertEqual(len(err), 1)
  133. str_value = '<unprintable %s object>' % X.__name__
  134. self.assertEqual(err[0], X.__name__ + ': ' + str_value + '\n')
  135. def test_without_exception(self):
  136. err = traceback.format_exception_only(None, None)
  137. self.assertEqual(err, ['None\n'])
  138. class TracebackFormatTests(unittest.TestCase):
  139. def test_traceback_indentation(self):
  140. # Make sure that the traceback is properly indented.
  141. tb_lines = example_traceback.splitlines()
  142. self.assertEquals(len(tb_lines), 3)
  143. banner, location, source_line = tb_lines
  144. self.assert_(banner.startswith('Traceback'))
  145. self.assert_(location.startswith(' File'))
  146. self.assert_(source_line.startswith(' raise'))
  147. def test_main():
  148. run_unittest(TracebackCases, TracebackFormatTests)
  149. if __name__ == "__main__":
  150. test_main()