Skip to content

Preserve each chained comprehension filter’s polarity - #20

Open
EiNSTeiN- wants to merge 2 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/comprehension-filter-polarity
Open

EiNSTeiN- wants to merge 2 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/comprehension-filter-polarity

Conversation

@EiNSTeiN-

Copy link
Copy Markdown

I am opening this PR to preserve each comprehension filter's polarity when its acceptance edge leads to another filter. The code below currently decompiles with its first two tests inverted:

def select(rows, wanted):
    return [row.tag for row in rows
            if row.value == wanted if row.ready() if row.final()]

The incorrect output is:

def select(rows, wanted):
    return [row.tag for row in rows
            if row.value != wanted if not row.ready() if row.final()]

This selects different rows and changes which comparison and method calls run. For example, a matching row no longer reaches ready(), while a nonmatching row can reach it and raise an exception that the source skips.

A forward jump accepting the first filter can land at the next filter rather than at append. The parser's scan onward for append can encounter that later filter's rejection edge and invert the first filter. The fix first proves the current fallthrough's exact padding/back-edge trampoline to the current comprehension loop. That identifies the current jump's acceptance/rejection polarity without adopting later filters' control flow.

Variations include !=, not row.ready(), one and-joined filter versus multiple if clauses, and list, set and dictionary comprehensions. Both same-line and line-broken filters retain their short-circuit order.

The additional recognition starts at Python 3.12, matching the introduction of inlined comprehensions in PEP 709. The earlier separate-code-object path retains its existing handling.

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