Show More
@@ -1756,7 +1756,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1756 | return ''.join(msg) |
|
1756 | return ''.join(msg) | |
1757 |
|
1757 | |||
1758 | def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None, |
|
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 | """Display the exception that just occurred. |
|
1760 | """Display the exception that just occurred. | |
1761 |
|
1761 | |||
1762 | If nothing is known about the exception, this is the method which |
|
1762 | If nothing is known about the exception, this is the method which | |
@@ -1778,7 +1778,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1778 | if issubclass(etype, SyntaxError): |
|
1778 | if issubclass(etype, SyntaxError): | |
1779 | # Though this won't be called by syntax errors in the input |
|
1779 | # Though this won't be called by syntax errors in the input | |
1780 | # line, there may be SyntaxError cases with imported code. |
|
1780 | # line, there may be SyntaxError cases with imported code. | |
1781 | self.showsyntaxerror(filename) |
|
1781 | self.showsyntaxerror(filename, running_compiled_code) | |
1782 | elif etype is UsageError: |
|
1782 | elif etype is UsageError: | |
1783 | self.show_usage_error(value) |
|
1783 | self.show_usage_error(value) | |
1784 | else: |
|
1784 | else: | |
@@ -1817,7 +1817,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1817 | """ |
|
1817 | """ | |
1818 | print(self.InteractiveTB.stb2text(stb)) |
|
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 | """Display the syntax error that just occurred. |
|
1821 | """Display the syntax error that just occurred. | |
1822 |
|
1822 | |||
1823 | This doesn't display a stack trace because there isn't one. |
|
1823 | This doesn't display a stack trace because there isn't one. | |
@@ -1825,6 +1825,9 b' class InteractiveShell(SingletonConfigurable):' | |||||
1825 | If a filename is given, it is stuffed in the exception instead |
|
1825 | If a filename is given, it is stuffed in the exception instead | |
1826 | of what was there before (because Python's parser always uses |
|
1826 | of what was there before (because Python's parser always uses | |
1827 | "<string>" when reading from a string). |
|
1827 | "<string>" when reading from a string). | |
|
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. | |||
1828 | """ |
|
1831 | """ | |
1829 | etype, value, last_traceback = self._get_exc_info() |
|
1832 | etype, value, last_traceback = self._get_exc_info() | |
1830 |
|
1833 | |||
@@ -1835,7 +1838,9 b' class InteractiveShell(SingletonConfigurable):' | |||||
1835 | # Not the format we expect; leave it alone |
|
1838 | # Not the format we expect; leave it alone | |
1836 | pass |
|
1839 | pass | |
1837 |
|
1840 | |||
1838 | stb = self.SyntaxTB.structured_traceback(etype, value, []) |
|
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 | self._showtraceback(etype, value, stb) |
|
1844 | self._showtraceback(etype, value, stb) | |
1840 |
|
1845 | |||
1841 | # This is overridden in TerminalInteractiveShell to show a message about |
|
1846 | # This is overridden in TerminalInteractiveShell to show a message about | |
@@ -2861,7 +2866,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
2861 | except: |
|
2866 | except: | |
2862 | if result is not None: |
|
2867 | if result is not None: | |
2863 | result.error_in_exec = sys.exc_info()[1] |
|
2868 | result.error_in_exec = sys.exc_info()[1] | |
2864 | self.showtraceback() |
|
2869 | self.showtraceback(running_compiled_code=True) | |
2865 | else: |
|
2870 | else: | |
2866 | outflag = False |
|
2871 | outflag = False | |
2867 | return outflag |
|
2872 | return outflag |
@@ -167,6 +167,33 b' class SyntaxErrorTest(unittest.TestCase):' | |||||
167 | with tt.AssertPrints("line unknown"): |
|
167 | with tt.AssertPrints("line unknown"): | |
168 | ip.run_cell("raise SyntaxError()") |
|
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 | def test_changing_py_file(self): |
|
197 | def test_changing_py_file(self): | |
171 | with TemporaryDirectory() as td: |
|
198 | with TemporaryDirectory() as td: | |
172 | fname = os.path.join(td, "foo.py") |
|
199 | fname = os.path.join(td, "foo.py") |
General Comments 0
You need to be logged in to leave comments.
Login now