##// END OF EJS Templates
autoformat with black
autoformat with black

File last commit:

r25115:b078d256
r25141:0e6cca83
Show More
test_ultratb.py
440 lines | 12.1 KiB | text/x-python | PythonLexer
Thomas Kluyver
Add test for non-ascii tracebacks.
r8326 # encoding: utf-8
Thomas Kluyver
Add failing test for issue gh-1456
r8099 """Tests for IPython.core.ultratb
"""
Thomas Kluyver
Add test for non-ascii tracebacks.
r8326 import io
Craig Citro
Silence tokenization errors in ultratb....
r23973 import logging
Matthias Bussonnier
Move ultratb test to be run on CI.
r21789 import sys
Thomas Kluyver
Add failing test for issue gh-1456
r8099 import os.path
Scott Sanderson
TEST: Add a regression test.
r21719 from textwrap import dedent
Matthias Bussonnier
Move ultratb test to be run on CI.
r21789 import traceback
Thomas Kluyver
Add failing test for issue gh-1456
r8099 import unittest
Srinivas Reddy Thatiparthy
remove python2 specific code
r23064 from unittest import mock
Thomas Kluyver
Truncate tracebacks on recursion error...
r21983
Matthias Bussonnier
Fix state leakage and speedup in test-suite...
r25073 import IPython.core.ultratb as ultratb
from IPython.core.ultratb import ColorTB, VerboseTB, find_recursion
Matthias Bussonnier
Move ultratb test to be run on CI.
r21789
Scott Sanderson
TEST: Add a regression test.
r21719
Thomas Kluyver
Add failing test for issue gh-1456
r8099 from IPython.testing import tools as tt
Thomas Kluyver
Refine unicode tests for ultratb
r12167 from IPython.testing.decorators import onlyif_unicode_paths
Thomas Kluyver
Add failing test for issue gh-1456
r8099 from IPython.utils.syspathcontext import prepended_to_syspath
from IPython.utils.tempdir import TemporaryDirectory
file_1 = """1
2
3
def f():
1/0
"""
file_2 = """def f():
1/0
"""
Matthias Bussonnier
Fix state leakage and speedup in test-suite...
r25073
def recursionlimit(frames):
"""
decorator to set the recursion limit temporarily
"""
def inner(test_function):
def wrapper(*args, **kwargs):
_orig_rec_limit = ultratb._FRAME_RECURSION_LIMIT
Matthias Bussonnier
Misc modifications for pytest comppatibility...
r25115 ultratb._FRAME_RECURSION_LIMIT = 50
Matthias Bussonnier
Fix state leakage and speedup in test-suite...
r25073
rl = sys.getrecursionlimit()
sys.setrecursionlimit(frames)
try:
return test_function(*args, **kwargs)
finally:
sys.setrecursionlimit(rl)
ultratb._FRAME_RECURSION_LIMIT = _orig_rec_limit
return wrapper
return inner
Thomas Kluyver
Add failing test for issue gh-1456
r8099 class ChangedPyFileTest(unittest.TestCase):
def test_changing_py_file(self):
"""Traceback produced if the line where the error occurred is missing?
https://github.com/ipython/ipython/issues/1456
"""
with TemporaryDirectory() as td:
fname = os.path.join(td, "foo.py")
with open(fname, "w") as f:
f.write(file_1)
with prepended_to_syspath(td):
ip.run_cell("import foo")
with tt.AssertPrints("ZeroDivisionError"):
ip.run_cell("foo.f()")
# Make the file shorter, so the line of the error is missing.
with open(fname, "w") as f:
f.write(file_2)
# For some reason, this was failing on the *second* call after
# changing the file, so we call f() twice.
with tt.AssertNotPrints("Internal Python error", channel='stderr'):
with tt.AssertPrints("ZeroDivisionError"):
ip.run_cell("foo.f()")
with tt.AssertPrints("ZeroDivisionError"):
ip.run_cell("foo.f()")
Thomas Kluyver
Add test for non-ascii tracebacks.
r8326
iso_8859_5_file = u'''# coding: iso-8859-5
def fail():
"""дбИЖ"""
1/0 # дбИЖ
'''
class NonAsciiTest(unittest.TestCase):
Thomas Kluyver
Refine unicode tests for ultratb
r12167 @onlyif_unicode_paths
def test_nonascii_path(self):
Thomas Kluyver
Add test for non-ascii tracebacks.
r8326 # Non-ascii directory name as well.
with TemporaryDirectory(suffix=u'é') as td:
Thomas Kluyver
Refine unicode tests for ultratb
r12167 fname = os.path.join(td, u"fooé.py")
with open(fname, "w") as f:
f.write(file_1)
with prepended_to_syspath(td):
ip.run_cell("import foo")
with tt.AssertPrints("ZeroDivisionError"):
ip.run_cell("foo.f()")
def test_iso8859_5(self):
with TemporaryDirectory() as td:
Thomas Kluyver
Add test for non-ascii tracebacks.
r8326 fname = os.path.join(td, 'dfghjkl.py')
with io.open(fname, 'w', encoding='iso-8859-5') as f:
f.write(iso_8859_5_file)
with prepended_to_syspath(td):
ip.run_cell("from dfghjkl import fail")
with tt.AssertPrints("ZeroDivisionError"):
with tt.AssertPrints(u'дбИЖ', suppress=False):
ip.run_cell('fail()')
Min RK
test nonascii exceptions
r22268
def test_nonascii_msg(self):
cell = u"raise Exception('é')"
expected = u"Exception('é')"
ip.run_cell("%xmode plain")
with tt.AssertPrints(expected):
ip.run_cell(cell)
ip.run_cell("%xmode verbose")
with tt.AssertPrints(expected):
ip.run_cell(cell)
ip.run_cell("%xmode context")
with tt.AssertPrints(expected):
ip.run_cell(cell)
Thomas Kluyver
Add failing test for IndentationError display
r8416
Dan Allan
ENH: Add a 'Minimal' xmode option....
r24849 ip.run_cell("%xmode minimal")
with tt.AssertPrints(u"Exception: é"):
ip.run_cell(cell)
Scott Sanderson
TEST: Add a regression test.
r21719
Dan Allan
TST: Put %xmode back after testing new Minimal mode.
r24852 # Put this back into Context mode for later tests.
ip.run_cell("%xmode context")
Scott Sanderson
TEST: Add a regression test.
r21719 class NestedGenExprTestCase(unittest.TestCase):
"""
Regression test for the following issues:
https://github.com/ipython/ipython/issues/8293
https://github.com/ipython/ipython/issues/8205
"""
def test_nested_genexpr(self):
code = dedent(
"""\
class SpecificException(Exception):
pass
def foo(x):
raise SpecificException("Success!")
sum(sum(foo(x) for _ in [0]) for x in [0])
"""
)
with tt.AssertPrints('SpecificException: Success!', suppress=False):
ip.run_cell(code)
Thomas Kluyver
Add failing test for IndentationError display
r8416 indentationerror_file = """if True:
zoon()
"""
class IndentationErrorTest(unittest.TestCase):
def test_indentationerror_shows_line(self):
# See issue gh-2398
with tt.AssertPrints("IndentationError"):
with tt.AssertPrints("zoon()", suppress=False):
ip.run_cell(indentationerror_file)
with TemporaryDirectory() as td:
fname = os.path.join(td, "foo.py")
with open(fname, "w") as f:
f.write(indentationerror_file)
with tt.AssertPrints("IndentationError"):
with tt.AssertPrints("zoon()", suppress=False):
ip.magic('run %s' % fname)
Jez Ng
Fix traceback handling of SyntaxErrors without linenos.
r8589
Thomas Kluyver
Add failing test for SyntaxError display
r12543 se_file_1 = """1
2
7/
"""
se_file_2 = """7/
"""
Jez Ng
Fix traceback handling of SyntaxErrors without linenos.
r8589 class SyntaxErrorTest(unittest.TestCase):
def test_syntaxerror_without_lineno(self):
with tt.AssertNotPrints("TypeError"):
with tt.AssertPrints("line unknown"):
ip.run_cell("raise SyntaxError()")
Thomas Kluyver
Add failing test for SyntaxError display
r12543
Piotr Zielinski
Verbose error message for syntax error occuring at runtime
r23611 def test_syntaxerror_no_stacktrace_at_compile_time(self):
syntax_error_at_compile_time = """
def foo():
..
"""
with tt.AssertPrints("SyntaxError"):
ip.run_cell(syntax_error_at_compile_time)
with tt.AssertNotPrints("foo()"):
ip.run_cell(syntax_error_at_compile_time)
def test_syntaxerror_stacktrace_when_running_compiled_code(self):
syntax_error_at_runtime = """
def foo():
eval("..")
def bar():
foo()
bar()
"""
with tt.AssertPrints("SyntaxError"):
ip.run_cell(syntax_error_at_runtime)
# Assert syntax error during runtime generate stacktrace
with tt.AssertPrints(["foo()", "bar()"]):
ip.run_cell(syntax_error_at_runtime)
Matthias Bussonnier
Fix state leakage and speedup in test-suite...
r25073 del ip.user_ns['bar']
del ip.user_ns['foo']
Piotr Zielinski
Verbose error message for syntax error occuring at runtime
r23611
Thomas Kluyver
Add failing test for SyntaxError display
r12543 def test_changing_py_file(self):
with TemporaryDirectory() as td:
fname = os.path.join(td, "foo.py")
with open(fname, 'w') as f:
f.write(se_file_1)
with tt.AssertPrints(["7/", "SyntaxError"]):
ip.magic("run " + fname)
# Modify the file
with open(fname, 'w') as f:
f.write(se_file_2)
# The SyntaxError should point to the correct line
with tt.AssertPrints(["7/", "SyntaxError"]):
ip.magic("run " + fname)
Thomas Kluyver
Add failing test for gh-4361
r12950
def test_non_syntaxerror(self):
# SyntaxTB may be called with an error other than a SyntaxError
# See e.g. gh-4361
try:
raise ValueError('QWERTY')
except ValueError:
with tt.AssertPrints('QWERTY'):
ip.showsyntaxerror()
Justyna Ilczuk
i1673 add tests for python3 exceptions
r17161
class Python3ChainedExceptionsTest(unittest.TestCase):
DIRECT_CAUSE_ERROR_CODE = """
try:
x = 1 + 2
print(not_defined_here)
except Exception as e:
x += 55
x - 1
y = {}
raise KeyError('uh') from e
"""
EXCEPTION_DURING_HANDLING_CODE = """
try:
x = 1 + 2
print(not_defined_here)
except Exception as e:
x += 55
x - 1
y = {}
raise KeyError('uh')
"""
Thomas Kluyver
Add failing test for suppressing exception chaining
r21519 SUPPRESS_CHAINING_CODE = """
try:
1/0
except Exception:
raise ValueError("Yikes") from None
"""
Justyna Ilczuk
i1673 add tests for python3 exceptions
r17161 def test_direct_cause_error(self):
Srinivas Reddy Thatiparthy
cleanup
r23081 with tt.AssertPrints(["KeyError", "NameError", "direct cause"]):
ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE)
Justyna Ilczuk
i1673 add tests for python3 exceptions
r17161
def test_exception_during_handling_error(self):
Srinivas Reddy Thatiparthy
cleanup
r23081 with tt.AssertPrints(["KeyError", "NameError", "During handling"]):
ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE)
Thomas Kluyver
Add failing test for suppressing exception chaining
r21519
def test_suppress_exception_chaining(self):
Srinivas Reddy Thatiparthy
cleanup
r23081 with tt.AssertNotPrints("ZeroDivisionError"), \
tt.AssertPrints("ValueError", suppress=False):
ip.run_cell(self.SUPPRESS_CHAINING_CODE)
Matthias Bussonnier
Move ultratb test to be run on CI.
r21789
Thomas Kluyver
Truncate tracebacks on recursion error...
r21983 class RecursionTest(unittest.TestCase):
DEFINITIONS = """
def non_recurs():
1/0
def r1():
r1()
def r3a():
r3b()
def r3b():
r3c()
def r3c():
r3a()
def r3o1():
r3a()
def r3o2():
r3o1()
"""
def setUp(self):
ip.run_cell(self.DEFINITIONS)
def test_no_recursion(self):
with tt.AssertNotPrints("frames repeated"):
ip.run_cell("non_recurs()")
Matthias Bussonnier
Misc modifications for pytest comppatibility...
r25115 @recursionlimit(150)
Thomas Kluyver
Truncate tracebacks on recursion error...
r21983 def test_recursion_one_frame(self):
with tt.AssertPrints("1 frames repeated"):
ip.run_cell("r1()")
Matthias Bussonnier
Misc modifications for pytest comppatibility...
r25115 @recursionlimit(150)
Thomas Kluyver
Truncate tracebacks on recursion error...
r21983 def test_recursion_three_frames(self):
with tt.AssertPrints("3 frames repeated"):
ip.run_cell("r3o2()")
Matthias Bussonnier
Misc modifications for pytest comppatibility...
r25115 @recursionlimit(150)
Thomas Kluyver
Truncate tracebacks on recursion error...
r21983 def test_find_recursion(self):
captured = []
def capture_exc(*args, **kwargs):
captured.append(sys.exc_info())
with mock.patch.object(ip, 'showtraceback', capture_exc):
ip.run_cell("r3o2()")
self.assertEqual(len(captured), 1)
etype, evalue, tb = captured[0]
self.assertIn("recursion", str(evalue))
records = ip.InteractiveTB.get_records(tb, 3, ip.InteractiveTB.tb_offset)
for r in records[:10]:
print(r[1:4])
# The outermost frames should be:
# 0: the 'cell' that was running when the exception came up
# 1: r3o2()
# 2: r3o1()
# 3: r3a()
# Then repeating r3b, r3c, r3a
last_unique, repeat_length = find_recursion(etype, evalue, records)
self.assertEqual(last_unique, 2)
self.assertEqual(repeat_length, 3)
Matthias Bussonnier
Move ultratb test to be run on CI.
r21789 #----------------------------------------------------------------------------
# module testing (minimal)
Paul Ivanov
remove sys_version for Python 3...
r22959 def test_handlers():
def spam(c, d_e):
(d, e) = d_e
x = c + d
y = c * d
foo(x, y)
def foo(a, b, bar=1):
eggs(a, b + bar)
def eggs(f, g, z=globals()):
h = f + g
i = f - g
return h / i
buff = io.StringIO()
buff.write('')
buff.write('*** Before ***')
try:
buff.write(spam(1, (2, 3)))
except:
traceback.print_exc(file=buff)
handler = ColorTB(ostream=buff)
buff.write('*** ColorTB ***')
try:
buff.write(spam(1, (2, 3)))
except:
handler(*sys.exc_info())
buff.write('')
handler = VerboseTB(ostream=buff)
buff.write('*** VerboseTB ***')
try:
buff.write(spam(1, (2, 3)))
except:
handler(*sys.exc_info())
buff.write('')
Matthias Bussonnier
Move ultratb test to be run on CI.
r21789
Matthias Bussonnier
Skip tests that now seem to pass on 3.8.
r24926 from IPython.testing.decorators import skipif
Craig Citro
Silence tokenization errors in ultratb....
r23973
class TokenizeFailureTest(unittest.TestCase):
"""Tests related to https://github.com/ipython/ipython/issues/6864."""
Matthias Bussonnier
comment why the changes and for which python version
r24932 # that appear to test that we are handling an exception that can be thrown
# by the tokenizer due to a bug that seem to have been fixed in 3.8, though
# I'm unsure if other sequences can make it raise this error. Let's just
# skip in 3.8 for now
Matthias Bussonnier
Skip tests that now seem to pass on 3.8.
r24926 @skipif(sys.version_info > (3,8))
Craig Citro
Silence tokenization errors in ultratb....
r23973 def testLogging(self):
message = "An unexpected error occurred while tokenizing input"
cell = 'raise ValueError("""a\nb""")'
stream = io.StringIO()
handler = logging.StreamHandler(stream)
logger = logging.getLogger()
loglevel = logger.level
logger.addHandler(handler)
self.addCleanup(lambda: logger.removeHandler(handler))
self.addCleanup(lambda: logger.setLevel(loglevel))
logger.setLevel(logging.INFO)
with tt.AssertNotPrints(message):
ip.run_cell(cell)
self.assertNotIn(message, stream.getvalue())
logger.setLevel(logging.DEBUG)
with tt.AssertNotPrints(message):
ip.run_cell(cell)
self.assertIn(message, stream.getvalue())