Show More
@@ -1626,6 +1626,39 class InteractiveShell(SingletonConfigurable, Magic): | |||
|
1626 | 1626 | """ |
|
1627 | 1627 | self.showtraceback((etype,value,tb),tb_offset=0) |
|
1628 | 1628 | |
|
1629 | def _get_exc_info(self, exc_tuple=None): | |
|
1630 | """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc. | |
|
1631 | ||
|
1632 | Ensures sys.last_type,value,traceback hold the exc_info we found, | |
|
1633 | from whichever source. | |
|
1634 | ||
|
1635 | raises ValueError if none of these contain any information | |
|
1636 | """ | |
|
1637 | if exc_tuple is None: | |
|
1638 | etype, value, tb = sys.exc_info() | |
|
1639 | else: | |
|
1640 | etype, value, tb = exc_tuple | |
|
1641 | ||
|
1642 | if etype is None: | |
|
1643 | if hasattr(sys, 'last_type'): | |
|
1644 | etype, value, tb = sys.last_type, sys.last_value, \ | |
|
1645 | sys.last_traceback | |
|
1646 | ||
|
1647 | if etype is None: | |
|
1648 | raise ValueError("No exception to find") | |
|
1649 | ||
|
1650 | # Now store the exception info in sys.last_type etc. | |
|
1651 | # WARNING: these variables are somewhat deprecated and not | |
|
1652 | # necessarily safe to use in a threaded environment, but tools | |
|
1653 | # like pdb depend on their existence, so let's set them. If we | |
|
1654 | # find problems in the field, we'll need to revisit their use. | |
|
1655 | sys.last_type = etype | |
|
1656 | sys.last_value = value | |
|
1657 | sys.last_traceback = tb | |
|
1658 | ||
|
1659 | return etype, value, tb | |
|
1660 | ||
|
1661 | ||
|
1629 | 1662 | def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None, |
|
1630 | 1663 | exception_only=False): |
|
1631 | 1664 | """Display the exception that just occurred. |
@@ -1640,18 +1673,11 class InteractiveShell(SingletonConfigurable, Magic): | |||
|
1640 | 1673 | simply call this method.""" |
|
1641 | 1674 | |
|
1642 | 1675 | try: |
|
1643 | if exc_tuple is None: | |
|
1644 |
etype, value, tb = s |
|
|
1645 |
e |
|
|
1646 | etype, value, tb = exc_tuple | |
|
1647 | ||
|
1648 | if etype is None: | |
|
1649 | if hasattr(sys, 'last_type'): | |
|
1650 | etype, value, tb = sys.last_type, sys.last_value, \ | |
|
1651 | sys.last_traceback | |
|
1652 | else: | |
|
1653 | self.write_err('No traceback available to show.\n') | |
|
1654 | return | |
|
1676 | try: | |
|
1677 | etype, value, tb = self._get_exc_info(exc_tuple) | |
|
1678 | except ValueError: | |
|
1679 | self.write_err('No traceback available to show.\n') | |
|
1680 | return | |
|
1655 | 1681 | |
|
1656 | 1682 | if etype is SyntaxError: |
|
1657 | 1683 | # Though this won't be called by syntax errors in the input |
@@ -1660,13 +1686,6 class InteractiveShell(SingletonConfigurable, Magic): | |||
|
1660 | 1686 | elif etype is UsageError: |
|
1661 | 1687 | self.write_err("UsageError: %s" % value) |
|
1662 | 1688 | else: |
|
1663 | # WARNING: these variables are somewhat deprecated and not | |
|
1664 | # necessarily safe to use in a threaded environment, but tools | |
|
1665 | # like pdb depend on their existence, so let's set them. If we | |
|
1666 | # find problems in the field, we'll need to revisit their use. | |
|
1667 | sys.last_type = etype | |
|
1668 | sys.last_value = value | |
|
1669 | sys.last_traceback = tb | |
|
1670 | 1689 | if etype in self.custom_exceptions: |
|
1671 | 1690 | stb = self.CustomTB(etype, value, tb, tb_offset) |
|
1672 | 1691 | else: |
@@ -1708,12 +1727,7 class InteractiveShell(SingletonConfigurable, Magic): | |||
|
1708 | 1727 | of what was there before (because Python's parser always uses |
|
1709 | 1728 | "<string>" when reading from a string). |
|
1710 | 1729 | """ |
|
1711 |
etype, value, last_traceback = s |
|
|
1712 | ||
|
1713 | # See note about these variables in showtraceback() above | |
|
1714 | sys.last_type = etype | |
|
1715 | sys.last_value = value | |
|
1716 | sys.last_traceback = last_traceback | |
|
1730 | etype, value, last_traceback = self._get_exc_info() | |
|
1717 | 1731 | |
|
1718 | 1732 | if filename and etype is SyntaxError: |
|
1719 | 1733 | try: |
@@ -9,6 +9,8 from __future__ import absolute_import | |||
|
9 | 9 | #----------------------------------------------------------------------------- |
|
10 | 10 | |
|
11 | 11 | import os |
|
12 | import sys | |
|
13 | from StringIO import StringIO | |
|
12 | 14 | |
|
13 | 15 | import nose.tools as nt |
|
14 | 16 | |
@@ -232,6 +234,23 def test_reset_in_length(): | |||
|
232 | 234 | def test_time(): |
|
233 | 235 | _ip.magic('time None') |
|
234 | 236 | |
|
237 | def test_tb_syntaxerror(): | |
|
238 | """test %tb after a SyntaxError""" | |
|
239 | ip = get_ipython() | |
|
240 | ip.run_cell("for") | |
|
241 | ||
|
242 | # trap and validate stdout | |
|
243 | save_stdout = sys.stdout | |
|
244 | try: | |
|
245 | sys.stdout = StringIO() | |
|
246 | ip.run_cell("%tb") | |
|
247 | out = sys.stdout.getvalue() | |
|
248 | finally: | |
|
249 | sys.stdout = save_stdout | |
|
250 | # trim output, and only check the last line | |
|
251 | last_line = out.rstrip().splitlines()[-1].strip() | |
|
252 | nt.assert_equals(last_line, "SyntaxError: invalid syntax") | |
|
253 | ||
|
235 | 254 | |
|
236 | 255 | @py3compat.doctest_refactor_print |
|
237 | 256 | def doctest_time(): |
General Comments 0
You need to be logged in to leave comments.
Login now