Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reapply monkeypatch to inspect.findsource() #2232

Merged
merged 2 commits into from
Aug 2, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 51 additions & 0 deletions IPython/core/tests/test_ultratb.py
Original file line number Diff line number Diff line change
@@ -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()")
19 changes: 6 additions & 13 deletions IPython/core/ultratb.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,10 @@ def inspect_error():
error('Internal Python error in the inspect module.\n'
'Below is the traceback from this internal error.\n')


# N.B. This function is a monkeypatch we are currently not applying.
# It was written some time ago, to fix an apparent Python bug with
# codeobj.co_firstlineno . Unfortunately, we don't know under what conditions
# the bug occurred, so we can't tell if it has been fixed. If it reappears, we
# will apply the monkeypatch again. Also, note that findsource() is not called
# by our code at this time - we don't know if it was when the monkeypatch was
# written, or if the monkeypatch is needed for some other code (like a debugger).
# For the discussion about not applying it, see gh-1229. TK, Jan 2011.
# This function is a monkeypatch we apply to the Python inspect module. We have
# now found when it's needed (see discussion on issue gh-1456), and we have a
# test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
# the monkeypatch is not applied. TK, Aug 2012.
def findsource(object):
"""Return the entire source file and starting line number for an object.

Expand Down Expand Up @@ -210,10 +205,8 @@ def findsource(object):
return lines, lnum
raise IOError('could not find code object')

# Not applying the monkeypatch - see above the function for details. TK, Jan 2012
# Monkeypatch inspect to apply our bugfix. This code only works with py25
#if sys.version_info[:2] >= (2,5):
# inspect.findsource = findsource
# Monkeypatch inspect to apply our bugfix. This code only works with Python >= 2.5
inspect.findsource = findsource

def fix_frame_records_filenames(records):
"""Try to fix the filenames in each record from inspect.getinnerframes().
Expand Down
15 changes: 12 additions & 3 deletions IPython/testing/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,10 @@ def write(self, s):
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.
Expand Down Expand Up @@ -337,7 +340,13 @@ def __exit__(self, etype, value, traceback):
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.

Expand All @@ -346,7 +355,7 @@ def __exit__(self, etype, value, traceback):
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
Expand Down