From e023dcb20b62e31c94fc2b4ccea5739609629173 2021-12-24 12:01:25 From: Matthias Bussonnier Date: 2021-12-24 12:01:25 Subject: [PATCH] Add line number next to the file in the traceback Fix some "skip" error messages and docstrings for test. We use filename:lineno as this syntax is understood by many tools to directly open the relevant file at given line. --- diff --git a/IPython/core/tests/test_completer.py b/IPython/core/tests/test_completer.py index 59f8fee..db44d51 100644 --- a/IPython/core/tests/test_completer.py +++ b/IPython/core/tests/test_completer.py @@ -419,9 +419,9 @@ class TestCompleter(unittest.TestCase): with provisionalcompleter(): ip.Completer.use_jedi = jedi_status matches = c.all_completions("TestCl") - assert matches == ['TestClass'], jedi_status + assert matches == ["TestClass"], (jedi_status, matches) matches = c.all_completions("TestClass.") - assert len(matches) > 2, jedi_status + assert len(matches) > 2, (jedi_status, matches) matches = c.all_completions("TestClass.a") assert matches == ['TestClass.a', 'TestClass.a1'], jedi_status diff --git a/IPython/core/tests/test_iplib.py b/IPython/core/tests/test_iplib.py index 7fa4bba..94ce518 100644 --- a/IPython/core/tests/test_iplib.py +++ b/IPython/core/tests/test_iplib.py @@ -45,11 +45,11 @@ def doctest_tb_plain(): In [19]: run simpleerr.py Traceback (most recent call last): - ...line ..., in + File ...:... in bar(mode) - ...line ..., in bar + File ...:... in bar div0() - ...line ..., in div0 + File ...:... in div0 x/y ZeroDivisionError: ... """ @@ -132,13 +132,13 @@ def doctest_tb_sysexit(): In [20]: %tb Traceback (most recent call last): - File ..., in execfile + File ...:... in execfile exec(compiler(f.read(), fname, "exec"), glob, loc) - File ..., in + File ...:... in bar(mode) - File ..., in bar + File ...:... in bar sysexit(stat, mode) - File ..., in sysexit + File ...:... in sysexit raise SystemExit(stat, f"Mode = {mode}") SystemExit: (2, 'Mode = exit') diff --git a/IPython/core/tests/test_ultratb.py b/IPython/core/tests/test_ultratb.py index 66a7a95..4239980 100644 --- a/IPython/core/tests/test_ultratb.py +++ b/IPython/core/tests/test_ultratb.py @@ -188,10 +188,6 @@ se_file_2 = """7/ """ class SyntaxErrorTest(unittest.TestCase): - def test_syntaxerror_without_lineno(self): - with tt.AssertNotPrints("TypeError"): - with tt.AssertPrints("line unknown"): - ip.run_cell("raise SyntaxError()") def test_syntaxerror_no_stacktrace_at_compile_time(self): syntax_error_at_compile_time = """ diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index 696103f..e947839 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -169,7 +169,7 @@ def _format_traceback_lines(lines, Colors, has_colors, lvals): return res -def _format_filename(file, ColorFilename, ColorNormal): +def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None): """ Format filename lines with `In [n]` if it's the nth code cell or `File *.py` if it's a module. @@ -185,14 +185,17 @@ def _format_filename(file, ColorFilename, ColorNormal): if ipinst is not None and file in ipinst.compile._filename_map: file = "[%s]" % ipinst.compile._filename_map[file] - tpl_link = "Input %sIn %%s%s" % (ColorFilename, ColorNormal) + tpl_link = f"Input {ColorFilename}In {{file}}{ColorNormal}" else: file = util_path.compress_user( py3compat.cast_unicode(file, util_path.fs_encoding) ) - tpl_link = "File %s%%s%s" % (ColorFilename, ColorNormal) + if lineno is None: + tpl_link = f"File {ColorFilename}{{file}}{ColorNormal}" + else: + tpl_link = f"File {ColorFilename}{{file}}:{{lineno}}{ColorNormal}" - return tpl_link % file + return tpl_link.format(file=file, lineno=lineno) #--------------------------------------------------------------------------- # Module classes @@ -439,11 +442,10 @@ class ListTB(TBTools): Colors = self.Colors list = [] for filename, lineno, name, line in extracted_list[:-1]: - item = " %s, line %s%d%s, in %s%s%s\n" % ( - _format_filename(filename, Colors.filename, Colors.Normal), - Colors.lineno, - lineno, - Colors.Normal, + item = " %s in %s%s%s\n" % ( + _format_filename( + filename, Colors.filename, Colors.Normal, lineno=lineno + ), Colors.name, name, Colors.Normal, @@ -453,12 +455,11 @@ class ListTB(TBTools): list.append(item) # Emphasize the last entry filename, lineno, name, line = extracted_list[-1] - item = "%s %s, line %s%d%s, in %s%s%s%s\n" % ( - Colors.normalEm, - _format_filename(filename, Colors.filenameEm, Colors.normalEm), - Colors.linenoEm, - lineno, + item = "%s %s in %s%s%s%s\n" % ( Colors.normalEm, + _format_filename( + filename, Colors.filenameEm, Colors.normalEm, lineno=lineno + ), Colors.nameEm, name, Colors.normalEm, @@ -501,14 +502,15 @@ class ListTB(TBTools): lineno = "unknown" textline = "" list.append( - "%s %s, line %s%s%s\n" + "%s %s%s\n" % ( Colors.normalEm, _format_filename( - value.filename, Colors.filenameEm, Colors.normalEm + value.filename, + Colors.filenameEm, + Colors.normalEm, + lineno=(None if lineno == "unknown" else lineno), ), - Colors.linenoEm, - lineno, Colors.Normal, ) ) @@ -628,27 +630,35 @@ class VerboseTB(TBTools): return ' %s[... skipping similar frames: %s]%s\n' % ( Colors.excName, frame_info.description, ColorsNormal) - indent = ' ' * INDENT_SIZE - em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal) - tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, - ColorsNormal) - tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ - (Colors.vName, Colors.valEm, ColorsNormal) - tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) + indent = " " * INDENT_SIZE + em_normal = "%s\n%s%s" % (Colors.valEm, indent, ColorsNormal) + tpl_call = f"in {Colors.vName}{{file}}{Colors.valEm}{{scope}}{ColorsNormal}" + tpl_call_fail = "in %s%%s%s(***failed resolving arguments***)%s" % ( + Colors.vName, + Colors.valEm, + ColorsNormal, + ) + tpl_name_val = "%%s %s= %%s%s" % (Colors.valEm, ColorsNormal) - link = _format_filename(frame_info.filename, Colors.filenameEm, ColorsNormal) + link = _format_filename( + frame_info.filename, + Colors.filenameEm, + ColorsNormal, + lineno=frame_info.lineno, + ) args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame) func = frame_info.executing.code_qualname() - if func == '': - call = tpl_call % (func, '') + if func == "": + call = tpl_call.format(file=func, scope="") else: # Decide whether to include variable details or not var_repr = eqrepr if self.include_vars else nullrepr try: - call = tpl_call % (func, inspect.formatargvalues(args, - varargs, varkw, - locals_, formatvalue=var_repr)) + scope = inspect.formatargvalues( + args, varargs, varkw, locals_, formatvalue=var_repr + ) + call = tpl_call.format(file=func, scope=scope) except KeyError: # This happens in situations like errors inside generator # expressions, where local variables are listed in the diff --git a/IPython/testing/plugin/pytest_ipdoctest.py b/IPython/testing/plugin/pytest_ipdoctest.py index a58d086..603e33c 100644 --- a/IPython/testing/plugin/pytest_ipdoctest.py +++ b/IPython/testing/plugin/pytest_ipdoctest.py @@ -503,7 +503,7 @@ def _check_all_skipped(test: "doctest.DocTest") -> None: all_skipped = all(x.options.get(doctest.SKIP, False) for x in test.examples) if all_skipped: - pytest.skip("all tests skipped by +SKIP option") + pytest.skip("all docstests skipped by +SKIP option") def _is_mocked(obj: object) -> bool: