Show More
@@ -0,0 +1,50 b'' | |||||
|
1 | Restore line numbers for Input | |||
|
2 | ================================== | |||
|
3 | ||||
|
4 | Line number information in tracebacks from input are restored. | |||
|
5 | Line numbers from input were removed during the transition to v8 enhanced traceback reporting. | |||
|
6 | ||||
|
7 | So, instead of:: | |||
|
8 | ||||
|
9 | --------------------------------------------------------------------------- | |||
|
10 | ZeroDivisionError Traceback (most recent call last) | |||
|
11 | Input In [3], in <cell line: 1>() | |||
|
12 | ----> 1 myfunc(2) | |||
|
13 | ||||
|
14 | Input In [2], in myfunc(z) | |||
|
15 | 1 def myfunc(z): | |||
|
16 | ----> 2 foo.boo(z-1) | |||
|
17 | ||||
|
18 | File ~/code/python/ipython/foo.py:3, in boo(x) | |||
|
19 | 2 def boo(x): | |||
|
20 | ----> 3 return 1/(1-x) | |||
|
21 | ||||
|
22 | ZeroDivisionError: division by zero | |||
|
23 | ||||
|
24 | The error traceback now looks like:: | |||
|
25 | ||||
|
26 | --------------------------------------------------------------------------- | |||
|
27 | ZeroDivisionError Traceback (most recent call last) | |||
|
28 | Cell In [3], line 1 | |||
|
29 | ----> 1 myfunc(2) | |||
|
30 | ||||
|
31 | Cell In [2], line 2, in myfunc(z) | |||
|
32 | 1 def myfunc(z): | |||
|
33 | ----> 2 foo.boo(z-1) | |||
|
34 | ||||
|
35 | File ~/code/python/ipython/foo.py:3, in boo(x) | |||
|
36 | 2 def boo(x): | |||
|
37 | ----> 3 return 1/(1-x) | |||
|
38 | ||||
|
39 | ZeroDivisionError: division by zero | |||
|
40 | ||||
|
41 | or, with xmode=Plain:: | |||
|
42 | ||||
|
43 | Traceback (most recent call last): | |||
|
44 | Cell In [12], line 1 | |||
|
45 | myfunc(2) | |||
|
46 | Cell In [6], line 2 in myfunc | |||
|
47 | foo.boo(z-1) | |||
|
48 | File ~/code/python/ipython/foo.py:3 in boo | |||
|
49 | return 1/(1-x) | |||
|
50 | ZeroDivisionError: division by zero |
@@ -16,7 +16,6 b' import ast' | |||||
16 | import atexit |
|
16 | import atexit | |
17 | import bdb |
|
17 | import bdb | |
18 | import builtins as builtin_mod |
|
18 | import builtins as builtin_mod | |
19 | import dis |
|
|||
20 | import functools |
|
19 | import functools | |
21 | import inspect |
|
20 | import inspect | |
22 | import os |
|
21 | import os | |
@@ -3212,29 +3211,6 b' class InteractiveShell(SingletonConfigurable):' | |||||
3212 | ast.fix_missing_locations(node) |
|
3211 | ast.fix_missing_locations(node) | |
3213 | return node |
|
3212 | return node | |
3214 |
|
3213 | |||
3215 | def _update_code_co_name(self, code): |
|
|||
3216 | """Python 3.10 changed the behaviour so that whenever a code object |
|
|||
3217 | is assembled in the compile(ast) the co_firstlineno would be == 1. |
|
|||
3218 |
|
||||
3219 | This makes pydevd/debugpy think that all cells invoked are the same |
|
|||
3220 | since it caches information based on (co_firstlineno, co_name, co_filename). |
|
|||
3221 |
|
||||
3222 | Given that, this function changes the code 'co_name' to be unique |
|
|||
3223 | based on the first real lineno of the code (which also has a nice |
|
|||
3224 | side effect of customizing the name so that it's not always <module>). |
|
|||
3225 |
|
||||
3226 | See: https://github.com/ipython/ipykernel/issues/841 |
|
|||
3227 | """ |
|
|||
3228 | if not hasattr(code, "replace"): |
|
|||
3229 | # It may not be available on older versions of Python (only |
|
|||
3230 | # available for 3.8 onwards). |
|
|||
3231 | return code |
|
|||
3232 | try: |
|
|||
3233 | first_real_line = next(dis.findlinestarts(code))[1] |
|
|||
3234 | except StopIteration: |
|
|||
3235 | return code |
|
|||
3236 | return code.replace(co_name="<cell line: %s>" % (first_real_line,)) |
|
|||
3237 |
|
||||
3238 | async def run_ast_nodes( |
|
3214 | async def run_ast_nodes( | |
3239 | self, |
|
3215 | self, | |
3240 | nodelist: ListType[stmt], |
|
3216 | nodelist: ListType[stmt], | |
@@ -3333,7 +3309,6 b' class InteractiveShell(SingletonConfigurable):' | |||||
3333 | else 0x0 |
|
3309 | else 0x0 | |
3334 | ): |
|
3310 | ): | |
3335 | code = compiler(mod, cell_name, mode) |
|
3311 | code = compiler(mod, cell_name, mode) | |
3336 | code = self._update_code_co_name(code) |
|
|||
3337 | asy = compare(code) |
|
3312 | asy = compare(code) | |
3338 | if await self.run_code(code, result, async_=asy): |
|
3313 | if await self.run_code(code, result, async_=asy): | |
3339 | return True |
|
3314 | return True |
@@ -45,7 +45,7 b' def doctest_tb_plain():' | |||||
45 |
|
45 | |||
46 | In [19]: run simpleerr.py |
|
46 | In [19]: run simpleerr.py | |
47 | Traceback (most recent call last): |
|
47 | Traceback (most recent call last): | |
48 |
File ...:... |
|
48 | File ...:... | |
49 | bar(mode) |
|
49 | bar(mode) | |
50 | File ...:... in bar |
|
50 | File ...:... in bar | |
51 | div0() |
|
51 | div0() | |
@@ -64,7 +64,7 b' def doctest_tb_context():' | |||||
64 | --------------------------------------------------------------------------- |
|
64 | --------------------------------------------------------------------------- | |
65 | ZeroDivisionError Traceback (most recent call last) |
|
65 | ZeroDivisionError Traceback (most recent call last) | |
66 | <BLANKLINE> |
|
66 | <BLANKLINE> | |
67 | ... in <module> |
|
67 | ... | |
68 | 30 except IndexError: |
|
68 | 30 except IndexError: | |
69 | 31 mode = 'div' |
|
69 | 31 mode = 'div' | |
70 | ---> 33 bar(mode) |
|
70 | ---> 33 bar(mode) | |
@@ -93,7 +93,7 b' def doctest_tb_verbose():' | |||||
93 | --------------------------------------------------------------------------- |
|
93 | --------------------------------------------------------------------------- | |
94 | ZeroDivisionError Traceback (most recent call last) |
|
94 | ZeroDivisionError Traceback (most recent call last) | |
95 | <BLANKLINE> |
|
95 | <BLANKLINE> | |
96 | ... in <module> |
|
96 | ... | |
97 | 30 except IndexError: |
|
97 | 30 except IndexError: | |
98 | 31 mode = 'div' |
|
98 | 31 mode = 'div' | |
99 | ---> 33 bar(mode) |
|
99 | ---> 33 bar(mode) | |
@@ -134,7 +134,7 b' def doctest_tb_sysexit():' | |||||
134 | Traceback (most recent call last): |
|
134 | Traceback (most recent call last): | |
135 | File ...:... in execfile |
|
135 | File ...:... in execfile | |
136 | exec(compiler(f.read(), fname, "exec"), glob, loc) |
|
136 | exec(compiler(f.read(), fname, "exec"), glob, loc) | |
137 |
File ...:... |
|
137 | File ...:... | |
138 | bar(mode) |
|
138 | bar(mode) | |
139 | File ...:... in bar |
|
139 | File ...:... in bar | |
140 | sysexit(stat, mode) |
|
140 | sysexit(stat, mode) | |
@@ -152,7 +152,7 b' def doctest_tb_sysexit():' | |||||
152 | ... with open(fname, "rb") as f: |
|
152 | ... with open(fname, "rb") as f: | |
153 | ... compiler = compiler or compile |
|
153 | ... compiler = compiler or compile | |
154 | ---> ... exec(compiler(f.read(), fname, "exec"), glob, loc) |
|
154 | ---> ... exec(compiler(f.read(), fname, "exec"), glob, loc) | |
155 |
... |
|
155 | ... | |
156 | 30 except IndexError: |
|
156 | 30 except IndexError: | |
157 | 31 mode = 'div' |
|
157 | 31 mode = 'div' | |
158 | ---> 33 bar(mode) |
|
158 | ---> 33 bar(mode) | |
@@ -189,7 +189,7 b' def doctest_tb_sysexit_verbose():' | |||||
189 | --------------------------------------------------------------------------- |
|
189 | --------------------------------------------------------------------------- | |
190 | SystemExit Traceback (most recent call last) |
|
190 | SystemExit Traceback (most recent call last) | |
191 | <BLANKLINE> |
|
191 | <BLANKLINE> | |
192 | ... in <module> |
|
192 | ... | |
193 | 30 except IndexError: |
|
193 | 30 except IndexError: | |
194 | 31 mode = 'div' |
|
194 | 31 mode = 'div' | |
195 | ---> 33 bar(mode) |
|
195 | ---> 33 bar(mode) |
@@ -187,7 +187,10 b' def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None):' | |||||
187 |
|
187 | |||
188 | if ipinst is not None and file in ipinst.compile._filename_map: |
|
188 | if ipinst is not None and file in ipinst.compile._filename_map: | |
189 | file = "[%s]" % ipinst.compile._filename_map[file] |
|
189 | file = "[%s]" % ipinst.compile._filename_map[file] | |
190 | tpl_link = f"Input {ColorFilename}In {{file}}{ColorNormal}" |
|
190 | if lineno is None: | |
|
191 | tpl_link = f"Cell {ColorFilename}In {{file}}{ColorNormal}" | |||
|
192 | else: | |||
|
193 | tpl_link = f"Cell {ColorFilename}In {{file}}, line {{lineno}}{ColorNormal}" | |||
191 | else: |
|
194 | else: | |
192 | file = util_path.compress_user( |
|
195 | file = util_path.compress_user( | |
193 | py3compat.cast_unicode(file, util_path.fs_encoding) |
|
196 | py3compat.cast_unicode(file, util_path.fs_encoding) | |
@@ -463,34 +466,25 b' class ListTB(TBTools):' | |||||
463 |
|
466 | |||
464 | Colors = self.Colors |
|
467 | Colors = self.Colors | |
465 | list = [] |
|
468 | list = [] | |
466 |
for filename, lineno, name, line in extracted_list |
|
469 | for ind, (filename, lineno, name, line) in enumerate(extracted_list): | |
467 | item = " %s in %s%s%s\n" % ( |
|
470 | normalCol, nameCol, fileCol, lineCol = ( | |
468 | _format_filename( |
|
471 | # Emphasize the last entry | |
469 |
|
|
472 | (Colors.normalEm, Colors.nameEm, Colors.filenameEm, Colors.line) | |
470 | ), |
|
473 | if ind == len(extracted_list) - 1 | |
471 | Colors.name, |
|
474 | else (Colors.Normal, Colors.name, Colors.filename, "") | |
472 | name, |
|
|||
473 | Colors.Normal, |
|
|||
474 | ) |
|
475 | ) | |
|
476 | ||||
|
477 | fns = _format_filename(filename, fileCol, normalCol, lineno=lineno) | |||
|
478 | item = f"{normalCol} {fns}" | |||
|
479 | ||||
|
480 | if name != "<module>": | |||
|
481 | item += f" in {nameCol}{name}{normalCol}\n" | |||
|
482 | else: | |||
|
483 | item += "\n" | |||
475 | if line: |
|
484 | if line: | |
476 |
item += |
|
485 | item += f"{lineCol} {line.strip()}{normalCol}\n" | |
477 | list.append(item) |
|
486 | list.append(item) | |
478 | # Emphasize the last entry |
|
487 | ||
479 | filename, lineno, name, line = extracted_list[-1] |
|
|||
480 | item = "%s %s in %s%s%s%s\n" % ( |
|
|||
481 | Colors.normalEm, |
|
|||
482 | _format_filename( |
|
|||
483 | filename, Colors.filenameEm, Colors.normalEm, lineno=lineno |
|
|||
484 | ), |
|
|||
485 | Colors.nameEm, |
|
|||
486 | name, |
|
|||
487 | Colors.normalEm, |
|
|||
488 | Colors.Normal, |
|
|||
489 | ) |
|
|||
490 | if line: |
|
|||
491 | item += '%s %s%s\n' % (Colors.line, line.strip(), |
|
|||
492 | Colors.Normal) |
|
|||
493 | list.append(item) |
|
|||
494 | return list |
|
488 | return list | |
495 |
|
489 | |||
496 | def _format_exception_only(self, etype, value): |
|
490 | def _format_exception_only(self, etype, value): | |
@@ -687,7 +681,7 b' class VerboseTB(TBTools):' | |||||
687 |
|
681 | |||
688 | func = frame_info.executing.code_qualname() |
|
682 | func = frame_info.executing.code_qualname() | |
689 | if func == "<module>": |
|
683 | if func == "<module>": | |
690 | call = tpl_call.format(file=func, scope="") |
|
684 | call = "" | |
691 | else: |
|
685 | else: | |
692 | # Decide whether to include variable details or not |
|
686 | # Decide whether to include variable details or not | |
693 | var_repr = eqrepr if self.include_vars else nullrepr |
|
687 | var_repr = eqrepr if self.include_vars else nullrepr | |
@@ -731,7 +725,7 b' class VerboseTB(TBTools):' | |||||
731 | if lvals_list: |
|
725 | if lvals_list: | |
732 | lvals = '%s%s' % (indent, em_normal.join(lvals_list)) |
|
726 | lvals = '%s%s' % (indent, em_normal.join(lvals_list)) | |
733 |
|
727 | |||
734 | result = "%s, %s\n" % (link, call) |
|
728 | result = f'{link}{", " if call else ""}{call}\n' | |
735 |
|
729 | |||
736 | result += ''.join(_format_traceback_lines(frame_info.lines, Colors, self.has_colors, lvals)) |
|
730 | result += ''.join(_format_traceback_lines(frame_info.lines, Colors, self.has_colors, lvals)) | |
737 | return result |
|
731 | return result |
General Comments 0
You need to be logged in to leave comments.
Login now