ruff/crates/ruff_python_parser/resources/valid/expressions/arguments.py
Brent Westbrook 2baaedda6c
[syntax-errors] Start detecting compile-time syntax errors (#16106)
## Summary

This PR implements the "greeter" approach for checking the AST for
syntax errors emitted by the CPython compiler. It introduces two main
infrastructural changes to support all of the compile-time errors:
1. Adds a new `semantic_errors` module to the parser crate with public
`SemanticSyntaxChecker` and `SemanticSyntaxError` types
2. Embeds a `SemanticSyntaxChecker` in the `ruff_linter::Checker` for
checking these errors in ruff

As a proof of concept, it also implements detection of two syntax
errors:
1. A reimplementation of
[`late-future-import`](https://docs.astral.sh/ruff/rules/late-future-import/)
(`F404`)
2. Detection of rebound comprehension iteration variables
(https://github.com/astral-sh/ruff/issues/14395)

## Test plan
Existing F404 tests, new inline tests in the `ruff_python_parser` crate,
and a linter CLI test showing an example of the `Message` output.

I also tested in VS Code, where `preview = false` and turning off syntax
errors both disable the new errors:


![image](https://github.com/user-attachments/assets/cf453d95-04f7-484b-8440-cb812f29d45e)

And on the playground, where `preview = false` also disables the errors:


![image](https://github.com/user-attachments/assets/a97570c4-1efa-439f-9d99-a54487dd6064)


Fixes #14395

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-03-21 14:45:25 -04:00

50 lines
805 B
Python

# This only tests the call arguments and not the expression before the opening parenthesis.
# Simple
call()
call(x, y)
call(x, y,) # Trailing comma
call(x=1, y=2)
call(*x)
call(**x)
# Order
call(x, y=1)
call(x, *y)
call(x, **y)
call(x=1, *y)
call(x=1, **y)
call(*x, **y)
call(*x, y, z)
call(**x, y=1, z=2)
call(*x1, *x2, **y1, **y2)
call(x=1, **y, z=1)
# Keyword expression
call(x=1 if True else 2)
call(x=await y)
call(x=lambda y: y)
call(x=(y := 1))
# Yield expression
call((yield x))
call((yield from x))
# Named expression
call(x := 1)
call(x := 1 for i in iter)
# Starred expressions
call(*x and y)
call(*x | y)
call(*await x)
call(*lambda x: x)
call(*x if True else y)
# Double starred
call(**x)
call(**x and y)
call(**await x)
call(**x if True else y)
call(**(yield x))
call(**lambda x: x)