Closed
Description
Python 3.12 introduced a change in tracing behavior. Now a conditional in a finally block will revisit the condition before exiting the block.
Here is test.py:
import sys
print(sys.version)
def example(raise_exc: bool, enter_finally_cond: bool):
try:
if raise_exc:
print("raising exception")
raise Exception
print("not raising exception")
finally:
if enter_finally_cond:
print("in finally conditional")
print("after finally")
try:
example(raise_exc=True, enter_finally_cond=True)
except:
pass
When traced under 3.11:
% python3.11 -m trace --trace test.py
--- modulename: test, funcname: <module>
test.py(1): import sys
test.py(2): print(sys.version)
3.11.4 (main, Jun 7 2023, 08:42:37) [Clang 14.0.3 (clang-1403.0.22.14.1)]
test.py(4): def example(raise_exc: bool, enter_finally_cond: bool):
test.py(16): try:
test.py(17): example(raise_exc=True, enter_finally_cond=True)
--- modulename: test, funcname: example
test.py(5): try:
test.py(6): if raise_exc:
test.py(7): print("raising exception")
raising exception
test.py(8): raise Exception
test.py(11): if enter_finally_cond:
test.py(12): print("in finally conditional")
in finally conditional
test.py(18): except:
test.py(19): pass
When traced under 3.12:
% python3.12 -m trace --trace test.py
--- modulename: test, funcname: <module>
test.py(1): import sys
test.py(2): print(sys.version)
3.12.0b2 (main, Jun 7 2023, 08:47:18) [Clang 14.0.3 (clang-1403.0.22.14.1)]
test.py(4): def example(raise_exc: bool, enter_finally_cond: bool):
test.py(16): try:
test.py(17): example(raise_exc=True, enter_finally_cond=True)
--- modulename: test, funcname: example
test.py(5): try:
test.py(6): if raise_exc:
test.py(7): print("raising exception")
raising exception
test.py(8): raise Exception
test.py(11): if enter_finally_cond:
test.py(12): print("in finally conditional")
in finally conditional
test.py(11): if enter_finally_cond: # <******
test.py(18): except:
test.py(19): pass
The extra line is marked with <******
. There's no reason for the if statement to be traced again.