Skip to content

3.12 tracing regression: a conditional in a finally block will revisit the condition before exiting the block. #105658

Closed
@nedbat

Description

@nedbat

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.

Linked PRs

Metadata

Metadata

Assignees

Labels

3.12bugs and security fixes3.13bugs and security fixestype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions