mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 05:25:17 +00:00
Format expr generator exp (#5804)
This commit is contained in:
parent
cda90d071c
commit
5d68ad9008
13 changed files with 224 additions and 271 deletions
27
crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/generator_exp.py
vendored
Normal file
27
crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/generator_exp.py
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
(a for b in c)
|
||||
|
||||
# parens around generator expression not required
|
||||
len(a for b in c)
|
||||
|
||||
# parens around generator expression required
|
||||
sum((a for b in c), start=0)
|
||||
|
||||
# black keeps these atm, but intends to remove them in the future:
|
||||
# https://github.com/psf/black/issues/2943
|
||||
f((1 for _ in a))
|
||||
|
||||
# make sure source parenthesis detection isn't fooled by these
|
||||
f((1) for _ in (a))
|
||||
|
||||
# combination of the two above
|
||||
f(((1) for _ in (a)))
|
||||
|
||||
|
||||
# black keeps these atm, but intends to remove them in the future:
|
||||
# https://github.com/psf/black/issues/2943
|
||||
len(
|
||||
( # leading
|
||||
a for b in c
|
||||
# trailing
|
||||
)
|
||||
)
|
|
@ -6,6 +6,7 @@ use ruff_python_ast::node::AnyNodeRef;
|
|||
use ruff_python_whitespace::{SimpleTokenizer, TokenKind};
|
||||
|
||||
use crate::comments::dangling_comments;
|
||||
use crate::expression::expr_generator_exp::GeneratorExpParentheses;
|
||||
use crate::expression::parentheses::{
|
||||
parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||
};
|
||||
|
@ -50,13 +51,23 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
|
|||
let mut joiner = f.join_comma_separated(item.end());
|
||||
match args.as_slice() {
|
||||
[argument] if keywords.is_empty() => {
|
||||
match argument {
|
||||
Expr::GeneratorExp(generator_exp) => joiner.entry(
|
||||
generator_exp,
|
||||
&generator_exp
|
||||
.format()
|
||||
.with_options(GeneratorExpParentheses::StripIfOnlyFunctionArg),
|
||||
),
|
||||
other => {
|
||||
let parentheses =
|
||||
if is_single_argument_parenthesized(argument, item.end(), source) {
|
||||
Parentheses::Always
|
||||
} else {
|
||||
Parentheses::Never
|
||||
};
|
||||
joiner.entry(argument, &argument.format().with_options(parentheses));
|
||||
joiner.entry(other, &other.format().with_options(parentheses))
|
||||
}
|
||||
};
|
||||
}
|
||||
arguments => {
|
||||
joiner
|
||||
|
|
|
@ -1,22 +1,77 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::parenthesized;
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use crate::prelude::*;
|
||||
use crate::AsFormat;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{format_args, write, Buffer, FormatResult, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprGeneratorExp;
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Default)]
|
||||
pub enum GeneratorExpParentheses {
|
||||
#[default]
|
||||
Default,
|
||||
|
||||
// skip parens if the generator exp is the only argument to a function, e.g.
|
||||
// ```python
|
||||
// all(x for y in z)`
|
||||
// ```
|
||||
StripIfOnlyFunctionArg,
|
||||
}
|
||||
|
||||
impl FormatRuleWithOptions<ExprGeneratorExp, PyFormatContext<'_>> for FormatExprGeneratorExp {
|
||||
type Options = GeneratorExpParentheses;
|
||||
|
||||
fn with_options(mut self, options: Self::Options) -> Self {
|
||||
self.parentheses = options;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatExprGeneratorExp;
|
||||
pub struct FormatExprGeneratorExp {
|
||||
parentheses: GeneratorExpParentheses,
|
||||
}
|
||||
|
||||
impl FormatNodeRule<ExprGeneratorExp> for FormatExprGeneratorExp {
|
||||
fn fmt_fields(&self, _item: &ExprGeneratorExp, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
fn fmt_fields(&self, item: &ExprGeneratorExp, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let ExprGeneratorExp {
|
||||
range: _,
|
||||
elt,
|
||||
generators,
|
||||
} = item;
|
||||
|
||||
let joined = format_with(|f| {
|
||||
f.join_with(soft_line_break_or_space())
|
||||
.entries(generators.iter().formatted())
|
||||
.finish()
|
||||
});
|
||||
|
||||
if self.parentheses == GeneratorExpParentheses::StripIfOnlyFunctionArg {
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])"
|
||||
[
|
||||
group(&elt.format()),
|
||||
soft_line_break_or_space(),
|
||||
group(&joined),
|
||||
]
|
||||
)
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
[parenthesized(
|
||||
"(",
|
||||
&format_args!(
|
||||
group(&elt.format()),
|
||||
soft_line_break_or_space(),
|
||||
group(&joined)
|
||||
),
|
||||
")"
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NeedsParentheses for ExprGeneratorExp {
|
||||
|
|
|
@ -121,35 +121,21 @@ def something():
|
|||
):
|
||||
pass
|
||||
|
||||
@@ -59,26 +53,14 @@
|
||||
else "this one is a little shorter"
|
||||
@@ -60,11 +54,9 @@
|
||||
)
|
||||
|
||||
-generator_expression = (
|
||||
generator_expression = (
|
||||
- (
|
||||
- some_long_value_name_foo_bar_baz
|
||||
- if some_boolean_variable
|
||||
- else some_fallback_value_foo_bar_baz
|
||||
- )
|
||||
- for some_boolean_variable in some_iterable
|
||||
-)
|
||||
+generator_expression = (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
def limit_offset_sql(self, low_mark, high_mark):
|
||||
"""Return LIMIT/OFFSET SQL clause."""
|
||||
limit, offset = self._get_limit_offset_params(low_mark, high_mark)
|
||||
return " ".join(
|
||||
- sql
|
||||
- for sql in (
|
||||
- "LIMIT %d" % limit if limit else None,
|
||||
- ("OFFSET %d" % offset) if offset else None,
|
||||
- )
|
||||
- if sql
|
||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
+ some_long_value_name_foo_bar_baz
|
||||
+ if some_boolean_variable
|
||||
+ else some_fallback_value_foo_bar_baz
|
||||
for some_boolean_variable in some_iterable
|
||||
)
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
@ -210,14 +196,24 @@ nested = (
|
|||
else "this one is a little shorter"
|
||||
)
|
||||
|
||||
generator_expression = (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
generator_expression = (
|
||||
some_long_value_name_foo_bar_baz
|
||||
if some_boolean_variable
|
||||
else some_fallback_value_foo_bar_baz
|
||||
for some_boolean_variable in some_iterable
|
||||
)
|
||||
|
||||
|
||||
def limit_offset_sql(self, low_mark, high_mark):
|
||||
"""Return LIMIT/OFFSET SQL clause."""
|
||||
limit, offset = self._get_limit_offset_params(low_mark, high_mark)
|
||||
return " ".join(
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
sql
|
||||
for sql in (
|
||||
"LIMIT %d" % limit if limit else None,
|
||||
("OFFSET %d" % offset) if offset else None,
|
||||
)
|
||||
if sql
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ with match() as match:
|
|||
|
||||
|
||||
def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
|
||||
@@ -23,13 +23,11 @@
|
||||
@@ -23,11 +23,7 @@
|
||||
pygram.python_grammar,
|
||||
]
|
||||
|
||||
|
@ -145,14 +145,9 @@ with match() as match:
|
|||
- pass
|
||||
+ NOT_YET_IMPLEMENTED_StmtMatch
|
||||
|
||||
- if all(version.is_python2() for version in target_versions):
|
||||
+ if all(
|
||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
+ ):
|
||||
if all(version.is_python2() for version in target_versions):
|
||||
# Python 2-only code, so try Python 2 grammars.
|
||||
return [
|
||||
# Python 2.7 with future print_function import
|
||||
@@ -41,13 +39,11 @@
|
||||
@@ -41,13 +37,11 @@
|
||||
re.match()
|
||||
match = a
|
||||
with match() as match:
|
||||
|
@ -168,7 +163,7 @@ with match() as match:
|
|||
self.assertIs(x, False)
|
||||
self.assertEqual(y, 0)
|
||||
self.assertIs(z, x)
|
||||
@@ -72,16 +68,12 @@
|
||||
@@ -72,16 +66,12 @@
|
||||
def test_patma_155(self):
|
||||
x = 0
|
||||
y = None
|
||||
|
@ -187,7 +182,7 @@ with match() as match:
|
|||
|
||||
# At least one of the above branches must have been taken, because every Python
|
||||
# version has exactly one of the two 'ASYNC_*' flags
|
||||
@@ -99,9 +91,9 @@
|
||||
@@ -99,9 +89,9 @@
|
||||
re.match()
|
||||
match = a
|
||||
with match() as match:
|
||||
|
@ -231,9 +226,7 @@ def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
|
|||
|
||||
NOT_YET_IMPLEMENTED_StmtMatch
|
||||
|
||||
if all(
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
):
|
||||
if all(version.is_python2() for version in target_versions):
|
||||
# Python 2-only code, so try Python 2 grammars.
|
||||
return [
|
||||
# Python 2.7 with future print_function import
|
||||
|
|
|
@ -27,7 +27,7 @@ f(x, (a := b + c for c in range(10)), y=z, **q)
|
|||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -1,15 +1,20 @@
|
||||
@@ -1,7 +1,7 @@
|
||||
# Unparenthesized walruses are now allowed in indices since Python 3.10.
|
||||
-x[a:=0]
|
||||
-x[a:=0, b:=1]
|
||||
|
@ -37,25 +37,7 @@ f(x, (a := b + c for c in range(10)), y=z, **q)
|
|||
+x[5, b := 0]
|
||||
|
||||
# Walruses are allowed inside generator expressions on function calls since 3.10.
|
||||
-if any(match := pattern_error.match(s) for s in buffer):
|
||||
+if any((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])):
|
||||
if match.group(2) == data_not_available:
|
||||
# Error OK to ignore.
|
||||
pass
|
||||
|
||||
-f(a := b + c for c in range(10))
|
||||
-f((a := b + c for c in range(10)), x)
|
||||
-f(y=(a := b + c for c in range(10)))
|
||||
-f(x, (a := b + c for c in range(10)), y=z, **q)
|
||||
+f((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []))
|
||||
+f((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []), x)
|
||||
+f(y=(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []))
|
||||
+f(
|
||||
+ x,
|
||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []),
|
||||
+ y=z,
|
||||
+ **q,
|
||||
+)
|
||||
if any(match := pattern_error.match(s) for s in buffer):
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
@ -67,20 +49,15 @@ x[a := 0, b := 1]
|
|||
x[5, b := 0]
|
||||
|
||||
# Walruses are allowed inside generator expressions on function calls since 3.10.
|
||||
if any((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])):
|
||||
if any(match := pattern_error.match(s) for s in buffer):
|
||||
if match.group(2) == data_not_available:
|
||||
# Error OK to ignore.
|
||||
pass
|
||||
|
||||
f((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []))
|
||||
f((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []), x)
|
||||
f(y=(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []))
|
||||
f(
|
||||
x,
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []),
|
||||
y=z,
|
||||
**q,
|
||||
)
|
||||
f(a := b + c for c in range(10))
|
||||
f((a := b + c for c in range(10)), x)
|
||||
f(y=(a := b + c for c in range(10)))
|
||||
f(x, (a := b + c for c in range(10)), y=z, **q)
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py
|
||||
---
|
||||
## Input
|
||||
|
||||
```py
|
||||
#!/usr/bin/env python3.7
|
||||
|
||||
|
||||
def f():
|
||||
return (i * 2 async for i in arange(42))
|
||||
|
||||
|
||||
def g():
|
||||
return (
|
||||
something_long * something_long
|
||||
async for something_long in async_generator(with_an_argument)
|
||||
)
|
||||
|
||||
|
||||
async def func():
|
||||
if test:
|
||||
out_batched = [
|
||||
i
|
||||
async for i in aitertools._async_map(
|
||||
self.async_inc, arange(8), batch_size=3
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def awaited_generator_value(n):
|
||||
return (await awaitable for awaitable in awaitable_list)
|
||||
|
||||
|
||||
def make_arange(n):
|
||||
return (i * 2 for i in range(n) if await wrap(i))
|
||||
```
|
||||
|
||||
## Black Differences
|
||||
|
||||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -2,14 +2,11 @@
|
||||
|
||||
|
||||
def f():
|
||||
- return (i * 2 async for i in arange(42))
|
||||
+ return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
def g():
|
||||
- return (
|
||||
- something_long * something_long
|
||||
- async for something_long in async_generator(with_an_argument)
|
||||
- )
|
||||
+ return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
async def func():
|
||||
@@ -23,8 +20,8 @@
|
||||
|
||||
|
||||
def awaited_generator_value(n):
|
||||
- return (await awaitable for awaitable in awaitable_list)
|
||||
+ return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
def make_arange(n):
|
||||
- return (i * 2 for i in range(n) if await wrap(i))
|
||||
+ return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
||||
```py
|
||||
#!/usr/bin/env python3.7
|
||||
|
||||
|
||||
def f():
|
||||
return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
def g():
|
||||
return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
async def func():
|
||||
if test:
|
||||
out_batched = [
|
||||
i
|
||||
async for i in aitertools._async_map(
|
||||
self.async_inc, arange(8), batch_size=3
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def awaited_generator_value(n):
|
||||
return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
|
||||
|
||||
def make_arange(n):
|
||||
return (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
||||
```py
|
||||
#!/usr/bin/env python3.7
|
||||
|
||||
|
||||
def f():
|
||||
return (i * 2 async for i in arange(42))
|
||||
|
||||
|
||||
def g():
|
||||
return (
|
||||
something_long * something_long
|
||||
async for something_long in async_generator(with_an_argument)
|
||||
)
|
||||
|
||||
|
||||
async def func():
|
||||
if test:
|
||||
out_batched = [
|
||||
i
|
||||
async for i in aitertools._async_map(
|
||||
self.async_inc, arange(8), batch_size=3
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def awaited_generator_value(n):
|
||||
return (await awaitable for awaitable in awaitable_list)
|
||||
|
||||
|
||||
def make_arange(n):
|
||||
return (i * 2 for i in range(n) if await wrap(i))
|
||||
```
|
||||
|
||||
|
|
@ -83,12 +83,9 @@ while x := f(x):
|
|||
x = (y := 0)
|
||||
(z := (y := (x := 0)))
|
||||
(info := (name, phone, *rest))
|
||||
@@ -31,9 +31,9 @@
|
||||
len(lines := f.readlines())
|
||||
foo(x := 3, cat="vector")
|
||||
@@ -33,7 +33,7 @@
|
||||
foo(cat=(category := "vector"))
|
||||
-if any(len(longline := l) >= 100 for l in lines):
|
||||
+if any((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])):
|
||||
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)):
|
||||
|
@ -143,7 +140,7 @@ x = (y := 0)
|
|||
len(lines := f.readlines())
|
||||
foo(x := 3, cat="vector")
|
||||
foo(cat=(category := "vector"))
|
||||
if any((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])):
|
||||
if any(len(longline := l) >= 100 for l in lines):
|
||||
print(longline)
|
||||
if (env_base := os.environ.get("PYTHONUSERBASE", None)):
|
||||
return env_base
|
||||
|
|
|
@ -363,21 +363,6 @@ 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}
|
||||
@@ -181,10 +187,10 @@
|
||||
(SomeName)
|
||||
SomeName
|
||||
(Good, Bad, Ugly)
|
||||
-(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")))
|
||||
-(((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3))
|
||||
+(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
+(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
+(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
+(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
(*starred,)
|
||||
{
|
||||
"id": "1",
|
||||
@@ -208,24 +214,14 @@
|
||||
what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
|
||||
vars_to_remove
|
||||
|
@ -435,15 +420,6 @@ last_call()
|
|||
assert not Test, "Short message"
|
||||
assert this is ComplexTest and not requirements.fit_in_a_single_line(
|
||||
force=False
|
||||
@@ -259,7 +255,7 @@
|
||||
...
|
||||
for y in ():
|
||||
...
|
||||
-for z in (i for i in (1, 2, 3)):
|
||||
+for z in (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []):
|
||||
...
|
||||
for i in call():
|
||||
...
|
||||
@@ -328,13 +324,18 @@
|
||||
):
|
||||
return True
|
||||
|
@ -670,10 +646,10 @@ numpy[np.newaxis, :]
|
|||
(SomeName)
|
||||
SomeName
|
||||
(Good, Bad, Ugly)
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
(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")))
|
||||
(((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3))
|
||||
(*starred,)
|
||||
{
|
||||
"id": "1",
|
||||
|
@ -738,7 +714,7 @@ for (x,) in (1,), (2,), (3,):
|
|||
...
|
||||
for y in ():
|
||||
...
|
||||
for z in (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []):
|
||||
for z in (i for i in (1, 2, 3)):
|
||||
...
|
||||
for i in call():
|
||||
...
|
||||
|
|
|
@ -43,7 +43,7 @@ ham[lower + offset : upper + offset]
|
|||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -4,19 +4,21 @@
|
||||
@@ -4,19 +4,19 @@
|
||||
slice[d::d]
|
||||
slice[0]
|
||||
slice[-1]
|
||||
|
@ -63,16 +63,13 @@ ham[lower + offset : upper + offset]
|
|||
+slice[lambda NOT_YET_IMPLEMENTED_lambda: True :, None::]
|
||||
slice[1 or 2 : True and False]
|
||||
slice[not so_simple : 1 < val <= 10]
|
||||
-slice[(1 for i in range(42)) : x]
|
||||
slice[(1 for i in range(42)) : x]
|
||||
-slice[:: [i for i in range(42)]]
|
||||
+slice[
|
||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []) : x
|
||||
+]
|
||||
+slice[ :: [i for i in range(42)]]
|
||||
|
||||
|
||||
async def f():
|
||||
@@ -27,5 +29,5 @@
|
||||
@@ -27,5 +27,5 @@
|
||||
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
|
||||
ham[lower:upper], ham[lower:upper:], ham[lower::step]
|
||||
# ham[lower+offset : upper+offset]
|
||||
|
@ -101,9 +98,7 @@ slice[lambda NOT_YET_IMPLEMENTED_lambda: True : lambda NOT_YET_IMPLEMENTED_lambd
|
|||
slice[lambda NOT_YET_IMPLEMENTED_lambda: True :, None::]
|
||||
slice[1 or 2 : True and False]
|
||||
slice[not so_simple : 1 < val <= 10]
|
||||
slice[
|
||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []) : x
|
||||
]
|
||||
slice[(1 for i in range(42)) : x]
|
||||
slice[ :: [i for i in range(42)]]
|
||||
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ aaaaaaaaaaaaaa + [
|
|||
]
|
||||
(
|
||||
aaaaaaaaaaaaaa
|
||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
||||
+ (a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)
|
||||
)
|
||||
aaaaaaaaaaaaaa + {
|
||||
a
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/generator_exp.py
|
||||
---
|
||||
## Input
|
||||
```py
|
||||
(a for b in c)
|
||||
|
||||
# parens around generator expression not required
|
||||
len(a for b in c)
|
||||
|
||||
# parens around generator expression required
|
||||
sum((a for b in c), start=0)
|
||||
|
||||
# black keeps these atm, but intends to remove them in the future:
|
||||
# https://github.com/psf/black/issues/2943
|
||||
f((1 for _ in a))
|
||||
|
||||
# make sure source parenthesis detection isn't fooled by these
|
||||
f((1) for _ in (a))
|
||||
|
||||
# combination of the two above
|
||||
f(((1) for _ in (a)))
|
||||
|
||||
|
||||
# black keeps these atm, but intends to remove them in the future:
|
||||
# https://github.com/psf/black/issues/2943
|
||||
len(
|
||||
( # leading
|
||||
a for b in c
|
||||
# trailing
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Output
|
||||
```py
|
||||
(a for b in c)
|
||||
|
||||
# parens around generator expression not required
|
||||
len(a for b in c)
|
||||
|
||||
# parens around generator expression required
|
||||
sum((a for b in c), start=0)
|
||||
|
||||
# black keeps these atm, but intends to remove them in the future:
|
||||
# https://github.com/psf/black/issues/2943
|
||||
f(1 for _ in a)
|
||||
|
||||
# make sure source parenthesis detection isn't fooled by these
|
||||
f((1) for _ in (a))
|
||||
|
||||
# combination of the two above
|
||||
f((1) for _ in (a))
|
||||
|
||||
|
||||
# black keeps these atm, but intends to remove them in the future:
|
||||
# https://github.com/psf/black/issues/2943
|
||||
len(
|
||||
# leading
|
||||
a
|
||||
for b in c
|
||||
# trailing
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|||
|
||||
|
||||
# currently unparsable by black: https://github.com/psf/black/issues/3678
|
||||
with (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []):
|
||||
with (name_2 for name_0 in name_4):
|
||||
pass
|
||||
with (a, *b):
|
||||
pass
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue