mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:10 +00:00
Remove parentheses around some walrus operators (#6173)
## Summary Closes https://github.com/astral-sh/ruff/issues/5781 ## Test Plan Added cases to `crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/named_expr.py` one-by-one and adjusted the condition as needed.
This commit is contained in:
parent
1d7ad30188
commit
5d9814d84d
5 changed files with 93 additions and 215 deletions
|
@ -11,3 +11,28 @@ if (
|
||||||
y0 = (y1 := f(x))
|
y0 = (y1 := f(x))
|
||||||
|
|
||||||
f(x:=y, z=True)
|
f(x:=y, z=True)
|
||||||
|
|
||||||
|
assert (x := 1)
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return (x := 1)
|
||||||
|
|
||||||
|
|
||||||
|
for x in (y := [1, 2, 3]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async for x in (y := [1, 2, 3]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
del (x := 1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (e := Exception):
|
||||||
|
if x := 1:
|
||||||
|
pass
|
||||||
|
|
||||||
|
(x := 1)
|
||||||
|
|
||||||
|
(x := 1) + (y := 2)
|
||||||
|
|
|
@ -32,11 +32,25 @@ impl FormatNodeRule<ExprNamedExpr> for FormatExprNamedExpr {
|
||||||
impl NeedsParentheses for ExprNamedExpr {
|
impl NeedsParentheses for ExprNamedExpr {
|
||||||
fn needs_parentheses(
|
fn needs_parentheses(
|
||||||
&self,
|
&self,
|
||||||
_parent: AnyNodeRef,
|
parent: AnyNodeRef,
|
||||||
_context: &PyFormatContext,
|
_context: &PyFormatContext,
|
||||||
) -> OptionalParentheses {
|
) -> OptionalParentheses {
|
||||||
// Unlike tuples, named expression parentheses are not part of the range even when
|
// Unlike tuples, named expression parentheses are not part of the range even when
|
||||||
// mandatory. See [PEP 572](https://peps.python.org/pep-0572/) for details.
|
// mandatory. See [PEP 572](https://peps.python.org/pep-0572/) for details.
|
||||||
|
if parent.is_stmt_ann_assign()
|
||||||
|
|| parent.is_stmt_assign()
|
||||||
|
|| parent.is_stmt_aug_assign()
|
||||||
|
|| parent.is_stmt_assert()
|
||||||
|
|| parent.is_stmt_return()
|
||||||
|
|| parent.is_except_handler_except_handler()
|
||||||
|
|| parent.is_with_item()
|
||||||
|
|| parent.is_stmt_delete()
|
||||||
|
|| parent.is_stmt_for()
|
||||||
|
|| parent.is_stmt_async_for()
|
||||||
|
{
|
||||||
OptionalParentheses::Always
|
OptionalParentheses::Always
|
||||||
|
} else {
|
||||||
|
OptionalParentheses::Never
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,196 +0,0 @@
|
||||||
---
|
|
||||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
|
||||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572.py
|
|
||||||
---
|
|
||||||
## Input
|
|
||||||
|
|
||||||
```py
|
|
||||||
(a := 1)
|
|
||||||
(a := a)
|
|
||||||
if (match := pattern.search(data)) is None:
|
|
||||||
pass
|
|
||||||
if match := pattern.search(data):
|
|
||||||
pass
|
|
||||||
[y := f(x), y**2, y**3]
|
|
||||||
filtered_data = [y for x in data if (y := f(x)) is None]
|
|
||||||
(y := f(x))
|
|
||||||
y0 = (y1 := f(x))
|
|
||||||
foo(x=(y := f(x)))
|
|
||||||
|
|
||||||
|
|
||||||
def foo(answer=(p := 42)):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def foo(answer: (p := 42) = 5):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
lambda: (x := 1)
|
|
||||||
(x := lambda: 1)
|
|
||||||
(x := lambda: (y := 1))
|
|
||||||
lambda line: (m := re.match(pattern, line)) and m.group(1)
|
|
||||||
x = (y := 0)
|
|
||||||
(z := (y := (x := 0)))
|
|
||||||
(info := (name, phone, *rest))
|
|
||||||
(x := 1, 2)
|
|
||||||
(total := total + tax)
|
|
||||||
len(lines := f.readlines())
|
|
||||||
foo(x := 3, cat="vector")
|
|
||||||
foo(cat=(category := "vector"))
|
|
||||||
if any(len(longline := l) >= 100 for l in lines):
|
|
||||||
print(longline)
|
|
||||||
if env_base := os.environ.get("PYTHONUSERBASE", None):
|
|
||||||
return env_base
|
|
||||||
if self._is_special and (ans := self._check_nans(context=context)):
|
|
||||||
return ans
|
|
||||||
foo(b := 2, a=1)
|
|
||||||
foo((b := 2), a=1)
|
|
||||||
foo(c=(b := 2), a=1)
|
|
||||||
|
|
||||||
while x := f(x):
|
|
||||||
pass
|
|
||||||
while x := f(x):
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
## Black Differences
|
|
||||||
|
|
||||||
```diff
|
|
||||||
--- Black
|
|
||||||
+++ Ruff
|
|
||||||
@@ -2,7 +2,7 @@
|
|
||||||
(a := a)
|
|
||||||
if (match := pattern.search(data)) is None:
|
|
||||||
pass
|
|
||||||
-if match := pattern.search(data):
|
|
||||||
+if (match := pattern.search(data)):
|
|
||||||
pass
|
|
||||||
[y := f(x), y**2, y**3]
|
|
||||||
filtered_data = [y for x in data if (y := f(x)) is None]
|
|
||||||
@@ -33,7 +33,7 @@
|
|
||||||
foo(cat=(category := "vector"))
|
|
||||||
if any(len(longline := l) >= 100 for l in lines):
|
|
||||||
print(longline)
|
|
||||||
-if env_base := os.environ.get("PYTHONUSERBASE", None):
|
|
||||||
+if (env_base := os.environ.get("PYTHONUSERBASE", None)):
|
|
||||||
return env_base
|
|
||||||
if self._is_special and (ans := self._check_nans(context=context)):
|
|
||||||
return ans
|
|
||||||
@@ -41,7 +41,7 @@
|
|
||||||
foo((b := 2), a=1)
|
|
||||||
foo(c=(b := 2), a=1)
|
|
||||||
|
|
||||||
-while x := f(x):
|
|
||||||
+while (x := f(x)):
|
|
||||||
pass
|
|
||||||
-while x := f(x):
|
|
||||||
+while (x := f(x)):
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ruff Output
|
|
||||||
|
|
||||||
```py
|
|
||||||
(a := 1)
|
|
||||||
(a := a)
|
|
||||||
if (match := pattern.search(data)) is None:
|
|
||||||
pass
|
|
||||||
if (match := pattern.search(data)):
|
|
||||||
pass
|
|
||||||
[y := f(x), y**2, y**3]
|
|
||||||
filtered_data = [y for x in data if (y := f(x)) is None]
|
|
||||||
(y := f(x))
|
|
||||||
y0 = (y1 := f(x))
|
|
||||||
foo(x=(y := f(x)))
|
|
||||||
|
|
||||||
|
|
||||||
def foo(answer=(p := 42)):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def foo(answer: (p := 42) = 5):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
lambda: (x := 1)
|
|
||||||
(x := lambda: 1)
|
|
||||||
(x := lambda: (y := 1))
|
|
||||||
lambda line: (m := re.match(pattern, line)) and m.group(1)
|
|
||||||
x = (y := 0)
|
|
||||||
(z := (y := (x := 0)))
|
|
||||||
(info := (name, phone, *rest))
|
|
||||||
(x := 1, 2)
|
|
||||||
(total := total + tax)
|
|
||||||
len(lines := f.readlines())
|
|
||||||
foo(x := 3, cat="vector")
|
|
||||||
foo(cat=(category := "vector"))
|
|
||||||
if any(len(longline := l) >= 100 for l in lines):
|
|
||||||
print(longline)
|
|
||||||
if (env_base := os.environ.get("PYTHONUSERBASE", None)):
|
|
||||||
return env_base
|
|
||||||
if self._is_special and (ans := self._check_nans(context=context)):
|
|
||||||
return ans
|
|
||||||
foo(b := 2, a=1)
|
|
||||||
foo((b := 2), a=1)
|
|
||||||
foo(c=(b := 2), a=1)
|
|
||||||
|
|
||||||
while (x := f(x)):
|
|
||||||
pass
|
|
||||||
while (x := f(x)):
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
## Black Output
|
|
||||||
|
|
||||||
```py
|
|
||||||
(a := 1)
|
|
||||||
(a := a)
|
|
||||||
if (match := pattern.search(data)) is None:
|
|
||||||
pass
|
|
||||||
if match := pattern.search(data):
|
|
||||||
pass
|
|
||||||
[y := f(x), y**2, y**3]
|
|
||||||
filtered_data = [y for x in data if (y := f(x)) is None]
|
|
||||||
(y := f(x))
|
|
||||||
y0 = (y1 := f(x))
|
|
||||||
foo(x=(y := f(x)))
|
|
||||||
|
|
||||||
|
|
||||||
def foo(answer=(p := 42)):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def foo(answer: (p := 42) = 5):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
lambda: (x := 1)
|
|
||||||
(x := lambda: 1)
|
|
||||||
(x := lambda: (y := 1))
|
|
||||||
lambda line: (m := re.match(pattern, line)) and m.group(1)
|
|
||||||
x = (y := 0)
|
|
||||||
(z := (y := (x := 0)))
|
|
||||||
(info := (name, phone, *rest))
|
|
||||||
(x := 1, 2)
|
|
||||||
(total := total + tax)
|
|
||||||
len(lines := f.readlines())
|
|
||||||
foo(x := 3, cat="vector")
|
|
||||||
foo(cat=(category := "vector"))
|
|
||||||
if any(len(longline := l) >= 100 for l in lines):
|
|
||||||
print(longline)
|
|
||||||
if env_base := os.environ.get("PYTHONUSERBASE", None):
|
|
||||||
return env_base
|
|
||||||
if self._is_special and (ans := self._check_nans(context=context)):
|
|
||||||
return ans
|
|
||||||
foo(b := 2, a=1)
|
|
||||||
foo((b := 2), a=1)
|
|
||||||
foo(c=(b := 2), a=1)
|
|
||||||
|
|
||||||
while x := f(x):
|
|
||||||
pass
|
|
||||||
while x := f(x):
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,6 @@ def f():
|
||||||
@relaxed_decorator[0]
|
@relaxed_decorator[0]
|
||||||
def f():
|
def f():
|
||||||
...
|
...
|
||||||
@@ -13,8 +12,10 @@
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
-@extremely_long_variable_name_that_doesnt_fit := complex.expression(
|
|
||||||
- with_long="arguments_value_that_wont_fit_at_the_end_of_the_line"
|
|
||||||
+@(
|
|
||||||
+ extremely_long_variable_name_that_doesnt_fit := complex.expression(
|
|
||||||
+ with_long="arguments_value_that_wont_fit_at_the_end_of_the_line"
|
|
||||||
+ )
|
|
||||||
)
|
|
||||||
def f():
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ruff Output
|
## Ruff Output
|
||||||
|
@ -64,11 +51,9 @@ def f():
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@(
|
@extremely_long_variable_name_that_doesnt_fit := complex.expression(
|
||||||
extremely_long_variable_name_that_doesnt_fit := complex.expression(
|
|
||||||
with_long="arguments_value_that_wont_fit_at_the_end_of_the_line"
|
with_long="arguments_value_that_wont_fit_at_the_end_of_the_line"
|
||||||
)
|
)
|
||||||
)
|
|
||||||
def f():
|
def f():
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
|
@ -17,6 +17,31 @@ if (
|
||||||
y0 = (y1 := f(x))
|
y0 = (y1 := f(x))
|
||||||
|
|
||||||
f(x:=y, z=True)
|
f(x:=y, z=True)
|
||||||
|
|
||||||
|
assert (x := 1)
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return (x := 1)
|
||||||
|
|
||||||
|
|
||||||
|
for x in (y := [1, 2, 3]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async for x in (y := [1, 2, 3]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
del (x := 1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (e := Exception):
|
||||||
|
if x := 1:
|
||||||
|
pass
|
||||||
|
|
||||||
|
(x := 1)
|
||||||
|
|
||||||
|
(x := 1) + (y := 2)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
@ -32,6 +57,31 @@ if (
|
||||||
y0 = (y1 := f(x))
|
y0 = (y1 := f(x))
|
||||||
|
|
||||||
f(x := y, z=True)
|
f(x := y, z=True)
|
||||||
|
|
||||||
|
assert (x := 1)
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return (x := 1)
|
||||||
|
|
||||||
|
|
||||||
|
for x in (y := [1, 2, 3]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async for x in (y := [1, 2, 3]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
del (x := 1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except (e := Exception):
|
||||||
|
if x := 1:
|
||||||
|
pass
|
||||||
|
|
||||||
|
(x := 1)
|
||||||
|
|
||||||
|
(x := 1) + (y := 2)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue