From 9fb8d6e99934ebfbb591f227437e01630c7bff20 Mon Sep 17 00:00:00 2001 From: Chris Pryer <14341145+cnpryer@users.noreply.github.com> Date: Wed, 19 Jul 2023 08:05:38 -0400 Subject: [PATCH] Omit tuple parentheses inside comprehensions (#5790) --- .../fixtures/ruff/expression/dict_comp.py | 32 +++++ .../src/expression/expr_tuple.rs | 10 ++ .../src/other/comprehension.rs | 17 ++- ...atibility@simple_cases__expression.py.snap | 36 ++--- .../format@expression__dict_comp.py.snap | 124 +++++++++++++++++- .../format@expression__list_comp.py.snap | 9 +- .../format@expression__set_comp.py.snap | 12 +- 7 files changed, 198 insertions(+), 42 deletions(-) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/dict_comp.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/dict_comp.py index d4c68f01a5..87b0c035a7 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/dict_comp.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/dict_comp.py @@ -43,3 +43,35 @@ if gggggggggggggggggggggggggggggggggggggggggggg } + +# Useful for tuple target (see https://github.com/astral-sh/ruff/issues/5779#issuecomment-1637614763) +{k: v for a, a, a, a, a, a, a, a, a, a, [a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a] in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension} +{k: v for a, a, a, a, a, a, a, a, a, a, (a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension} + +# Leading +{ # Leading + k: v # Trailing + for a, a, a, a, a, a, a, a, a, a, ( # Trailing + a, + a, + a, + a, + a, + a, + a, + a, + a, # Trailing + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, # Trailing + ) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension # Trailing +} # Trailing +# Trailing \ No newline at end of file diff --git a/crates/ruff_python_formatter/src/expression/expr_tuple.rs b/crates/ruff_python_formatter/src/expression/expr_tuple.rs index e0e5689a9c..8e2128a6e7 100644 --- a/crates/ruff_python_formatter/src/expression/expr_tuple.rs +++ b/crates/ruff_python_formatter/src/expression/expr_tuple.rs @@ -14,6 +14,9 @@ use crate::prelude::*; #[derive(Eq, PartialEq, Debug, Default)] pub enum TupleParentheses { + /// Black omits parentheses for tuples inside of comprehensions. + Comprehension, + /// Effectively `None` in `Option` #[default] Default, @@ -116,6 +119,13 @@ impl FormatNodeRule for FormatExprTuple { parenthesized("(", &ExprSequence::new(item), ")").fmt(f) } _ => match self.parentheses { + TupleParentheses::Comprehension => { + let separator = + format_with(|f| group(&format_args![text(","), space()]).fmt(f)); + f.join_with(separator) + .entries(elts.iter().formatted()) + .finish() + } TupleParentheses::Subscript => group(&ExprSequence::new(item)).fmt(f), _ => parenthesize_if_expands(&ExprSequence::new(item)).fmt(f), }, diff --git a/crates/ruff_python_formatter/src/other/comprehension.rs b/crates/ruff_python_formatter/src/other/comprehension.rs index 0503f2d93b..85de94885e 100644 --- a/crates/ruff_python_formatter/src/other/comprehension.rs +++ b/crates/ruff_python_formatter/src/other/comprehension.rs @@ -1,4 +1,5 @@ use crate::comments::{leading_comments, trailing_comments}; +use crate::expression::expr_tuple::TupleParentheses; use crate::prelude::*; use crate::AsFormat; use crate::{FormatNodeRule, PyFormatter}; @@ -58,7 +59,7 @@ impl FormatNodeRule for FormatComprehension { trailing_comments(before_target_comments), group(&format_args!( Spacer(target), - target.format(), + ExprTupleWithoutParentheses(target), in_spacer, leading_comments(before_in_comments), text("in"), @@ -104,3 +105,17 @@ impl FormatNodeRule for FormatComprehension { Ok(()) } } + +struct ExprTupleWithoutParentheses<'a>(&'a Expr); + +impl Format> for ExprTupleWithoutParentheses<'_> { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + match self.0 { + Expr::Tuple(expr_tuple) => expr_tuple + .format() + .with_options(TupleParentheses::Comprehension) + .fmt(f), + other => other.format().fmt(f), + } + } +} diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap index 541a0aff4f..f548f665b3 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap @@ -314,19 +314,7 @@ last_call() () (1,) (1, 2) -@@ -101,7 +108,10 @@ - {a: b * -2 for a, b in dictionary.items()} - { - k: v -- for k, v in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension -+ for ( -+ k, -+ v, -+ ) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension - } - Python3 > Python2 > COBOL - Life is Life -@@ -115,7 +125,7 @@ +@@ -115,7 +122,7 @@ arg, another, kwarg="hey", @@ -335,7 +323,7 @@ last_call() ) # note: no trailing comma pre-3.6 call(*gidgets[:2]) call(a, *gidgets[:2]) -@@ -152,13 +162,13 @@ +@@ -152,13 +159,13 @@ slice[0:1] slice[0:1:2] slice[:] @@ -352,7 +340,7 @@ last_call() numpy[0, :] numpy[:, i] numpy[0, :2] -@@ -172,7 +182,7 @@ +@@ -172,7 +179,7 @@ numpy[1 : c + 1, c] numpy[-(c + 1) :, d] numpy[:, l[-2]] @@ -361,10 +349,11 @@ last_call() numpy[np.newaxis, :] (str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None) {"2.7": dead, "3.7": long_live or die_hard} -@@ -208,24 +218,14 @@ +@@ -207,25 +214,15 @@ + ) what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set( vars_to_remove - ) +-) -result = ( - session.query(models.Customer.id) - .filter( @@ -372,7 +361,7 @@ last_call() - ) - .order_by(models.Customer.id.asc()) - .all() --) + ) -result = ( - session.query(models.Customer.id) - .filter( @@ -394,7 +383,7 @@ last_call() Ø = set() authors.łukasz.say_thanks() mapping = { -@@ -237,10 +237,10 @@ +@@ -237,10 +234,10 @@ def gen(): @@ -409,7 +398,7 @@ last_call() async def f(): -@@ -328,13 +328,18 @@ +@@ -328,13 +325,18 @@ ): return True if ( @@ -431,7 +420,7 @@ last_call() ^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n ): return True -@@ -342,7 +347,8 @@ +@@ -342,7 +344,8 @@ ~aaaaaaaaaaaaaaaa.a + aaaaaaaaaaaaaaaa.b - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e @@ -556,10 +545,7 @@ str or None if (1 if True else 2) else str or bytes or None {a: b * -2 for a, b in dictionary.items()} { k: v - for ( - k, - v, - ) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension + for k, v in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension } Python3 > Python2 > COBOL Life is Life diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__dict_comp.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__dict_comp.py.snap index 6a96be6a10..1887490574 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__dict_comp.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__dict_comp.py.snap @@ -49,7 +49,38 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression if gggggggggggggggggggggggggggggggggggggggggggg } -``` + +# Useful for tuple target (see https://github.com/astral-sh/ruff/issues/5779#issuecomment-1637614763) +{k: v for a, a, a, a, a, a, a, a, a, a, [a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a] in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension} +{k: v for a, a, a, a, a, a, a, a, a, a, (a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension} + +# Leading +{ # Leading + k: v # Trailing + for a, a, a, a, a, a, a, a, a, a, ( # Trailing + a, + a, + a, + a, + a, + a, + a, + a, + a, # Trailing + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, # Trailing + ) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension # Trailing +} # Trailing +# Trailing``` ## Output ```py @@ -95,16 +126,97 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression dddddddddddddddddd, eeeeeeeeeeeeeeeeeee, ]: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - for ( - ccccccccccccccccccccccccccccccccccccccc, - ddddddddddddddddddd, - [eeeeeeeeeeeeeeeeeeeeee, fffffffffffffffffffffffff], - ) in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd + for ccccccccccccccccccccccccccccccccccccccc, ddddddddddddddddddd, [ + eeeeeeeeeeeeeeeeeeeeee, + fffffffffffffffffffffffff, + ] in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd if fffffffffffffffffffffffffffffffffffffffffff < gggggggggggggggggggggggggggggggggggggggggggggg < hhhhhhhhhhhhhhhhhhhhhhhhhh if gggggggggggggggggggggggggggggggggggggggggggg } + +# Useful for tuple target (see https://github.com/astral-sh/ruff/issues/5779#issuecomment-1637614763) +{ + k: v + for a, a, a, a, a, a, a, a, a, a, [ + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + ] in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension +} +{ + k: v + for a, a, a, a, a, a, a, a, a, a, ( + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + ) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension +} + +# Leading +{ + # Leading + k: v # Trailing + for a, a, a, a, a, a, a, a, a, a, ( + # Trailing + a, + a, + a, + a, + a, + a, + a, + a, + a, # Trailing + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, + a, # Trailing + ) in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension # Trailing +} # Trailing +# Trailing ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap index ee8cb00842..374e4aa6e3 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap @@ -92,11 +92,10 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee] - for ( - ccccccccccccccccccccccccccccccccccccccc, - ddddddddddddddddddd, - [eeeeeeeeeeeeeeeeeeeeee, fffffffffffffffffffffffff], - ) in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd + for ccccccccccccccccccccccccccccccccccccccc, ddddddddddddddddddd, [ + eeeeeeeeeeeeeeeeeeeeee, + fffffffffffffffffffffffff, + ] in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd if fffffffffffffffffffffffffffffffffffffffffff < gggggggggggggggggggggggggggggggggggggggggggggg < hhhhhhhhhhhhhhhhhhhhhhhhhh diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__set_comp.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__set_comp.py.snap index 614bd3a7d4..256e2a8bc1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__set_comp.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__set_comp.py.snap @@ -92,14 +92,16 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee] - for ( - ccccccccccccccccccccccccccccccccccccccc, - ddddddddddddddddddd, - [eeeeeeeeeeeeeeeeeeeeee, fffffffffffffffffffffffff], - ) in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd + for ccccccccccccccccccccccccccccccccccccccc, ddddddddddddddddddd, [ + eeeeeeeeeeeeeeeeeeeeee, + fffffffffffffffffffffffff, + ] in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd if fffffffffffffffffffffffffffffffffffffffffff < gggggggggggggggggggggggggggggggggggggggggggggg < hhhhhhhhhhhhhhhhhhhhhhhhhh if gggggggggggggggggggggggggggggggggggggggggggg } ``` + + +