Show More
@@ -1756,7 +1756,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1756 | 1756 | return ''.join(msg) |
|
1757 | 1757 | |
|
1758 | 1758 | def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None, |
|
1759 | exception_only=False): | |
|
1759 | exception_only=False, running_compiled_code=False): | |
|
1760 | 1760 | """Display the exception that just occurred. |
|
1761 | 1761 | |
|
1762 | 1762 | If nothing is known about the exception, this is the method which |
@@ -1774,11 +1774,11 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1774 | 1774 | except ValueError: |
|
1775 | 1775 | print('No traceback available to show.', file=sys.stderr) |
|
1776 | 1776 | return |
|
1777 | ||
|
1777 | ||
|
1778 | 1778 | if issubclass(etype, SyntaxError): |
|
1779 | 1779 | # Though this won't be called by syntax errors in the input |
|
1780 | 1780 | # line, there may be SyntaxError cases with imported code. |
|
1781 | self.showsyntaxerror(filename) | |
|
1781 | self.showsyntaxerror(filename, running_compiled_code) | |
|
1782 | 1782 | elif etype is UsageError: |
|
1783 | 1783 | self.show_usage_error(value) |
|
1784 | 1784 | else: |
@@ -1817,7 +1817,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1817 | 1817 | """ |
|
1818 | 1818 | print(self.InteractiveTB.stb2text(stb)) |
|
1819 | 1819 | |
|
1820 | def showsyntaxerror(self, filename=None): | |
|
1820 | def showsyntaxerror(self, filename=None, running_compiled_code=False): | |
|
1821 | 1821 | """Display the syntax error that just occurred. |
|
1822 | 1822 | |
|
1823 | 1823 | This doesn't display a stack trace because there isn't one. |
@@ -1825,7 +1825,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1825 | 1825 | If a filename is given, it is stuffed in the exception instead |
|
1826 | 1826 | of what was there before (because Python's parser always uses |
|
1827 | 1827 | "<string>" when reading from a string). |
|
1828 | """ | |
|
1828 | ||
|
1829 | If the syntax error occurred when running a compiled code (i.e. running_compile_code=True), | |
|
1830 | longer stack trace will be displayed. | |
|
1831 | """ | |
|
1829 | 1832 | etype, value, last_traceback = self._get_exc_info() |
|
1830 | 1833 | |
|
1831 | 1834 | if filename and issubclass(etype, SyntaxError): |
@@ -1834,8 +1837,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1834 | 1837 | except: |
|
1835 | 1838 | # Not the format we expect; leave it alone |
|
1836 | 1839 | pass |
|
1837 | ||
|
1838 | stb = self.SyntaxTB.structured_traceback(etype, value, []) | |
|
1840 | ||
|
1841 | # If the error occured when executing compiled code, we should provide full stacktrace. | |
|
1842 | elist = traceback.extract_tb(last_traceback) if running_compiled_code else [] | |
|
1843 | stb = self.SyntaxTB.structured_traceback(etype, value, elist) | |
|
1839 | 1844 | self._showtraceback(etype, value, stb) |
|
1840 | 1845 | |
|
1841 | 1846 | # This is overridden in TerminalInteractiveShell to show a message about |
@@ -2861,7 +2866,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2861 | 2866 | except: |
|
2862 | 2867 | if result is not None: |
|
2863 | 2868 | result.error_in_exec = sys.exc_info()[1] |
|
2864 | self.showtraceback() | |
|
2869 | self.showtraceback(running_compiled_code=True) | |
|
2865 | 2870 | else: |
|
2866 | 2871 | outflag = False |
|
2867 | 2872 | return outflag |
@@ -167,6 +167,33 b' class SyntaxErrorTest(unittest.TestCase):' | |||
|
167 | 167 | with tt.AssertPrints("line unknown"): |
|
168 | 168 | ip.run_cell("raise SyntaxError()") |
|
169 | 169 | |
|
170 | def test_syntaxerror_no_stacktrace_at_compile_time(self): | |
|
171 | syntax_error_at_compile_time = """ | |
|
172 | def foo(): | |
|
173 | .. | |
|
174 | """ | |
|
175 | with tt.AssertPrints("SyntaxError"): | |
|
176 | ip.run_cell(syntax_error_at_compile_time) | |
|
177 | ||
|
178 | with tt.AssertNotPrints("foo()"): | |
|
179 | ip.run_cell(syntax_error_at_compile_time) | |
|
180 | ||
|
181 | def test_syntaxerror_stacktrace_when_running_compiled_code(self): | |
|
182 | syntax_error_at_runtime = """ | |
|
183 | def foo(): | |
|
184 | eval("..") | |
|
185 | ||
|
186 | def bar(): | |
|
187 | foo() | |
|
188 | ||
|
189 | bar() | |
|
190 | """ | |
|
191 | with tt.AssertPrints("SyntaxError"): | |
|
192 | ip.run_cell(syntax_error_at_runtime) | |
|
193 | # Assert syntax error during runtime generate stacktrace | |
|
194 | with tt.AssertPrints(["foo()", "bar()"]): | |
|
195 | ip.run_cell(syntax_error_at_runtime) | |
|
196 | ||
|
170 | 197 | def test_changing_py_file(self): |
|
171 | 198 | with TemporaryDirectory() as td: |
|
172 | 199 | fname = os.path.join(td, "foo.py") |
General Comments 0
You need to be logged in to leave comments.
Login now