diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index f61456d..c9177b8 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2533,7 +2533,8 @@ class InteractiveShell(SingletonConfigurable): except: if kw['raise_exceptions']: raise - self.showtraceback() + # tb offset is 2 because we wrap execfile + self.showtraceback(tb_offset=2) def safe_execfile_ipy(self, fname): """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax. diff --git a/IPython/core/tests/test_run.py b/IPython/core/tests/test_run.py index 2c4e098..877c1a7 100644 --- a/IPython/core/tests/test_run.py +++ b/IPython/core/tests/test_run.py @@ -28,6 +28,7 @@ from nose import SkipTest from IPython.testing import decorators as dec from IPython.testing import tools as tt from IPython.utils import py3compat +from IPython.utils.io import capture_output from IPython.utils.tempdir import TemporaryDirectory from IPython.core import debugger @@ -474,3 +475,40 @@ def test_run__name__(): _ip.magic('run -n {}'.format(path)) nt.assert_equal(_ip.user_ns.pop('q'), 'foo') + +def test_run_tb(): + """Test traceback offset in %run""" + with TemporaryDirectory() as td: + path = pjoin(td, 'foo.py') + with open(path, 'w') as f: + f.write('\n'.join([ + "def foo():", + " return bar()", + "def bar():", + " raise RuntimeError('hello!')", + "foo()", + ])) + with capture_output() as io: + _ip.magic('run {}'.format(path)) + out = io.stdout + nt.assert_not_in("execfile", out) + nt.assert_in("RuntimeError", out) + nt.assert_equal(out.count("---->"), 3) + +def test_script_tb(): + """Test traceback offset in `ipython script.py`""" + with TemporaryDirectory() as td: + path = pjoin(td, 'foo.py') + with open(path, 'w') as f: + f.write('\n'.join([ + "def foo():", + " return bar()", + "def bar():", + " raise RuntimeError('hello!')", + "foo()", + ])) + out, err = tt.ipexec(path) + nt.assert_not_in("execfile", out) + nt.assert_in("RuntimeError", out) + nt.assert_equal(out.count("---->"), 3) + diff --git a/IPython/utils/py3compat.py b/IPython/utils/py3compat.py index 822dad3..d41a975 100644 --- a/IPython/utils/py3compat.py +++ b/IPython/utils/py3compat.py @@ -181,9 +181,6 @@ else: def MethodType(func, instance): return types.MethodType(func, instance, type(instance)) - # don't override system execfile on 2.x: - execfile = execfile - def doctest_refactor_print(func_or_str): return func_or_str