Fix syntax error false positives on parenthesized context managers (#20846)

This PR resolves the issue noticed in
https://github.com/astral-sh/ruff/pull/20777#discussion_r2417233227.
Namely, cases like this were being flagged as syntax errors despite
being perfectly valid on Python 3.8:

```pycon
Python 3.8.20 (default, Oct  2 2024, 16:34:12)
[Clang 18.1.8 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> with (open("foo.txt", "w")): ...
...
Ellipsis
>>> with (open("foo.txt", "w")) as f: print(f)
...
<_io.TextIOWrapper name='foo.txt' mode='w' encoding='UTF-8'>
```

The second of these was already allowed but not the first:

```shell
> ruff check --target-version py38 --ignore ALL - <<EOF
with (open("foo.txt", "w")): ...
with (open("foo.txt", "w")) as f: print(f)
EOF
invalid-syntax: Cannot use parentheses within a `with` statement on Python 3.8 (syntax was added in Python 3.9)
 --> -:1:6
  |
1 | with (open("foo.txt", "w")): ...
  |      ^
2 | with (open("foo.txt", "w")) as f: print(f)
  |

Found 1 error.
```

There was some discussion of related cases in
https://github.com/astral-sh/ruff/pull/16523#discussion_r1984657793, but
it seems I overlooked the single-element case when flagging tuples. As
suggested in the other thread, we can just check if there's more than
one element or a trailing comma, which will cause the tuple parsing on
<=3.8 and avoid the false positives.
This commit is contained in:
Brent Westbrook 2025-10-13 14:13:27 -04:00 committed by GitHub
parent 373fe8a39c
commit 71f8389f61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 222 additions and 149 deletions

View file

@ -807,31 +807,6 @@ with (
```
### Unsupported Syntax Errors
error[invalid-syntax]: Cannot use parentheses within a `with` statement on Python 3.8 (syntax was added in Python 3.9)
--> with.py:333:10
|
332 | if True:
333 | with (
| ^
334 | anyio.CancelScope(shield=True)
335 | if get_running_loop()
|
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
error[invalid-syntax]: Cannot use parentheses within a `with` statement on Python 3.8 (syntax was added in Python 3.9)
--> with.py:359:6
|
357 | pass
358 |
359 | with (
| ^
360 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
361 | ):
|
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
### Output 2
```
indent-style = space