Skip to content

Commit e1e9bab

Browse files
authored
gh-102778: Add sys.last_exc, deprecate sys.last_type, sys.last_value,sys.last_traceback (#102779)
1 parent 039714d commit e1e9bab

22 files changed

+103
-36
lines changed

Doc/library/sys.rst

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,22 +1102,25 @@ always available.
11021102

11031103
.. versionadded:: 3.5
11041104

1105+
.. data:: last_exc
1106+
1107+
This variable is not always defined; it is set to the exception instance
1108+
when an exception is not handled and the interpreter prints an error message
1109+
and a stack traceback. Its intended use is to allow an interactive user to
1110+
import a debugger module and engage in post-mortem debugging without having
1111+
to re-execute the command that caused the error. (Typical use is
1112+
``import pdb; pdb.pm()`` to enter the post-mortem debugger; see :mod:`pdb`
1113+
module for more information.)
1114+
1115+
.. versionadded:: 3.12
11051116

11061117
.. data:: last_type
11071118
last_value
11081119
last_traceback
11091120

1110-
These three variables are not always defined; they are set when an exception is
1111-
not handled and the interpreter prints an error message and a stack traceback.
1112-
Their intended use is to allow an interactive user to import a debugger module
1113-
and engage in post-mortem debugging without having to re-execute the command
1114-
that caused the error. (Typical use is ``import pdb; pdb.pm()`` to enter the
1115-
post-mortem debugger; see :mod:`pdb` module for
1116-
more information.)
1117-
1118-
The meaning of the variables is the same as that of the return values from
1119-
:func:`exc_info` above.
1120-
1121+
These three variables are deprecated; use :data:`sys.last_exc` instead.
1122+
They hold the legacy representation of ``sys.last_exc``, as returned
1123+
from :func:`exc_info` above.
11211124

11221125
.. data:: maxsize
11231126

Doc/whatsnew/3.12.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ sys
397397
with contributions from Gregory P. Smith [Google] and Mark Shannon
398398
in :gh:`96123`.)
399399

400+
* Add :data:`sys.last_exc` which holds the last unhandled exception that
401+
was raised (for post-mortem debugging use cases). Deprecate the
402+
three fields that have the same information in its legacy form:
403+
:data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback`.
404+
(Contributed by Irit Katriel in :gh:`102778`.)
405+
400406

401407
Optimizations
402408
=============
@@ -488,6 +494,10 @@ Deprecated
488494
contain the creation time, which is also available in the new ``st_birthtime``
489495
field. (Contributed by Steve Dower in :gh:`99726`.)
490496

497+
* The :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback`
498+
fields are deprecated. Use :data:`sys.last_exc` instead.
499+
(Contributed by Irit Katriel in :gh:`102778`.)
500+
491501
Pending Removal in Python 3.13
492502
------------------------------
493503

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ struct _Py_global_strings {
481481
STRUCT_FOR_ID(kw2)
482482
STRUCT_FOR_ID(lambda)
483483
STRUCT_FOR_ID(last)
484+
STRUCT_FOR_ID(last_exc)
484485
STRUCT_FOR_ID(last_node)
485486
STRUCT_FOR_ID(last_traceback)
486487
STRUCT_FOR_ID(last_type)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/code.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ def showsyntaxerror(self, filename=None):
106106
107107
"""
108108
type, value, tb = sys.exc_info()
109+
sys.last_exc = value
109110
sys.last_type = type
110111
sys.last_value = value
111112
sys.last_traceback = tb
@@ -119,7 +120,7 @@ def showsyntaxerror(self, filename=None):
119120
else:
120121
# Stuff in the right filename
121122
value = SyntaxError(msg, (filename, lineno, offset, line))
122-
sys.last_value = value
123+
sys.last_exc = sys.last_value = value
123124
if sys.excepthook is sys.__excepthook__:
124125
lines = traceback.format_exception_only(type, value)
125126
self.write(''.join(lines))
@@ -138,6 +139,7 @@ def showtraceback(self):
138139
"""
139140
sys.last_type, sys.last_value, last_tb = ei = sys.exc_info()
140141
sys.last_traceback = last_tb
142+
sys.last_exc = ei[1]
141143
try:
142144
lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next)
143145
if sys.excepthook is sys.__excepthook__:

Lib/dis.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ def distb(tb=None, *, file=None, show_caches=False, adaptive=False):
118118
"""Disassemble a traceback (default: last traceback)."""
119119
if tb is None:
120120
try:
121-
tb = sys.last_traceback
121+
if hasattr(sys, 'last_exc'):
122+
tb = sys.last_exc.__traceback__
123+
else:
124+
tb = sys.last_traceback
122125
except AttributeError:
123126
raise RuntimeError("no last traceback to disassemble") from None
124127
while tb.tb_next: tb = tb.tb_next

Lib/idlelib/idle_test/test_stackviewer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def setUpClass(cls):
1919
except NameError:
2020
svs.last_type, svs.last_value, svs.last_traceback = (
2121
sys.exc_info())
22+
svs.last_exc = svs.last_value
2223

2324
requires('gui')
2425
cls.root = Tk()
@@ -27,7 +28,7 @@ def setUpClass(cls):
2728
@classmethod
2829
def tearDownClass(cls):
2930
svs = stackviewer.sys
30-
del svs.last_traceback, svs.last_type, svs.last_value
31+
del svs.last_exc, svs.last_traceback, svs.last_type, svs.last_value
3132

3233
cls.root.update_idletasks()
3334
## for id in cls.root.tk.call('after', 'info'):

Lib/idlelib/pyshell.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,11 +1367,14 @@ def open_stack_viewer(self, event=None):
13671367
if self.interp.rpcclt:
13681368
return self.interp.remote_stack_viewer()
13691369
try:
1370-
sys.last_traceback
1370+
if hasattr(sys, 'last_exc'):
1371+
sys.last_exc.__traceback__
1372+
else:
1373+
sys.last_traceback
13711374
except:
13721375
messagebox.showerror("No stack trace",
13731376
"There is no stack trace yet.\n"
1374-
"(sys.last_traceback is not defined)",
1377+
"(sys.last_exc and sys.last_traceback are not defined)",
13751378
parent=self.text)
13761379
return
13771380
from idlelib.stackviewer import StackBrowser

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy