-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
traceback.print_last behaving differently across python versions in ipython #14744
Description
See https://docs.python.org/3/library/traceback.html#traceback.print_last:
This is a shorthand for print_exception(sys.last_exc, limit, file, chain). In general it will work only after an exception has reached an interactive prompt (see sys.last_exc).
This behaves differently across different python versions, leading to an ugly python version check in my code. I'm not entirely sure if this is a python issue or an ipython issue.
The problem is that after raising an exception, in 3.10 and 3.11, the sys.last_exc attribute does not exist, while it does for 3.12 and 3.13. There is similar attribute sys.last_value, which exists in 3.10, 3.11, 3.12, but not in 3.13.
The confusion is that it seems like traceback.print_last is supposed to be a uniform interface across the python version, with the docs claiming that for 3.10 it uses sys.last_value internally and for later versions sys.last_exc. However, for 3.12 and 3.13 it just prints NoneType: None
python 3.10.16 / ipython 8.32.0
Python 3.10.16 (main, Feb 13 2025, 14:32:36) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.32.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import sys
In [2]: import traceback
In [3]: 1/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[3], line 1
----> 1 1/0
ZeroDivisionError: division by zero
In [4]: traceback.print_last()
Traceback (most recent call last):
File "/home/miron/.pyenv/versions/3.10.16/envs/finesse3-10/lib/python3.10/site-packages/IPython/core/interactiveshell.py", line 3579, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-3-9e1622b385b6>", line 1, in <module>
1/0
ZeroDivisionError: division by zero
In [5]: sys.last_exc
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[5], line 1
----> 1 sys.last_exc
AttributeError: module 'sys' has no attribute 'last_exc'
python 3.11.9 / ipython 8.32.0
Python 3.11.9 (main, Feb 13 2025, 14:34:41) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.32.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import sys
In [2]: import traceback
In [3]: 1/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[3], line 1
----> 1 1/0
ZeroDivisionError: division by zero
In [4]: traceback.print_last()
Traceback (most recent call last):
File "/home/miron/.pyenv/versions/3.11.9/envs/finesse3-11/lib/python3.11/site-packages/IPython/core/interactiveshell.py", line 3579, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-3-9e1622b385b6>", line 1, in <module>
1/0
~^~
ZeroDivisionError: division by zero
In [5]: sys.last_exc
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[5], line 1
----> 1 sys.last_exc
AttributeError: module 'sys' has no attribute 'last_exc'
python 3.12.9 / ipython 8.32.0
Python 3.12.9 (main, Feb 13 2025, 13:23:03) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.32.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import traceback
In [2]: import sys
In [3]: 1/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[3], line 1
----> 1 1/0
ZeroDivisionError: division by zero
In [4]: traceback.print_last()
NoneType: None
In [5]: sys.last_exc
Out[5]: ZeroDivisionError('division by zero')
python 3.12.2 / ipython 8.32.0
Python 3.13.2 (main, Feb 13 2025, 11:10:27) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.32.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import traceback
In [2]: import sys
In [3]: 1/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[3], line 1
----> 1 1/0
ZeroDivisionError: division by zero
In [4]: traceback.print_last()
NoneType: None
In [5]: sys.last_exc
Out[5]: ZeroDivisionError('division by zero')