Skip to content

Exclude frame-wide StopIteration cleanup from exception chains - #7

Open
EiNSTeiN- wants to merge 2 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/frame-stopiteration-handler
Open

EiNSTeiN- wants to merge 2 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/frame-stopiteration-handler

Conversation

@EiNSTeiN-

Copy link
Copy Markdown

I am opening this PR to keep a generator's frame-wide cleanup from swallowing later statements into an earlier exception handler. The code below currently decompiles with an extra else that changes which values are yielded after a handled exception:

def select(work):
    try:
        yield work("first")
    except ValueError:
        yield 2
    yield 3
    try:
        yield work("last")
    except KeyError:
        yield 5
    yield 6

Two sequential exception scopes must resume their shared mainline in order. The exception-chain extent walker can follow the generator/coroutine's frame-wide StopIteration conversion handler and absorb later mainline statements into an earlier lexical handler. In this example, yield 3 and the second try are moved into an else belonging to the first try, so they are skipped when ValueError is handled.

The change makes chain_extent ignore exception-table targets whose head is CALL_INTRINSIC_1 3. This target is frame cleanup, not a source-level except or finally continuation. The same correction applies to the asynchronous-generator variation, written as async def select(work) with the same body.

The relevant CALL_INTRINSIC_1 operation, including INTRINSIC_STOPITERATION_ERROR, is introduced in Python 3.12.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant