Skip to content

Add full PEP 798 support#25104

Open
JelleZijlstra wants to merge 7 commits into
astral-sh:mainfrom
JelleZijlstra:pep798
Open

Add full PEP 798 support#25104
JelleZijlstra wants to merge 7 commits into
astral-sh:mainfrom
JelleZijlstra:pep798

Conversation

@JelleZijlstra
Copy link
Copy Markdown
Collaborator

@JelleZijlstra JelleZijlstra commented May 11, 2026

Fixes #25098.

This adds full support for PEP 798 through the parser, linter, formatter, and type checker.
There are a lot of changes but they are mostly straightforward. Let me know though if it's better to split this up.

Fixes astral-sh#25098.

This adds full support for PEP 798 through the parser, linter, formatter, and type checker.
There are a lot of changes but they are mostly straightforward.
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented May 11, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 89.36%. The percentage of expected errors that received a diagnostic held steady at 85.49%. The number of fully passing files held steady at 88/134.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented May 11, 2026

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented May 11, 2026

ecosystem-analyzer results

No diagnostic changes detected ✅

Full report with detailed diff (timing results)

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented May 11, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@JelleZijlstra JelleZijlstra marked this pull request as ready for review May 11, 2026 15:41
@astral-sh-bot astral-sh-bot Bot requested a review from ntBre May 11, 2026 15:42
@MichaReiser MichaReiser assigned charliermarsh and unassigned ntBre May 12, 2026
Copy link
Copy Markdown
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Nice, thank you. This is great

I found a formatting issue that we should look into (surprise, comments)

I think it would also be worth adding coverage to some other rules that work on list, dict, and set comprehensions, like:

xs = [[1], [2]]

list([*x for x in xs])      # C411 diagnostic, but no fix
all([*x for x in xs])       # C419 diagnostic, but no fix
any({*x for x in xs})       # C419 diagnostic, but no fix

These won't have fixes until we update libCST

list(*x for x in xs) -> [*x for x in xs]   # C400
set(*x for x in xs)  -> {*x for x in xs}   # C401
dict({**d for d in dicts}) -> {**d for d in dicts}  # C418

Comment thread crates/ruff_python_parser/src/error.rs Outdated
Comment thread crates/ty_python_semantic/src/types/infer/builder.rs Outdated
Comment on lines +6709 to +6712
// Dict-unpack comprehensions are typed by the outer expression inference. Inferring
// them through the collection-literal helper here would report the same invalid
// mapping diagnostic twice.
self.infer_expression(value, TypeContext::default());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ibraheemdev would you mind taking a look at this change and whether there's a better way to avoid the duplicate diagnostic

@JelleZijlstra
Copy link
Copy Markdown
Collaborator Author

Thanks! I added coverage to a number of other rules.

Comment thread crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs Outdated
Comment on lines +2079 to +2085
// test_err pep_798_unpacking_comprehensions_py314
// # parse_options: {"target-version": "3.14"}
// [*x for x in y]
// {*x for x in y}
// {**x for x in y}
// (*x for x in y)
// f(*x for x in y)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we add some more test cases described in the PEP? It's fine to skip improving the error message in this PR as I think these would current just raise a "Starred expression cannot be used here"

>>> {*k: v for k,v in items}
  File "<stdin>", line 1
    {*k: v for k,v in items}
     ^^
SyntaxError: cannot use a starred expression in a dictionary key

>>> {k: *v for k,v in items}
  File "<stdin>", line 1
    {k: *v for k,v in items}
        ^^
SyntaxError: cannot use a starred expression in a dictionary value

>>> {**k: v for k,v in items}
  File "<stdin>", line 1
    {**k: v for k,v in items}
     ^^^
SyntaxError: cannot use dict unpacking in a dictionary key

>>> {k: **v for k,v in items}
  File "<stdin>", line 1
    {k: **v for k,v in items}
        ^^^
SyntaxError: cannot use dict unpacking in a dictionary value

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, this exposed a bug too (the recovery after this error was broken)

2 | {*k: v for k, v in items}
3 | {k: *v for k, v in items}
4 | {**k: v for k, v in items}
| ^^^^ Syntax Error: Starred expression cannot be used here
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The range here seems off. It should start at ** not at {

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parser support for PEP 798 in Python 3.15

5 participants