ruff/crates/ruff_python_parser/resources/inline/ok
Brent Westbrook 71f8389f61
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.
2025-10-13 14:13:27 -04:00
..
all_async_comprehension_py310.py
ambiguous_lpar_with_items_binary_expr.py
ambiguous_lpar_with_items_if_expr.py
ann_assign_stmt_simple_target.py
args_unparenthesized_generator.py
assign_stmt_starred_expr_value.py
assign_targets_terminator.py
async_for_statement.py
async_function_definition.py
async_with_statement.py
class_def_arguments.py
class_keyword_in_case_pattern.py
class_type_params_py312.py
comma_separated_regular_list_terminator.py
debug_rename_import.py
decorator_async_function.py
decorator_await_expression_py39.py
decorator_expression_dotted_ident_py38.py
decorator_expression_eval_hack_py38.py
decorator_expression_identity_hack_py38.py
decorator_expression_py39.py
del_debug_py38.py
del_targets_terminator.py
dotted_name_normalized_spaces.py
duplicate_match_key_attr.py
except_star_py311.py
except_stmt_as_name_soft_keyword.py
except_stmt_unparenthesized_tuple_no_as_py314.py
for_in_target_valid_expr.py
for_iter_unpack_py38.py
for_iter_unpack_py39.py
from_import_no_space.py
from_import_soft_keyword_module_name.py
from_import_stmt_terminator.py
fstring_format_spec_terminator.py
function_def_parameter_range.py
function_def_parenthesized_return_types.py
function_def_valid_return_expr.py
function_type_params_py312.py
global_stmt.py
import_as_name_soft_keyword.py
import_from_star.py [syntax-errors]: import from * only allowed at module scope (F406) (#20166) 2025-09-16 15:53:28 -04:00
import_stmt_terminator.py
irrefutable_case_pattern_at_end.py
iter_unpack_return_py37.py
iter_unpack_return_py38.py
iter_unpack_yield_py37.py
iter_unpack_yield_py38.py
lambda_with_no_parameters.py
lambda_with_valid_body.py
match_after_py310.py
match_as_pattern.py
match_as_pattern_soft_keyword.py
match_attr_pattern_soft_keyword.py
match_classify_as_identifier_1.py
match_classify_as_identifier_2.py
match_classify_as_keyword_1.py
match_classify_as_keyword_2.py
match_classify_as_keyword_or_identifier.py
match_sequence_pattern_parentheses_terminator.py
match_sequence_pattern_terminator.py
match_stmt_subject_expr.py
match_stmt_valid_guard_expr.py
multiple_assignment_in_case_pattern.py
multiple_starred_assignment_target.py [syntax-errors]: multiple-starred-expressions (F622) (#20243) 2025-09-24 19:32:55 +00:00
nested_async_comprehension_py310.py
nested_async_comprehension_py311.py
non_duplicate_type_parameter_names.py
non_rebound_comprehension_variable.py
nonlocal_declaration_at_module_level.py
nonlocal_stmt.py
param_with_annotation.py
param_with_default.py
param_with_star_annotation.py
param_with_star_annotation_py310.py
param_with_star_annotation_py311.py
params_non_default_after_star.py
params_seen_keyword_only_param_after_star.py
parenthesized_context_manager_py39.py
parenthesized_kwarg_py37.py
parenthesized_named_expr_index_py38.py
parenthesized_named_expr_py38.py
parenthesized_star_index_py310.py
pep701_f_string_py311.py
pep701_f_string_py312.py
pep750_t_string_py314.py
pos_only_py38.py
read_from_debug.py
simple_stmts_in_block.py
simple_stmts_with_semicolons.py
single_parenthesized_item_context_manager_py38.py Fix syntax error false positives on parenthesized context managers (#20846) 2025-10-13 14:13:27 -04:00
single_star_in_tuple.py
single_starred_assignment_target.py
star_index_py311.py
template_strings_py314.py Disallow implicit concatenation of t-strings and other string types (#19485) 2025-07-27 12:41:03 +00:00
tuple_context_manager_py38.py
type_param_default_py313.py
type_param_param_spec.py
type_param_type_var.py
type_param_type_var_tuple.py
type_stmt_py312.py
unparenthesized_named_expr_index_py39.py
unparenthesized_named_expr_py39.py
valid_annotation_class.py
valid_annotation_function_py313.py
valid_annotation_py313.py
valid_future_feature.py [syntax-errors]: future-feature-not-defined (F407) (#20554) 2025-09-25 13:52:24 -04:00
walrus_py38.py