Skip to content

Report a specific diagnostic for walrus in a comprehension iterable expression - #11606

Open
Henry Su (hsusul) wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix/walrus-comprehension-iterable-message
Open

Report a specific diagnostic for walrus in a comprehension iterable expression#11606
Henry Su (hsusul) wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix/walrus-comprehension-iterable-message

Conversation

@hsusul

Copy link
Copy Markdown
Contributor

Summary

An assignment expression (:=) used anywhere within the iterable expression of a comprehension's for clause is a syntax error under PEP 572, and — unlike a walrus used bare as a comprehension if condition — it cannot be made legal by adding parentheses. Pyright already reports this as an error, but it reused the generic message:

Operator ":=" is not allowed in this context without surrounding parentheses

That message is misleading here: the offending walrus in the reproduction is already parenthesized, and no amount of parenthesization will fix it. This addresses #11514.

Minimal reproduction

result = [
    y
    for y in [
        z
        for k in range(10)
        if (z := k * 2) % 3 == 0   # inner comprehension is the outer iterable
    ]
]

CPython:

SyntaxError: assignment expression cannot be used in a comprehension iterable expression

Current behavior

Pyright reports Operator ":=" is not allowed in this context without surrounding parentheses, even though the walrus is parenthesized.

Corrected behavior

Pyright reports Operator ":=" is not allowed within a comprehension iterable expression.

Root cause

In parser.ts, _parseAssignmentExpression emitted walrusNotAllowed for two distinct conditions that were OR'd together:

if (!this._assignmentExpressionsAllowed || disallowAssignmentExpression) {
    this._addSyntaxError(LocMessage.walrusNotAllowed(), walrusToken);
}

These two flags actually represent different restrictions:

  • !this._assignmentExpressionsAllowed is set only by _disallowAssignmentExpression, whose only caller wraps parsing of a comprehension for ... in <iterable> sequence expression. This is the "walrus in a comprehension iterable" restriction, which parentheses do not resolve.
  • disallowAssignmentExpression corresponds to a bare walrus that requires surrounding parentheses (e.g. an unparenthesized walrus used as a comprehension if condition, or a bare walrus where a test expression is expected). Here parentheses do resolve the error, so the existing message is correct.

Implementation

  • Split the condition so the comprehension-iterable case emits a new dedicated message walrusNotAllowedInComprehension, while the parentheses case keeps walrusNotAllowed. The iterable case is checked first so it wins when both apply (parentheses would not help there either).
  • Added the walrusNotAllowedInComprehension key to localize.ts and package.nls.en-us.json.

Error detection (which cases are flagged, and the diagnostic range) is unchanged — only the message text differs for the comprehension-iterable case.

Tests

  • New sample assignmentExprMessage1.py and test AssignmentExprMessage1 assert the exact message for both branches: the comprehension-iterable case gets the new message, and a bare walrus in a comprehension if keeps the generic message.
  • The existing AssignmentExpr4 test (which already exercises iterable-walrus cases) continues to pass with its error count unchanged, confirming detection is unaffected.

Validation

Run in packages/pyright-internal:

  • npx tsc --noEmit — passes.
  • npx prettier@2.8.8 -c on all changed TS/JSON files — "All matched files use Prettier code style!".
  • git diff --check — clean.
  • npx jest parser tokenizer typeEvaluator1 — all pass (includes the new AssignmentExprMessage1 and the unchanged AssignmentExpr4).
  • Full npx jest — all suites pass except LSP/type-server integration suites, which fail to run in this environment because they require the full monorepo bootstrap and the webpack test-server bundle (Cannot find module 'fs-extra' / Server bundle does not exist); these are unrelated to this change.

Compatibility

No API changes. The only behavioral difference is a more accurate diagnostic message for walrus operators inside a comprehension iterable expression; the set of reported errors and their source ranges are unchanged.

A walrus operator used anywhere within a comprehension's iterable
expression is a syntax error (PEP 572), and it cannot be fixed by
adding parentheses. Pyright detected this but reused the generic
"is not allowed in this context without surrounding parentheses"
message, which is misleading here.

Emit a dedicated message for this case while preserving the existing
message for a bare walrus used as a comprehension "if" condition,
where parentheses do resolve the error.

Addresses microsoft#11514.
@StellaHuang95

Stella Huang (StellaHuang95) commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

🔒 Automated review in progress — Stella Huang (@StellaHuang95) is auto-reviewing this PR.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved via Review Center.

@StellaHuang95 Stella Huang (StellaHuang95) added the review-auto:approved Automated review: no blocking findings (approval posted). label Aug 10, 2026

@rchiodo Rich Chiodo (rchiodo) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved via Review Center.

@rchiodo Rich Chiodo (rchiodo) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved via Review Center.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved via Review Center.

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

Labels

review-auto:approved Automated review: no blocking findings (approval posted).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants