Show More
@@ -0,0 +1,39 b'' | |||||
|
1 | Traceback improvements | |||
|
2 | ====================== | |||
|
3 | ||||
|
4 | Previously, error tracebacks for errors happening in code cells were showing a hash, the one used for compiling the Python AST. | |||
|
5 | ||||
|
6 | In [1]: def foo(): | |||
|
7 | ...: return 3 / 0 | |||
|
8 | ...: | |||
|
9 | ||||
|
10 | In [2]: foo() | |||
|
11 | --------------------------------------------------------------------------- | |||
|
12 | ZeroDivisionError Traceback (most recent call last) | |||
|
13 | <ipython-input-2-c19b6d9633cf> in <module> | |||
|
14 | ----> 1 foo() | |||
|
15 | ||||
|
16 | <ipython-input-1-1595a74c32d5> in foo() | |||
|
17 | 1 def foo(): | |||
|
18 | ----> 2 return 3 / 0 | |||
|
19 | 3 | |||
|
20 | ||||
|
21 | ZeroDivisionError: division by zero | |||
|
22 | ||||
|
23 | The error traceback is now correctly formatted, showing the cell number in which the error happened: | |||
|
24 | ||||
|
25 | In [1]: def foo(): | |||
|
26 | ...: return 3 / 0 | |||
|
27 | ...: | |||
|
28 | ||||
|
29 | In [2]: foo() | |||
|
30 | --------------------------------------------------------------------------- | |||
|
31 | ZeroDivisionError Traceback (most recent call last) | |||
|
32 | In [2], in <module> | |||
|
33 | ----> 1 foo() | |||
|
34 | ||||
|
35 | In [1], in foo() | |||
|
36 | 1 def foo(): | |||
|
37 | ----> 2 return 3 / 0 | |||
|
38 | ||||
|
39 | ZeroDivisionError: division by zero |
@@ -92,6 +92,10 b' class CachingCompiler(codeop.Compile):' | |||||
92 | # (otherwise we'd lose our tracebacks). |
|
92 | # (otherwise we'd lose our tracebacks). | |
93 | linecache.checkcache = check_linecache_ipython |
|
93 | linecache.checkcache = check_linecache_ipython | |
94 |
|
94 | |||
|
95 | # Caching a dictionary { filename: execution_count } for nicely | |||
|
96 | # rendered tracebacks. The filename corresponds to the filename | |||
|
97 | # argument used for the builtins.compile function. | |||
|
98 | self._filename_map = {} | |||
95 |
|
99 | |||
96 | def ast_parse(self, source, filename='<unknown>', symbol='exec'): |
|
100 | def ast_parse(self, source, filename='<unknown>', symbol='exec'): | |
97 | """Parse code to an AST with the current compiler flags active. |
|
101 | """Parse code to an AST with the current compiler flags active. | |
@@ -153,6 +157,10 b' class CachingCompiler(codeop.Compile):' | |||||
153 | raw_code = transformed_code |
|
157 | raw_code = transformed_code | |
154 |
|
158 | |||
155 | name = self.get_code_name(raw_code, transformed_code, number) |
|
159 | name = self.get_code_name(raw_code, transformed_code, number) | |
|
160 | ||||
|
161 | # Save the execution count | |||
|
162 | self._filename_map[name] = number | |||
|
163 | ||||
156 | entry = ( |
|
164 | entry = ( | |
157 | len(transformed_code), |
|
165 | len(transformed_code), | |
158 | time.time(), |
|
166 | time.time(), |
@@ -581,25 +581,31 b' class VerboseTB(TBTools):' | |||||
581 | Colors = self.Colors # just a shorthand + quicker name lookup |
|
581 | Colors = self.Colors # just a shorthand + quicker name lookup | |
582 | ColorsNormal = Colors.Normal # used a lot |
|
582 | ColorsNormal = Colors.Normal # used a lot | |
583 |
|
583 | |||
584 |
|
||||
585 |
|
||||
586 | if isinstance(frame_info, stack_data.RepeatedFrames): |
|
584 | if isinstance(frame_info, stack_data.RepeatedFrames): | |
587 | return ' %s[... skipping similar frames: %s]%s\n' % ( |
|
585 | return ' %s[... skipping similar frames: %s]%s\n' % ( | |
588 | Colors.excName, frame_info.description, ColorsNormal) |
|
586 | Colors.excName, frame_info.description, ColorsNormal) | |
589 |
|
587 | |||
|
588 | file = frame_info.filename | |||
|
589 | ||||
|
590 | ipinst = get_ipython() | |||
|
591 | if ipinst is not None and file in ipinst.compile._filename_map: | |||
|
592 | file = "[%s]" % ipinst.compile._filename_map[file] | |||
|
593 | tpl_link = "In %s%%s%s," % (Colors.filenameEm, ColorsNormal) | |||
|
594 | else: | |||
|
595 | file = util_path.compress_user( | |||
|
596 | py3compat.cast_unicode(file, util_path.fs_encoding) | |||
|
597 | ) | |||
|
598 | tpl_link = "File %s%%s%s," % (Colors.filenameEm, ColorsNormal) | |||
|
599 | ||||
590 | indent = ' ' * INDENT_SIZE |
|
600 | indent = ' ' * INDENT_SIZE | |
591 | em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal) |
|
601 | em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal) | |
592 | tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal) |
|
|||
593 | tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, |
|
602 | tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, | |
594 | ColorsNormal) |
|
603 | ColorsNormal) | |
595 | tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ |
|
604 | tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ | |
596 | (Colors.vName, Colors.valEm, ColorsNormal) |
|
605 | (Colors.vName, Colors.valEm, ColorsNormal) | |
597 | tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal) |
|
|||
598 | tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) |
|
606 | tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) | |
599 |
|
607 | |||
600 | file = frame_info.filename |
|
608 | link = tpl_link % file | |
601 | file = py3compat.cast_unicode(file, util_path.fs_encoding) |
|
|||
602 | link = tpl_link % util_path.compress_user(file) |
|
|||
603 | args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame) |
|
609 | args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame) | |
604 |
|
610 | |||
605 | func = frame_info.executing.code_qualname() |
|
611 | func = frame_info.executing.code_qualname() |
General Comments 0
You need to be logged in to leave comments.
Login now