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 | 16 | import atexit |
|
17 | 17 | import bdb |
|
18 | 18 | import builtins as builtin_mod |
|
19 | import dis | |
|
20 | 19 | import functools |
|
21 | 20 | import inspect |
|
22 | 21 | import os |
@@ -3212,29 +3211,6 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3212 | 3211 | ast.fix_missing_locations(node) |
|
3213 | 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 | 3214 | async def run_ast_nodes( |
|
3239 | 3215 | self, |
|
3240 | 3216 | nodelist: ListType[stmt], |
@@ -3333,7 +3309,6 b' class InteractiveShell(SingletonConfigurable):' | |||
|
3333 | 3309 | else 0x0 |
|
3334 | 3310 | ): |
|
3335 | 3311 | code = compiler(mod, cell_name, mode) |
|
3336 | code = self._update_code_co_name(code) | |
|
3337 | 3312 | asy = compare(code) |
|
3338 | 3313 | if await self.run_code(code, result, async_=asy): |
|
3339 | 3314 | return True |
@@ -45,7 +45,7 b' def doctest_tb_plain():' | |||
|
45 | 45 | |
|
46 | 46 | In [19]: run simpleerr.py |
|
47 | 47 | Traceback (most recent call last): |
|
48 |
File ...:... |
|
|
48 | File ...:... | |
|
49 | 49 | bar(mode) |
|
50 | 50 | File ...:... in bar |
|
51 | 51 | div0() |
@@ -64,7 +64,7 b' def doctest_tb_context():' | |||
|
64 | 64 | --------------------------------------------------------------------------- |
|
65 | 65 | ZeroDivisionError Traceback (most recent call last) |
|
66 | 66 | <BLANKLINE> |
|
67 | ... in <module> | |
|
67 | ... | |
|
68 | 68 | 30 except IndexError: |
|
69 | 69 | 31 mode = 'div' |
|
70 | 70 | ---> 33 bar(mode) |
@@ -93,7 +93,7 b' def doctest_tb_verbose():' | |||
|
93 | 93 | --------------------------------------------------------------------------- |
|
94 | 94 | ZeroDivisionError Traceback (most recent call last) |
|
95 | 95 | <BLANKLINE> |
|
96 | ... in <module> | |
|
96 | ... | |
|
97 | 97 | 30 except IndexError: |
|
98 | 98 | 31 mode = 'div' |
|
99 | 99 | ---> 33 bar(mode) |
@@ -134,7 +134,7 b' def doctest_tb_sysexit():' | |||
|
134 | 134 | Traceback (most recent call last): |
|
135 | 135 | File ...:... in execfile |
|
136 | 136 | exec(compiler(f.read(), fname, "exec"), glob, loc) |
|
137 |
File ...:... |
|
|
137 | File ...:... | |
|
138 | 138 | bar(mode) |
|
139 | 139 | File ...:... in bar |
|
140 | 140 | sysexit(stat, mode) |
@@ -152,7 +152,7 b' def doctest_tb_sysexit():' | |||
|
152 | 152 | ... with open(fname, "rb") as f: |
|
153 | 153 | ... compiler = compiler or compile |
|
154 | 154 | ---> ... exec(compiler(f.read(), fname, "exec"), glob, loc) |
|
155 |
... |
|
|
155 | ... | |
|
156 | 156 | 30 except IndexError: |
|
157 | 157 | 31 mode = 'div' |
|
158 | 158 | ---> 33 bar(mode) |
@@ -189,7 +189,7 b' def doctest_tb_sysexit_verbose():' | |||
|
189 | 189 | --------------------------------------------------------------------------- |
|
190 | 190 | SystemExit Traceback (most recent call last) |
|
191 | 191 | <BLANKLINE> |
|
192 | ... in <module> | |
|
192 | ... | |
|
193 | 193 | 30 except IndexError: |
|
194 | 194 | 31 mode = 'div' |
|
195 | 195 | ---> 33 bar(mode) |
@@ -187,7 +187,10 b' def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None):' | |||
|
187 | 187 | |
|
188 | 188 | if ipinst is not None and file in ipinst.compile._filename_map: |
|
189 | 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 | 194 | else: |
|
192 | 195 | file = util_path.compress_user( |
|
193 | 196 | py3compat.cast_unicode(file, util_path.fs_encoding) |
@@ -463,34 +466,25 b' class ListTB(TBTools):' | |||
|
463 | 466 | |
|
464 | 467 | Colors = self.Colors |
|
465 | 468 | list = [] |
|
466 |
for filename, lineno, name, line in extracted_list |
|
|
467 | item = " %s in %s%s%s\n" % ( | |
|
468 | _format_filename( | |
|
469 | filename, Colors.filename, Colors.Normal, lineno=lineno | |
|
470 | ), | |
|
471 | Colors.name, | |
|
472 | name, | |
|
473 | Colors.Normal, | |
|
474 | ) | |
|
475 | if line: | |
|
476 | item += ' %s\n' % line.strip() | |
|
477 | list.append(item) | |
|
469 | for ind, (filename, lineno, name, line) in enumerate(extracted_list): | |
|
470 | normalCol, nameCol, fileCol, lineCol = ( | |
|
478 | 471 | # Emphasize the last entry |
|
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, | |
|
472 | (Colors.normalEm, Colors.nameEm, Colors.filenameEm, Colors.line) | |
|
473 | if ind == len(extracted_list) - 1 | |
|
474 | else (Colors.Normal, Colors.name, Colors.filename, "") | |
|
489 | 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" | |
|
490 | 484 | if line: |
|
491 | item += '%s %s%s\n' % (Colors.line, line.strip(), | |
|
492 | Colors.Normal) | |
|
485 | item += f"{lineCol} {line.strip()}{normalCol}\n" | |
|
493 | 486 | list.append(item) |
|
487 | ||
|
494 | 488 | return list |
|
495 | 489 | |
|
496 | 490 | def _format_exception_only(self, etype, value): |
@@ -687,7 +681,7 b' class VerboseTB(TBTools):' | |||
|
687 | 681 | |
|
688 | 682 | func = frame_info.executing.code_qualname() |
|
689 | 683 | if func == "<module>": |
|
690 | call = tpl_call.format(file=func, scope="") | |
|
684 | call = "" | |
|
691 | 685 | else: |
|
692 | 686 | # Decide whether to include variable details or not |
|
693 | 687 | var_repr = eqrepr if self.include_vars else nullrepr |
@@ -731,7 +725,7 b' class VerboseTB(TBTools):' | |||
|
731 | 725 | if lvals_list: |
|
732 | 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 | 730 | result += ''.join(_format_traceback_lines(frame_info.lines, Colors, self.has_colors, lvals)) |
|
737 | 731 | return result |
General Comments 0
You need to be logged in to leave comments.
Login now