test_ultratb.py
222 lines
| 6.3 KiB
| text/x-python
|
PythonLexer
Thomas Kluyver
|
r8326 | # encoding: utf-8 | ||
Thomas Kluyver
|
r8099 | """Tests for IPython.core.ultratb | ||
""" | ||||
Thomas Kluyver
|
r8326 | import io | ||
Thomas Kluyver
|
r8099 | import os.path | ||
Scott Sanderson
|
r21719 | from textwrap import dedent | ||
Thomas Kluyver
|
r8099 | import unittest | ||
Scott Sanderson
|
r21719 | |||
Thomas Kluyver
|
r8099 | from IPython.testing import tools as tt | ||
Thomas Kluyver
|
r12167 | from IPython.testing.decorators import onlyif_unicode_paths | ||
Thomas Kluyver
|
r8099 | from IPython.utils.syspathcontext import prepended_to_syspath | ||
from IPython.utils.tempdir import TemporaryDirectory | ||||
Justyna Ilczuk
|
r17161 | from IPython.utils.py3compat import PY3 | ||
Thomas Kluyver
|
r8099 | |||
ip = get_ipython() | ||||
file_1 = """1 | ||||
2 | ||||
3 | ||||
def f(): | ||||
1/0 | ||||
""" | ||||
file_2 = """def f(): | ||||
1/0 | ||||
""" | ||||
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
|
r8326 | |||
iso_8859_5_file = u'''# coding: iso-8859-5 | ||||
def fail(): | ||||
"""дбИЖ""" | ||||
1/0 # дбИЖ | ||||
''' | ||||
class NonAsciiTest(unittest.TestCase): | ||||
Thomas Kluyver
|
r12167 | @onlyif_unicode_paths | ||
def test_nonascii_path(self): | ||||
Thomas Kluyver
|
r8326 | # Non-ascii directory name as well. | ||
with TemporaryDirectory(suffix=u'é') as td: | ||||
Thomas Kluyver
|
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
|
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()') | ||||
Thomas Kluyver
|
r8416 | |||
Scott Sanderson
|
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
|
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
|
r8589 | |||
Thomas Kluyver
|
r12543 | se_file_1 = """1 | ||
2 | ||||
7/ | ||||
""" | ||||
se_file_2 = """7/ | ||||
""" | ||||
Jez Ng
|
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
|
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
|
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
|
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
|
r21519 | SUPPRESS_CHAINING_CODE = """ | ||
try: | ||||
1/0 | ||||
except Exception: | ||||
raise ValueError("Yikes") from None | ||||
""" | ||||
Justyna Ilczuk
|
r17161 | def test_direct_cause_error(self): | ||
if PY3: | ||||
with tt.AssertPrints(["KeyError", "NameError", "direct cause"]): | ||||
ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE) | ||||
def test_exception_during_handling_error(self): | ||||
if PY3: | ||||
with tt.AssertPrints(["KeyError", "NameError", "During handling"]): | ||||
ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE) | ||||
Thomas Kluyver
|
r21519 | |||
def test_suppress_exception_chaining(self): | ||||
if PY3: | ||||
with tt.AssertNotPrints("ZeroDivisionError"), \ | ||||
tt.AssertPrints("ValueError", suppress=False): | ||||
ip.run_cell(self.SUPPRESS_CHAINING_CODE) | ||||