Reject more syntactically invalid Python programs#8524
Conversation
bd787b4 to
db76759
Compare
charliermarsh
left a comment
There was a problem hiding this comment.
This is excellent! Welcome to the repo :)
This commit adds some additional error checking to the parser such that assignments that are invalid syntax are rejected. This covers the obvious cases like `5 = 3` and some not so obvious cases like `x + y = 42`. This does add an additional recursive call to the parser for the cases handling assignments. I had initially been concerned about doing this, but `set_context` is already doing recursion during assignments, so I didn't feel as though this was changing any fundamental performance characteristics of the parser. (Also, in practice, I would expect any such recursion here to be quite shallow since the recursion is done on the target of an assignment. Such things are rarely nested much in practice.) Fixes #6895
This test previously asserted that, e.g., `a = 1, b = 2`, was valid
Python code. But it turns out that it is not:
>>> a = 1, b = 2
File "<input>", line 1
a = 1, b = 2
^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
This commit flips the particular assert to check that no Python code is
detected within the comment.
With the parser becoming a bit more strict, it discovered some invalid
syntax in one of the formatter tests. In particular, `yield a = 1`:
>>> (yield a, b) = (1, 2)
File "<input>", line 1
(yield a, b) = (1, 2)
^^^^^^^^^^
SyntaxError: cannot assign to yield expression here. Maybe you meant '==' instead of '='?
We just remove that bit from the `yield` test.
db76759 to
9142dae
Compare
|
@charliermarsh Can you check out the two commits I've just pushed? In particular, the stricter parser caused two tests to fail. I think my changes to those tests are correct, but I'd like to be cautious here! |
|
Taking a closer look at those changes... |
|
@BurntSushi - Those both look correct to me. I actually don't fully understand why |
For |
|
Ahh ok, so it's like |
|
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| ERA001 | 27 | 0 | 27 | 0 | 0 |
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+0 -25 violations, +0 -0 fixes in 41 projects)
apache/airflow (+0 -6 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --select ALL --preview
- airflow/config_templates/default_webserver_config.py:84:1: ERA001 Found commented-out code - airflow/example_dags/tutorial.py:63:9: ERA001 Found commented-out code - airflow/settings.py:633:1: ERA001 Found commented-out code - airflow/utils/log/secrets_masker.py:174:13: ERA001 Found commented-out code - tests/system/providers/amazon/aws/example_eks_templated.py:45:1: ERA001 Found commented-out code - tests/system/providers/amazon/aws/example_eks_templated.py:49:1: ERA001 Found commented-out code
bokeh/bokeh (+0 -6 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --select ALL --preview
- examples/integration/layout/plot_fixed_frame_size.py:40:1: ERA001 Found commented-out code - tests/integration/widgets/tables/test_source_updates.py:114:9: ERA001 Found commented-out code - tests/integration/widgets/tables/test_source_updates.py:167:9: ERA001 Found commented-out code - tests/integration/widgets/tables/test_source_updates.py:221:9: ERA001 Found commented-out code - tests/integration/widgets/tables/test_source_updates.py:269:9: ERA001 Found commented-out code - tests/unit/bokeh/plotting/test__renderer.py:125:1: ERA001 Found commented-out code
zulip/zulip (+0 -13 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --select ALL --preview
- zerver/data_import/slack.py:581:13: ERA001 Found commented-out code - zerver/lib/digest.py:89:1: ERA001 Found commented-out code - zerver/lib/display_recipient.py:106:5: ERA001 Found commented-out code - zerver/lib/email_notifications.py:309:5: ERA001 Found commented-out code - zerver/lib/email_notifications.py:317:5: ERA001 Found commented-out code - zerver/lib/email_notifications.py:321:5: ERA001 Found commented-out code - zerver/middleware.py:152:13: ERA001 Found commented-out code - zerver/middleware.py:175:13: ERA001 Found commented-out code - zerver/tests/test_events.py:548:13: ERA001 Found commented-out code - zerver/tests/test_events.py:550:13: ERA001 Found commented-out code - zerver/tests/test_events.py:556:17: ERA001 Found commented-out code - zerver/tests/test_events.py:727:9: ERA001 Found commented-out code - zproject/prod_settings_template.py:264:1: ERA001 Found commented-out code
Changes by rule (1 rules affected)
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| ERA001 | 25 | 0 | 25 | 0 | 0 |
Formatter (stable)
✅ ecosystem check detected no format changes.
Formatter (preview)
✅ ecosystem check detected no format changes.
|
Those ecosystem changes look like strict improvements to me. |
dhruvmanila
left a comment
There was a problem hiding this comment.
Thanks for writing such a thorough test suite! :)
Summary
This commit adds some additional error checking to the parser such that assignments that are invalid syntax are rejected. This covers the obvious cases like
5 = 3and some not so obvious cases likex + y = 42.This does add an additional recursive call to the parser for the cases handling assignments. I had initially been concerned about doing this, but
set_contextis already doing recursion during assignments, so I didn't feel as though this was changing any fundamental performance characteristics of the parser. (Also, in practice, I would expect any such recursion here to be quite shallow since the recursion is done on the target of an assignment. Such things are rarely nested much in practice.)Fixes #6895
Test Plan
I've added unit tests covering every case that is detected as invalid on an
Expr.