diff --git a/IPython/core/tests/test_ultratb.py b/IPython/core/tests/test_ultratb.py new file mode 100644 index 0000000..b235116 --- /dev/null +++ b/IPython/core/tests/test_ultratb.py @@ -0,0 +1,51 @@ +"""Tests for IPython.core.ultratb +""" + +import os.path +import unittest + +from IPython.testing import tools as tt +from IPython.utils.syspathcontext import prepended_to_syspath +from IPython.utils.tempdir import TemporaryDirectory + +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()") diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py index 79ca7f3..48a2869 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -306,7 +306,10 @@ else: super(MyStringIO, self).write(s) notprinted_msg = """Did not find {0!r} in printed output (on {1}): -{2!r}""" +------- +{2!s} +------- +""" class AssertPrints(object): """Context manager for testing that code prints certain text. @@ -337,7 +340,13 @@ class AssertPrints(object): printed = self.buffer.getvalue() assert self.s in printed, notprinted_msg.format(self.s, self.channel, printed) return False - + +printed_msg = """Found {0!r} in printed output (on {1}): +------- +{2!s} +------- +""" + class AssertNotPrints(AssertPrints): """Context manager for checking that certain output *isn't* produced. @@ -346,7 +355,7 @@ class AssertNotPrints(AssertPrints): self.tee.flush() setattr(sys, self.channel, self.orig_stream) printed = self.buffer.getvalue() - assert self.s not in printed, notprinted_msg.format(self.s, self.channel, printed) + assert self.s not in printed, printed_msg.format(self.s, self.channel, printed) return False @contextmanager