Skip to content

Keep parens around lambda iterables in comprehensions (preview)#5176

Merged
cobaltt7 merged 1 commit into
psf:mainfrom
sarathfrancis90:fix-comprehension-lambda-parens
Jun 15, 2026
Merged

Keep parens around lambda iterables in comprehensions (preview)#5176
cobaltt7 merged 1 commit into
psf:mainfrom
sarathfrancis90:fix-comprehension-lambda-parens

Conversation

@sarathfrancis90

Copy link
Copy Markdown
Contributor

Description

On --preview, this code crashes Black with an ASTSafetyError:

[x for x in (lambda: 0) if x]

wrap_comprehension_in makes the parens around a comprehension's iterable
invisible when the inner expression is low-precedence. There's already a guard
that keeps them for ternaries, but it only checks for syms.test, so a lambda
iterable slips through. Dropping the parens lets the trailing if/for clauses
get parsed as part of the lambda body (lambda: 0 if x), which isn't valid, so
Black emits unparsable output and bails out with an internal error. A bare
[x for x in (lambda y: y)] is broken the same way.

The fix extends the existing guard to also cover syms.lambdef. Long lambda
iterables still get wrapped, just with the parens kept. Hit a few comprehension
shapes (list/set/dict/genexpr, trailing if and for) while checking it.

Checklist - did you ...

  • Implement any code style changes under the --preview style, following the stability policy?
  • Add an entry in CHANGES.md if necessary?
  • Add / update tests if necessary?
  • Add new / update outdated documentation?
wrap_comprehension_in made the visible parens around the iterable after
`in` invisible whenever the inner expression was a low-precedence test,
but the guard that preserves them for ternaries only checked for
syms.test. A lambda iterable such as `[x for x in (lambda: 0) if x]`
fell through, so the parens were dropped and the trailing comprehension
clauses were swallowed into the lambda body, producing unparsable output
and an ASTSafetyError crash. Extend the guard to syms.lambdef as well.
@sarathfranciswork sarathfranciswork force-pushed the fix-comprehension-lambda-parens branch from c17fc45 to f0ce134 Compare June 12, 2026 08:09
@github-actions

Copy link
Copy Markdown
Contributor

diff-shades results comparing this PR (f0ce134) to main (6325332):

--preview style: no changes

--stable style: no changes


What is this? | Workflow run | diff-shades documentation

@cobaltt7 cobaltt7 merged commit f50ab10 into psf:main Jun 15, 2026
57 checks passed
sarathfrancis90 added a commit to sarathfrancis90/black that referenced this pull request Jun 26, 2026
…view)

`wrap_comprehension_in` keeps the parentheses around a lambda or conditional
expression used as a comprehension's iterable, otherwise the trailing
`for`/`if` clauses get absorbed into it and the result is invalid. psf#5176
handled the single-paren case, but `maybe_make_parens_invisible_in_atom`
recurses through the atom, so a redundantly nested pair like
`[x for x in ((lambda: 0))]` still had *both* layers stripped, producing
`[x for x in lambda: 0]` and crashing with an ASTSafetyError.

Look through redundant nested parens before deciding whether the atom wraps a
lambda or ternary, so at least one pair is kept.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants