[PT006] Fix syntax error when unpacking nested tuples in parametrize fixes (#22441)#22464
[PT006] Fix syntax error when unpacking nested tuples in parametrize fixes (#22441)#22464ntBre merged 5 commits intoastral-sh:mainfrom
Conversation
…fixes (astral-sh#22441) When fixing PT006, the code generator would unparse tuples without outer parentheses, causing syntax errors like `[1, 2,]` or `[(1,),,]` in parametrize decorators. This introduces `is_parenthesized` and `unparse_expr_in_sequence` helper functions to ensure tuples are properly parenthesized when used as sequence elements. Added regression tests for nested tuple edge cases including empty tuples, single-element tuples, and deeply nested structures.
|
|
@AlexWaygood I think this was missed for assignment. |
|
Thanks for the ping. I just requested my review, but we're a bit focused on the upcoming 0.15 release this week, so I may not get to this until next week. |
|
Totally understandable, thanks for the update and good luck with the 0.15 release! :) |
ntBre
left a comment
There was a problem hiding this comment.
Thanks for working on this! See my inline comment about parenthesized_range. I tried it locally and all of the tests pass, so we either need more tests, or we should reuse the existing function. This otherwise looks reasonable to me.
|
Thanks for checking. I added a regression case that shows why @pytest.mark.parametrize(
["param"],
[
(((1,)),),
],
)
def test_single_element_grouped_tuple(param): ...With |
|
Thanks! I took another look at this today, and I think a better solution is just to avoid the generator entirely and use |
Summary
Fixes a syntax error bug in the
PT006rule where applying fixes could generate invalid Python code.Problem: When unpacking nested tuples in
pytest.mark.parametrizedecorators, Ruff's code generator unparses tuples without outer parentheses at level 0 (e.g.,(1, 2)becomes1, 2and((1,),)becomes(1,),). This caused syntax errors like[1, 2,]or[(1,),,]when used as list elements.Solution: Introduced two helper functions in
parametrize.rs:is_parenthesized: Validates if a string is fully enclosed in matching parenthesesunparse_expr_in_sequence: Ensures non-empty tuples are always parenthesized when used as sequence elementsFixes #22441
Test Plan
Added comprehensive regression tests to
PT006.pycovering:((),)((1,),)((1, 2),)(((1,),),)("hello",,),([1, 2],,)Verified edge cases with automated snapshot testing:
PT006_default.snap,PT006_csv.snap,PT006_list.snap