Add full PEP 798 support#25104
Conversation
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.
Typing conformance resultsNo changes detected ✅Current numbersThe 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. |
Memory usage reportMemory usage unchanged ✅ |
|
|
MichaReiser
left a comment
There was a problem hiding this comment.
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 fixThese 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| // 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()); |
There was a problem hiding this comment.
@ibraheemdev would you mind taking a look at this change and whether there's a better way to avoid the duplicate diagnostic
|
Thanks! I added coverage to a number of other rules. |
| // 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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
The range here seems off. It should start at ** not at {
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.