Skip to content

comp_if should be moved into comp_for to correctly reflect Python's comprehension grammar #1525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JIAQIA opened this issue Apr 14, 2025 · 0 comments

Comments

@JIAQIA
Copy link

JIAQIA commented Apr 14, 2025

Describe the Bug

In Python, the following syntax is valid:

[(i, j) for i in range(3) if i > 0 for j in range(5) if j % 2 == 0]

However, in the current python.lark grammar, the relevant rule is defined as:

comprehension{comp_result}: comp_result comp_fors [comp_if]
comp_fors: comp_for+
comp_for: [ASYNC] "for" exprlist "in" or_test

With this grammar definition, the two if conditions cannot be parsed correctly. It only allows cases such as:

[(i, j) for i in range(3) for j in range(5) if j % 2 == 0 if j > 0]

In this structure, the if clauses are associated globally with the entire comprehension rather than individually with each for clause. This is incorrect because, in Python, each for clause in a comprehension can have its own set of if filters.

To Reproduce

I’m unable to provide a simple standalone reproduction script, but as described above, the provided example:

[(i, j) for i in range(3) if i > 0 for j in range(5) if j % 2 == 0]

fails to parse correctly under the current grammar. The issue is that the if clauses are incorrectly attached to the comprehension rule as a whole, rather than being associated with their respective comp_for. Each for loop in a comprehension should be able to have its own if filters.

Proposed Fix

In my project, the issue was resolved by modifying the grammar as follows:

comprehension{comp_result}: comp_result comp_fors
comp_fors: comp_for+
comp_for: [ASYNC] "for" exprlist "in" or_test comp_if*

This change allows each for clause to optionally have its own if filters, which aligns with Python’s actual comprehension syntax.

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

No branches or pull requests

1 participant