-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emit diagnostics for new syntax as per the target Python version #6591
Comments
The Match and Type alias statement can be implemented in the AST Statement analyzer within the match arms of the respective statement and checking the I would suggest to add this as a new rule under the |
There might be other new syntax worth addressing:
Some of these might be closer to functional changes than syntax and hard to detect. But perhaps the easy ones could be folded in? There are advantages to python 3.12 that might make people want to develop with it even though their code is meant to run on python 3.9 (say). |
Just to say we have a use case for targeting 3.7. Thanks for the great work on this! |
So far, most new syntaxes were not "auto-applied" during formatting, but PEP-701 f-string placeholder updates are auto-applied to all codes. This prevents backporting those codes to older Python versions seamlessly as Ruff does not report syntax errors in older Python versions. Looking forward to see this issue to be resolved. 👀 |
We'd appreciate contributions here if someone is interested in working on the project. We can do this relatively incrementally, but there is some initial complexity to determine how diagnostics are propagated. @dhruvmanila / @charliermarsh will provide some additional details. |
@td-anne For visibility, I've updated the PR description based on your list but this issue is mainly focused on the syntax itself and not the semantic meaning. For example, dictionary union (
But, the following can possibly be done as a separate rule and is not part of what we're proposing here.
Can you expand on the following? I don't see any new syntax related to PEP 617.
|
These did involve the introduction of some new syntax: unpacking using |
I see. Thanks for pointing that out. I'll update the PR description. |
The goal here is to update Ruff to detect syntax which is invalid as per the
For (1),
For (2),
I'm more leaning towards (2). An open question here is to whether implement this as a new rule or add it to |
I support detecting these syntax errors via the linter (Option (2)) wherever possible. I think it'll be great to have these errors be I'd much prefer to have these syntax errors be detected as part of |
I think one key difference between the two is that you should never suppress a syntax error that is an error regardless of the python version (I don't even know if we support suppressing them). I don't know if there are good reasons for suppressing python-version specific syntax errors but I could see an argument for that. I don't think these should be suppressed by inline noqa comments but a user might decide to suppress them with |
The only reasons I can see for wanting to suppress a syntax error diagnostic are:
If you have the right target version in your config file, I can't personally see any reason why you'd want to be able to suppress Python-version-specific syntax error diagnostics, or treat them any differently from syntax that's invalid on all Python versions. |
Any updates on this? We are still holding back the ruff version due to the f-string backporting issue. |
Once astral-sh/ruff#6591 is fixed, ruff will do this. (and I should also have CI, but meh)
…ons (#14625) ## Summary fixes: #14608 The logic that was only applied for 3.12+ target version needs to be applied for other versions as well. ## Test Plan I've moved the existing test cases for 3.12 only to `f_string.py` so that it's tested against the default target version. I think we should probably enabled testing for two target version (pre 3.12 and 3.12) but it won't highlight any issue because the parser doesn't consider this. Maybe we should enable this once we have target version specific syntax errors in place (#6591).
Now that
|
There are a few open design questions on where the best place is for those checks to be implemented. A very likely outcome is that some are implemented in the parser while others are implemented in the linter. @ntBre plans to work on this soon and can then advise on where we want to implement which checks |
This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes a couple of additional changes: 1. the `syntax_errors!` macro, which makes adding more variants a bit easier 2. the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error Because of the second point here, this PR is currently stacked on #16357. As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes a couple of additional changes: 1. the `syntax_errors!` macro, which makes adding more variants a bit easier 2. the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error Because of the second point here, this PR is currently stacked on #16357. As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
Summary -- This PR detects another syntax error from #6591 and is stacked on #16383. This time the relaxed grammar for decorators proposed in [PEP 614](https://peps.python.org/pep-0614/) is detected for Python 3.8 and lower. The 3.8 grammar for decorators is [here](https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-decorators): ``` decorators ::= decorator+ decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE dotted_name ::= identifier ("." identifier)* ``` in contrast to the current grammar [here](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-decorators) ``` decorators ::= decorator+ decorator ::= "@" assignment_expression NEWLINE assignment_expression ::= [identifier ":="] expression ``` This was the trickiest one of these to detect yet. It seemed like the best approach was to attempt to parse the old version and fall back on the new grammar if anything goes wrong, but I'm not as confident in this approach since it required adding a `Parser::try_parse_old_decorators` method. Test Plan -- New inline parser tests and linter CLI tests.
Summary -- This PR detects another syntax error from #6591 and is stacked on #16383. This time the relaxed grammar for decorators proposed in [PEP 614](https://peps.python.org/pep-0614/) is detected for Python 3.8 and lower. The 3.8 grammar for decorators is [here](https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-decorators): ``` decorators ::= decorator+ decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE dotted_name ::= identifier ("." identifier)* ``` in contrast to the current grammar [here](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-decorators) ``` decorators ::= decorator+ decorator ::= "@" assignment_expression NEWLINE assignment_expression ::= [identifier ":="] expression ``` This was the trickiest one of these to detect yet. It seemed like the best approach was to attempt to parse the old version and fall back on the new grammar if anything goes wrong, but I'm not as confident in this approach since it required adding a `Parser::try_parse_old_decorators` method. Test Plan -- New inline parser tests and linter CLI tests.
This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes a couple of additional changes: 1. the `syntax_errors!` macro, which makes adding more variants a bit easier 2. the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error Because of the second point here, this PR is currently stacked on #16357. As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
Summary -- This PR detects another syntax error from #6591 and is stacked on #16383. This time the relaxed grammar for decorators proposed in [PEP 614](https://peps.python.org/pep-0614/) is detected for Python 3.8 and lower. The 3.8 grammar for decorators is [here](https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-decorators): ``` decorators ::= decorator+ decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE dotted_name ::= identifier ("." identifier)* ``` in contrast to the current grammar [here](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-decorators) ``` decorators ::= decorator+ decorator ::= "@" assignment_expression NEWLINE assignment_expression ::= [identifier ":="] expression ``` This was the trickiest one of these to detect yet. It seemed like the best approach was to attempt to parse the old version and fall back on the new grammar if anything goes wrong, but I'm not as confident in this approach since it required adding a `Parser::try_parse_old_decorators` method. Test Plan -- New inline parser tests and linter CLI tests.
Summary -- This PR detects another syntax error from #6591 and is stacked on #16383. This time the relaxed grammar for decorators proposed in [PEP 614](https://peps.python.org/pep-0614/) is detected for Python 3.8 and lower. The 3.8 grammar for decorators is [here](https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-decorators): ``` decorators ::= decorator+ decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE dotted_name ::= identifier ("." identifier)* ``` in contrast to the current grammar [here](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-decorators) ``` decorators ::= decorator+ decorator ::= "@" assignment_expression NEWLINE assignment_expression ::= [identifier ":="] expression ``` This was the trickiest one of these to detect yet. It seemed like the best approach was to attempt to parse the old version and fall back on the new grammar if anything goes wrong, but I'm not as confident in this approach since it required adding a `Parser::try_parse_old_decorators` method. Test Plan -- New inline parser tests and linter CLI tests.
Summary -- This PR detects another syntax error from #6591 and is stacked on #16383. This time the relaxed grammar for decorators proposed in [PEP 614](https://peps.python.org/pep-0614/) is detected for Python 3.8 and lower. The 3.8 grammar for decorators is [here](https://docs.python.org/3.8/reference/compound_stmts.html#grammar-token-decorators): ``` decorators ::= decorator+ decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE dotted_name ::= identifier ("." identifier)* ``` in contrast to the current grammar [here](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-decorators) ``` decorators ::= decorator+ decorator ::= "@" assignment_expression NEWLINE assignment_expression ::= [identifier ":="] expression ``` This was the trickiest one of these to detect yet. It seemed like the best approach was to attempt to parse the old version and fall back on the new grammar if anything goes wrong, but I'm not as confident in this approach since it required adding a `Parser::try_parse_old_decorators` method. Test Plan -- New inline parser tests and linter CLI tests.
This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes a couple of additional changes: 1. the `syntax_errors!` macro, which makes adding more variants a bit easier 2. the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error Because of the second point here, this PR is currently stacked on #16357. As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
## Summary This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes the addition of the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error ## Test Plan As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes a couple of additional changes: 1. the `syntax_errors!` macro, which makes adding more variants a bit easier 2. the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error Because of the second point here, this PR is currently stacked on #16357. As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
This PR is the first in a series derived from #16308, each of which add support for detecting one version-related syntax error from #6591. This one should be the largest because it also includes a couple of additional changes: 1. the `syntax_errors!` macro, which makes adding more variants a bit easier 2. the `Parser::add_unsupported_syntax_error` method Otherwise I think the general structure will be the same for each syntax error: * Detecting the error in the parser * Inline parser tests for the new error * New ruff CLI tests for the new error Because of the second point here, this PR is currently stacked on #16357. As noted above, there are new inline parser tests, as well as new ruff CLI tests. Once #16379 is resolved, there should also be new mdtests for red-knot, but this PR does not currently include those.
Our parser doesn't take into account the Python version aka
target-version
setting while parsing the source code. This means that we would allow having a match statement when the target Python version is 3.9 or lower. We want to signal this to the user.One solution is to provide a diagnostic after the parsing is done. This diagnostic would indicate to the user that there's a syntax usage which isn't valid for the current target version. This is what's being done in Rome and Pyright1. We would still continue linting the file and emit other diagnostics as well.
Following is a non-exhaustive list of syntax changes with the minimum required Python version:
3.13
3.12
type
statements ([syntax-errors]type
statements before Python 3.12 #16478)type
parameter lists ([syntax-errors] Type parameter lists before Python 3.12 #16479)3.11
except*
syntax ([syntax-errors]except*
before Python 3.11 #16446)*args
via PEP 6463.10
match
statement (Start detecting version-related syntax errors in the parser #16090)3.9
for
statements on Python 3.9+ (officially made part of the language spec in Python 3.11) (cpython#90881)def i(): return 1, (*rest)
is no longer allowed (something with*rest
)3.8
f((a)=1)
) are no longer allowed on Python 3.8+ (cpython#78822) ([syntax-errors] Parenthesized keyword arguments after Python 3.8 #16482)return
andyield
statements no longer needs to be parenthesized on Pythonn 3.8+ (cpython#76298) ([syntax-errors] Tuple unpacking inreturn
andyield
before Python 3.8 #16485)Footnotes
Pyright: Type alias statement requires Python 3.12 or newer
↩The text was updated successfully, but these errors were encountered: