diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index c75992761d1334f..e3453a8756fdf14 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -470,7 +470,7 @@ def foo(a: int, b: str) -> str: %4d LOAD_GLOBAL 0 (Exception) CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 24 (to L9) + POP_JUMP_IF_FALSE 22 (to L9) L4: NOT_TAKEN L5: STORE_FAST 0 (e) @@ -478,16 +478,14 @@ def foo(a: int, b: str) -> str: LOAD_ATTR 2 (__traceback__) STORE_FAST 1 (tb) L7: POP_EXCEPT - LOAD_COMMON_CONSTANT 7 (None) + PUSH_NULL STORE_FAST 0 (e) - DELETE_FAST 0 (e) %4d LOAD_FAST 1 (tb) RETURN_VALUE - -- L8: LOAD_COMMON_CONSTANT 7 (None) + -- L8: PUSH_NULL STORE_FAST 0 (e) - DELETE_FAST 0 (e) RERAISE 1 %4d L9: RERAISE 0 diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index 5c2d69934b02ea6..b4cef37f22eb606 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1955,8 +1955,8 @@ def func(): ('branch', 'func', 4, 4), ('line', 'func', 5), ('line', 'meth', 1), - ('jump', 'func', 5, '[offset=122]'), - ('branch', 'func', '[offset=126]', '[offset=132]'), + ('jump', 'func', 5, '[offset=118]'), + ('branch', 'func', '[offset=122]', '[offset=128]'), ('line', 'get_events', 11)]) self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [ @@ -1970,8 +1970,8 @@ def func(): ('line', 'func', 5), ('line', 'meth', 1), ('return', 'meth', None), - ('jump', 'func', 5, '[offset=122]'), - ('branch', 'func', '[offset=126]', '[offset=132]'), + ('jump', 'func', 5, '[offset=118]'), + ('branch', 'func', '[offset=122]', '[offset=128]'), ('return', 'func', None), ('line', 'get_events', 11)]) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-18-54-06.gh-issue-145749.o1IQ5P.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-18-54-06.gh-issue-145749.o1IQ5P.rst new file mode 100644 index 000000000000000..eab4b459ddef25c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-18-54-06.gh-issue-145749.o1IQ5P.rst @@ -0,0 +1 @@ +Named exception blocks are now faster as they no longer use a ``DELETE_FAST`` instruction. diff --git a/Python/codegen.c b/Python/codegen.c index fa8c4ce88956557..7056145642617b4 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -2331,6 +2331,46 @@ codegen_continue(compiler *c, location loc) return SUCCESS; } +static int +codegen_clear_exception_name(compiler *c, identifier name) +{ + PyObject *mangled = _PyCompile_MaybeMangle(c, name); + if (mangled == NULL) { + return ERROR; + } + + int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled); + if (scope == -1) { + Py_DECREF(mangled); + return ERROR; + } + + _PyCompile_optype optype; + Py_ssize_t arg = 0; + if (_PyCompile_ResolveNameop( + c, mangled, scope, &optype, &arg) < 0) { + Py_DECREF(mangled); + return ERROR; + } + + if (optype == COMPILE_OP_FAST) { + ADDOP(c, NO_LOCATION, PUSH_NULL); + ADDOP_N(c, NO_LOCATION, STORE_FAST_MAYBE_NULL, mangled, varnames); + Py_DECREF(mangled); + return SUCCESS; + } + + Py_DECREF(mangled); + + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + codegen_nameop(c, NO_LOCATION, name, Store)); + RETURN_IF_ERROR( + codegen_nameop(c, NO_LOCATION, name, Del)); + + return SUCCESS; +} + /* Code generated for "try:
finally: