Format binary expressions (#4862)

* Format Binary Expressions

* Extract NeedsParentheses trait
This commit is contained in:
Micha Reiser 2023-06-06 10:34:53 +02:00 committed by GitHub
parent 775326790e
commit 3f032cf09d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 1122 additions and 217 deletions

View file

@ -168,7 +168,7 @@ if True:
- 2,
- 3,
-]
+[1, 2, 3,]
+[1, 2, 3]
-division_result_tuple = (6 / 2,)
+division_result_tuple = (6/2,)
@ -250,7 +250,7 @@ for x in (1,):
for (x,) in (1,), (2,), (3,):
pass
[1, 2, 3,]
[1, 2, 3]
division_result_tuple = (6/2,)
print("foo %r", (foo.bar,))

View file

@ -109,7 +109,21 @@ async def wat():
```diff
--- Black
+++ Ruff
@@ -19,14 +19,9 @@
@@ -4,10 +4,12 @@
#
# Has many lines. Many, many lines.
# Many, many, many lines.
-"""Module docstring.
+(
+ """Module docstring.
Possibly also many, many lines.
"""
+)
import os.path
import sys
@@ -19,9 +21,6 @@
import fast
except ImportError:
import slow as fast
@ -117,16 +131,9 @@ async def wat():
-
-# Some comment before a function.
y = 1
-(
- # some strings
- y # type: ignore
-)
+# some strings
+y # type: ignore
def function(default=None):
@@ -93,4 +88,4 @@
(
# some strings
@@ -93,4 +92,4 @@
# Some closing comments.
# Maybe Vim or Emacs directives for formatting.
@ -144,10 +151,12 @@ async def wat():
#
# Has many lines. Many, many lines.
# Many, many, many lines.
"""Module docstring.
(
"""Module docstring.
Possibly also many, many lines.
"""
)
import os.path
import sys
@ -160,8 +169,10 @@ try:
except ImportError:
import slow as fast
y = 1
# some strings
y # type: ignore
(
# some strings
y # type: ignore
)
def function(default=None):

View file

@ -276,17 +276,7 @@ last_call()
Name
None
True
@@ -22,119 +23,83 @@
v1 << 2
1 >> v2
1 % finished
-1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
-((1 + v2) - (v3 * 4)) ^ (((5**v6) / 7) // 8)
+1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8
+((1 + v2) - (v3 * 4)) ^ (((5 ** v6) / 7) // 8)
not great
~great
+value
@@ -30,56 +31,39 @@
-1
~int and not v1 ^ 123 + v2 | True
(~int) and (not ((v1 ^ (123 + v2)) | True))
@ -312,14 +302,14 @@ last_call()
(str or None) if True else (str or bytes or None)
str or None if (1 if True else 2) else str or bytes or None
(str or None) if (1 if True else 2) else (str or bytes or None)
-(
(
- (super_long_variable_name or None)
- if (1 if super_long_test_name else 2)
- else (str or bytes or None)
-)
+ (super_long_variable_name or None) if (1 if super_long_test_name else 2) else (str or bytes or None)
)
-{"2.7": dead, "3.7": (long_live or die_hard)}
-{"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}}
+(super_long_variable_name or None) if (1 if super_long_test_name else 2) else (str or bytes or None)
+{'2.7': dead, '3.7': (long_live or die_hard)}
+{'2.7': dead, '3.7': (long_live or die_hard), **{'3.6': verygood}}
{**a, **b, **c}
@ -338,7 +328,7 @@ last_call()
- 2,
- 3,
-]
+[1, 2, 3,]
+[1, 2, 3]
[*a]
[*range(10)]
-[
@ -351,15 +341,14 @@ last_call()
- *a,
- 5,
-]
-[
- this_is_a_very_long_variable_which_will_force_a_delimiter_split,
- element,
- another,
- *more,
-]
+[*a, 4, 5,]
+[4, *a, 5,]
+[this_is_a_very_long_variable_which_will_force_a_delimiter_split, element, another, *more]
+[*a, 4, 5]
+[4, *a, 5]
[
this_is_a_very_long_variable_which_will_force_a_delimiter_split,
element,
@@ -87,54 +71,44 @@
*more,
]
{i for i in (1, 2, 3)}
-{(i**2) for i in (1, 2, 3)}
-{(i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c"))}
@ -417,18 +406,21 @@ last_call()
dict[str, int]
tuple[str, ...]
-tuple[str, int, float, dict[str, int]]
tuple[
-tuple[
- str,
- int,
- float,
- dict[str, int],
+(
+ tuple[
+ str, int, float, dict[str, int]
]
+)
+tuple[str, int, float, dict[str, int],]
very_long_variable_name_filters: t.List[
t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
]
@@ -144,9 +109,9 @@
@@ -144,9 +118,9 @@
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
@ -441,7 +433,7 @@ last_call()
slice[0]
slice[0:1]
slice[0:1:2]
@@ -174,57 +139,29 @@
@@ -174,57 +148,29 @@
numpy[:, ::-1]
numpy[np.newaxis, :]
(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None)
@ -450,9 +442,8 @@ last_call()
+{'2.7': dead, '3.7': long_live or die_hard}
+{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]
-(SomeName)
(SomeName)
SomeName
+SomeName
(Good, Bad, Ugly)
(i for i in (1, 2, 3))
-((i**2) for i in (1, 2, 3))
@ -511,7 +502,7 @@ last_call()
Ø = set()
authors.łukasz.say_thanks()
mapping = {
@@ -237,134 +174,86 @@
@@ -237,114 +183,80 @@
def gen():
yield from outside_of_generator
@ -655,30 +646,7 @@ last_call()
+ ~ aaaaaaaaaaaaaaaa.a + aaaaaaaaaaaaaaaa.b - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e | aaaaaaaaaaaaaaaa.f & aaaaaaaaaaaaaaaa.g % aaaaaaaaaaaaaaaa.h ^ aaaaaaaaaaaaaaaa.i << aaaaaaaaaaaaaaaa.k >> aaaaaaaaaaaaaaaa.l ** aaaaaaaaaaaaaaaa.m // aaaaaaaaaaaaaaaa.n
):
return True
-(
- aaaaaaaaaaaaaaaa
- + aaaaaaaaaaaaaaaa
- - aaaaaaaaaaaaaaaa
- * (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
- / (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
-)
+aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaa * (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa) / (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa
-(
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-)
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbb >> bbbb * bbbb
-(
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- ^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- ^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-)
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ^bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
last_call()
# standalone comment at ENDMARKER
(
```
## Ruff Output
@ -709,8 +677,8 @@ Name1 or Name2 and Name3 or Name4
v1 << 2
1 >> v2
1 % finished
1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8
((1 + v2) - (v3 * 4)) ^ (((5 ** v6) / 7) // 8)
1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
((1 + v2) - (v3 * 4)) ^ (((5**v6) / 7) // 8)
not great
~great
+value
@ -731,7 +699,9 @@ str or None if True else str or bytes or None
(str or None) if True else (str or bytes or None)
str or None if (1 if True else 2) else str or bytes or None
(str or None) if (1 if True else 2) else (str or bytes or None)
(super_long_variable_name or None) if (1 if super_long_test_name else 2) else (str or bytes or None)
(
(super_long_variable_name or None) if (1 if super_long_test_name else 2) else (str or bytes or None)
)
{'2.7': dead, '3.7': (long_live or die_hard)}
{'2.7': dead, '3.7': (long_live or die_hard), **{'3.6': verygood}}
{**a, **b, **c}
@ -743,12 +713,17 @@ str or None if (1 if True else 2) else str or bytes or None
(1, 2, 3)
[]
[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]
[1, 2, 3,]
[1, 2, 3]
[*a]
[*range(10)]
[*a, 4, 5,]
[4, *a, 5,]
[this_is_a_very_long_variable_which_will_force_a_delimiter_split, element, another, *more]
[*a, 4, 5]
[4, *a, 5]
[
this_is_a_very_long_variable_which_will_force_a_delimiter_split,
element,
another,
*more,
]
{i for i in (1, 2, 3)}
{(i ** 2) for i in (1, 2, 3)}
{(i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}
@ -782,9 +757,11 @@ call.me(maybe)
list[str]
dict[str, int]
tuple[str, ...]
tuple[
(
tuple[
str, int, float, dict[str, int]
]
)
tuple[str, int, float, dict[str, int],]
very_long_variable_name_filters: t.List[
t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
@ -828,7 +805,7 @@ numpy[np.newaxis, :]
{'2.7': dead, '3.7': long_live or die_hard}
{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]
SomeName
(SomeName)
SomeName
(Good, Bad, Ugly)
(i for i in (1, 2, 3))
@ -936,11 +913,25 @@ if (
~ aaaaaaaaaaaaaaaa.a + aaaaaaaaaaaaaaaa.b - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e | aaaaaaaaaaaaaaaa.f & aaaaaaaaaaaaaaaa.g % aaaaaaaaaaaaaaaa.h ^ aaaaaaaaaaaaaaaa.i << aaaaaaaaaaaaaaaa.k >> aaaaaaaaaaaaaaaa.l ** aaaaaaaaaaaaaaaa.m // aaaaaaaaaaaaaaaa.n
):
return True
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaa * (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa) / (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
(
aaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaa
- aaaaaaaaaaaaaaaa
* (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
/ (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
)
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
<< aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
bbbb >> bbbb * bbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ^bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
last_call()
# standalone comment at ENDMARKER
```

View file

@ -76,16 +76,51 @@ x[
```diff
--- Black
+++ Ruff
@@ -56,4 +56,8 @@
@@ -31,14 +31,17 @@
ham[lower + offset : upper + offset]
slice[::, ::]
-slice[
+(
+ slice[
# A
:
# B
:
# C
]
-slice[
+)
+(
+ slice[
# A
1:
# B
@@ -46,8 +49,10 @@
# C
3
]
+)
-slice[
+(
+ slice[
# A
1
+ 2 :
@@ -56,4 +61,11 @@
# C
4
]
-x[1:2:3] # A # B # C
+x[
+)
+(
+ x[
+ 1: # A
+ 2: # B
+ 3 # C
+]
+)
```
## Ruff Output
@ -124,14 +159,17 @@ ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
slice[::, ::]
slice[
(
slice[
# A
:
# B
:
# C
]
slice[
)
(
slice[
# A
1:
# B
@ -139,8 +177,10 @@ slice[
# C
3
]
)
slice[
(
slice[
# A
1
+ 2 :
@ -149,11 +189,14 @@ slice[
# C
4
]
x[
)
(
x[
1: # A
2: # B
3 # C
]
)
```
## Black Output

View file

@ -42,14 +42,13 @@ assert (
```diff
--- Black
+++ Ruff
@@ -1,58 +1,33 @@
importA
-(
- ()
- << 0
@@ -2,18 +2,13 @@
(
()
<< 0
- ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525
-) #
+() << 0 ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525 #
+ **101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert sort_by_dependency(
{
@ -65,12 +64,7 @@ assert (
}
) == ["2a", "2b", "2", "3a", "3b", "3", "1"]
importA
0
-0 ^ 0 #
+0^0 #
@@ -25,34 +20,18 @@
class A:
def foo(self):
for _ in range(10):
@ -120,7 +114,11 @@ assert (
```py
importA
() << 0 ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525 #
(
()
<< 0
**101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert sort_by_dependency(
{
@ -131,7 +129,7 @@ assert sort_by_dependency(
importA
0
0^0 #
0 ^ 0 #
class A:

View file

@ -0,0 +1,123 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
---
## Input
```py
(aaaaaaaa
+ # trailing operator comment
b # trailing right comment
)
(aaaaaaaa # trailing left comment
+ # trailing operator comment
# leading right comment
b
)
# Black breaks the right side first for the following expressions:
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(argument1, argument2, argument3)
aaaaaaaaaaaaaa + [bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eeeeeee]
aaaaaaaaaaaaaa + (bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eeeeeee)
aaaaaaaaaaaaaa + { key1:bbbbbbbbbbbbbbbbbbbbbb, key2: ccccccccccccccccccccc, key3: dddddddddddddddd, key4: eeeeeee }
aaaaaaaaaaaaaa + { bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eeeeeee }
aaaaaaaaaaaaaa + [a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ]
aaaaaaaaaaaaaa + (a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb )
aaaaaaaaaaaaaa + {a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb}
# Wraps it in parentheses if it needs to break both left and right
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + [
bbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccc,
dddddddddddddddd,
eee
] # comment
# But only for expressions that have a statement parent.
not (aaaaaaaaaaaaaa + {a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb})
[a + [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] in c ]
# leading comment
(
# comment
content + b
)
```
## Output
```py
(
aaaaaaaa
+ b # trailing operator comment # trailing right comment
)
(
aaaaaaaa # trailing left comment
+ # trailing operator comment
# leading right comment
b
)
# Black breaks the right side first for the following expressions:
(
aaaaaaaaaaaaaa
+ caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(argument1, argument2, argument3)
)
aaaaaaaaaaaaaa + [
bbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccc,
dddddddddddddddd,
eeeeeee,
]
(
aaaaaaaaaaaaaa
+ (bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eeeeeee)
)
(
aaaaaaaaaaaaaa
+ { key1:bbbbbbbbbbbbbbbbbbbbbb, key2: ccccccccccccccccccccc, key3: dddddddddddddddd, key4: eeeeeee }
)
(
aaaaaaaaaaaaaa
+ { bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eeeeeee }
)
(
aaaaaaaaaaaaaa
+ [a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ]
)
(
aaaaaaaaaaaaaa
+ (a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb )
)
(
aaaaaaaaaaaaaa
+ {a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb}
)
# Wraps it in parentheses if it needs to break both left and right
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ [bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eee]
) # comment
# But only for expressions that have a statement parent.
(
not (aaaaaaaaaaaaaa + {a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb})
)
[
a + [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] in c,
]
# leading comment
(
# comment
content
+ b
)
```