Skip to content

Commit 75e1496

Browse files
committed
gh-102778: Add sys.last_exc, deprecate sys.last_type, sys.last_value, sys.last_traceback
1 parent 4f5774f commit 75e1496

File tree

9 files changed

+31
-14
lines changed

9 files changed

+31
-14
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 ``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

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: 2 additions & 0 deletions
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
@@ -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__:

Python/pylifecycle.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose)
13041304
{
13051305
// List of names to clear in sys
13061306
static const char * const sys_deletes[] = {
1307-
"path", "argv", "ps1", "ps2",
1307+
"path", "argv", "ps1", "ps2", "last_exc",
13081308
"last_type", "last_value", "last_traceback",
13091309
"__interactivehook__",
13101310
// path_hooks and path_importer_cache are cleared

Python/pythonrun.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,10 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
776776
}
777777

778778
if (set_sys_last_vars) {
779+
if (_PySys_SetAttr(&_Py_ID(last_exc), exc) < 0) {
780+
_PyErr_Clear(tstate);
781+
}
782+
/* Legacy version: */
779783
if (_PySys_SetAttr(&_Py_ID(last_type), typ) < 0) {
780784
_PyErr_Clear(tstate);
781785
}

Python/sysmodule.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,11 +2670,13 @@ stderr -- standard error object; used for error messages\n\
26702670
By assigning other file objects (or objects that behave like files)\n\
26712671
to these, it is possible to redirect all of the interpreter's I/O.\n\
26722672
\n\
2673+
last_exc - the last uncaught exception\n\
2674+
Only available in an interactive session after a\n\
2675+
traceback has been printed.\n\
26732676
last_type -- type of last uncaught exception\n\
26742677
last_value -- value of last uncaught exception\n\
26752678
last_traceback -- traceback of last uncaught exception\n\
2676-
These three are only available in an interactive session after a\n\
2677-
traceback has been printed.\n\
2679+
These three are the (deprecated) legacy representation of last_exc.\n\
26782680
"
26792681
)
26802682
/* concatenating string here */

0 commit comments

Comments
 (0)