diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index cefd64ddfe8417..0e32ee809b8e77 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -469,7 +469,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) @@ -477,16 +477,14 @@ def foo(a: int, b: str) -> str: LOAD_ATTR 2 (__traceback__) STORE_FAST 1 (tb) L7: POP_EXCEPT - LOAD_CONST 1 (None) + PUSH_NULL STORE_FAST 0 (e) - DELETE_FAST 0 (e) %4d LOAD_FAST 1 (tb) RETURN_VALUE - -- L8: LOAD_CONST 1 (None) + -- L8: PUSH_NULL STORE_FAST 0 (e) - DELETE_FAST 0 (e) RERAISE 1 %4d L9: RERAISE 0 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 00000000000000..eab4b459ddef25 --- /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 5749b615386717..ac37d4cca239d5 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -2526,7 +2526,7 @@ codegen_try_except(compiler *c, stmt_ty s) try: # body finally: - name = None # in case body contains "del name" + name = # in case body contains "del name" del name */ @@ -2541,26 +2541,22 @@ codegen_try_except(compiler *c, stmt_ty s) /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body); - /* name = None; del name; # Mark as artificial */ + /* name = ; del name; # Mark as artificial */ ADDOP(c, NO_LOCATION, POP_BLOCK); ADDOP(c, NO_LOCATION, POP_BLOCK); ADDOP(c, NO_LOCATION, POP_EXCEPT); - ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + ADDOP(c, NO_LOCATION, PUSH_NULL); RETURN_IF_ERROR( codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); - RETURN_IF_ERROR( - codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end); /* except: */ USE_LABEL(c, cleanup_end); - /* name = None; del name; # artificial */ - ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + /* name = ; del name; # artificial */ + ADDOP(c, NO_LOCATION, PUSH_NULL); RETURN_IF_ERROR( codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); - RETURN_IF_ERROR( - codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); ADDOP_I(c, NO_LOCATION, RERAISE, 1); } @@ -2725,7 +2721,7 @@ codegen_try_star_except(compiler *c, stmt_ty s) try: # body finally: - name = None # in case body contains "del name" + name = # in case body contains "del name" del name */ /* second try: */ @@ -2739,27 +2735,23 @@ codegen_try_star_except(compiler *c, stmt_ty s) /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body); - /* name = None; del name; # artificial */ + /* name = ; del name; # artificial */ ADDOP(c, NO_LOCATION, POP_BLOCK); if (handler->v.ExceptHandler.name) { - ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + ADDOP(c, NO_LOCATION, PUSH_NULL); RETURN_IF_ERROR( codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); - RETURN_IF_ERROR( - codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); } ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except); /* except: */ USE_LABEL(c, cleanup_end); - /* name = None; del name; # artificial */ + /* name = ; del name; # artificial */ if (handler->v.ExceptHandler.name) { - ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + ADDOP(c, NO_LOCATION, PUSH_NULL); RETURN_IF_ERROR( codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); - RETURN_IF_ERROR( - codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); } /* add exception raised to the res list */