mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 13:05:06 +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 ruff_python_whitespace::{SimpleTokenizer, TokenKind};
|
||||||
|
|
||||||
use crate::comments::dangling_comments;
|
use crate::comments::dangling_comments;
|
||||||
|
use crate::expression::expr_generator_exp::GeneratorExpParentheses;
|
||||||
use crate::expression::parentheses::{
|
use crate::expression::parentheses::{
|
||||||
parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
|
parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||||
};
|
};
|
||||||
|
@ -50,13 +51,23 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
|
||||||
let mut joiner = f.join_comma_separated(item.end());
|
let mut joiner = f.join_comma_separated(item.end());
|
||||||
match args.as_slice() {
|
match args.as_slice() {
|
||||||
[argument] if keywords.is_empty() => {
|
[argument] if keywords.is_empty() => {
|
||||||
let parentheses =
|
match argument {
|
||||||
if is_single_argument_parenthesized(argument, item.end(), source) {
|
Expr::GeneratorExp(generator_exp) => joiner.entry(
|
||||||
Parentheses::Always
|
generator_exp,
|
||||||
} else {
|
&generator_exp
|
||||||
Parentheses::Never
|
.format()
|
||||||
};
|
.with_options(GeneratorExpParentheses::StripIfOnlyFunctionArg),
|
||||||
joiner.entry(argument, &argument.format().with_options(parentheses));
|
),
|
||||||
|
other => {
|
||||||
|
let parentheses =
|
||||||
|
if is_single_argument_parenthesized(argument, item.end(), source) {
|
||||||
|
Parentheses::Always
|
||||||
|
} else {
|
||||||
|
Parentheses::Never
|
||||||
|
};
|
||||||
|
joiner.entry(other, &other.format().with_options(parentheses))
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
arguments => {
|
arguments => {
|
||||||
joiner
|
joiner
|
||||||
|
|
|
@ -1,21 +1,76 @@
|
||||||
use crate::context::PyFormatContext;
|
use crate::context::PyFormatContext;
|
||||||
|
use crate::expression::parentheses::parenthesized;
|
||||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
use crate::prelude::*;
|
||||||
use ruff_formatter::{write, Buffer, FormatResult};
|
use crate::AsFormat;
|
||||||
|
use crate::{FormatNodeRule, PyFormatter};
|
||||||
|
use ruff_formatter::{format_args, write, Buffer, FormatResult, FormatRuleWithOptions};
|
||||||
use ruff_python_ast::node::AnyNodeRef;
|
use ruff_python_ast::node::AnyNodeRef;
|
||||||
use rustpython_parser::ast::ExprGeneratorExp;
|
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)]
|
#[derive(Default)]
|
||||||
pub struct FormatExprGeneratorExp;
|
pub struct FormatExprGeneratorExp {
|
||||||
|
parentheses: GeneratorExpParentheses,
|
||||||
|
}
|
||||||
|
|
||||||
impl FormatNodeRule<ExprGeneratorExp> for FormatExprGeneratorExp {
|
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<()> {
|
||||||
write!(
|
let ExprGeneratorExp {
|
||||||
f,
|
range: _,
|
||||||
[not_yet_implemented_custom_text(
|
elt,
|
||||||
"(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])"
|
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,
|
||||||
|
[
|
||||||
|
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)
|
||||||
|
),
|
||||||
|
")"
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,34 +121,20 @@ def something():
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -59,26 +53,14 @@
|
@@ -60,11 +54,9 @@
|
||||||
else "this one is a little shorter"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
-generator_expression = (
|
generator_expression = (
|
||||||
- (
|
- (
|
||||||
- some_long_value_name_foo_bar_baz
|
- some_long_value_name_foo_bar_baz
|
||||||
- if some_boolean_variable
|
- if some_boolean_variable
|
||||||
- else some_fallback_value_foo_bar_baz
|
- else some_fallback_value_foo_bar_baz
|
||||||
- )
|
- )
|
||||||
- for some_boolean_variable in some_iterable
|
+ some_long_value_name_foo_bar_baz
|
||||||
-)
|
+ if some_boolean_variable
|
||||||
+generator_expression = (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
+ 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(
|
|
||||||
- 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 [])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -210,14 +196,24 @@ nested = (
|
||||||
else "this one is a little shorter"
|
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):
|
def limit_offset_sql(self, low_mark, high_mark):
|
||||||
"""Return LIMIT/OFFSET SQL clause."""
|
"""Return LIMIT/OFFSET SQL clause."""
|
||||||
limit, offset = self._get_limit_offset_params(low_mark, high_mark)
|
limit, offset = self._get_limit_offset_params(low_mark, high_mark)
|
||||||
return " ".join(
|
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]:
|
def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
|
||||||
@@ -23,13 +23,11 @@
|
@@ -23,11 +23,7 @@
|
||||||
pygram.python_grammar,
|
pygram.python_grammar,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -145,14 +145,9 @@ with match() as match:
|
||||||
- pass
|
- pass
|
||||||
+ NOT_YET_IMPLEMENTED_StmtMatch
|
+ NOT_YET_IMPLEMENTED_StmtMatch
|
||||||
|
|
||||||
- if all(version.is_python2() for version in target_versions):
|
if all(version.is_python2() for version in target_versions):
|
||||||
+ if all(
|
|
||||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
|
||||||
+ ):
|
|
||||||
# Python 2-only code, so try Python 2 grammars.
|
# Python 2-only code, so try Python 2 grammars.
|
||||||
return [
|
@@ -41,13 +37,11 @@
|
||||||
# Python 2.7 with future print_function import
|
|
||||||
@@ -41,13 +39,11 @@
|
|
||||||
re.match()
|
re.match()
|
||||||
match = a
|
match = a
|
||||||
with match() as match:
|
with match() as match:
|
||||||
|
@ -168,7 +163,7 @@ with match() as match:
|
||||||
self.assertIs(x, False)
|
self.assertIs(x, False)
|
||||||
self.assertEqual(y, 0)
|
self.assertEqual(y, 0)
|
||||||
self.assertIs(z, x)
|
self.assertIs(z, x)
|
||||||
@@ -72,16 +68,12 @@
|
@@ -72,16 +66,12 @@
|
||||||
def test_patma_155(self):
|
def test_patma_155(self):
|
||||||
x = 0
|
x = 0
|
||||||
y = None
|
y = None
|
||||||
|
@ -187,7 +182,7 @@ with match() as match:
|
||||||
|
|
||||||
# At least one of the above branches must have been taken, because every Python
|
# At least one of the above branches must have been taken, because every Python
|
||||||
# version has exactly one of the two 'ASYNC_*' flags
|
# version has exactly one of the two 'ASYNC_*' flags
|
||||||
@@ -99,9 +91,9 @@
|
@@ -99,9 +89,9 @@
|
||||||
re.match()
|
re.match()
|
||||||
match = a
|
match = a
|
||||||
with match() as match:
|
with match() as match:
|
||||||
|
@ -231,9 +226,7 @@ def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
|
||||||
|
|
||||||
NOT_YET_IMPLEMENTED_StmtMatch
|
NOT_YET_IMPLEMENTED_StmtMatch
|
||||||
|
|
||||||
if all(
|
if all(version.is_python2() for version in target_versions):
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
|
||||||
):
|
|
||||||
# Python 2-only code, so try Python 2 grammars.
|
# Python 2-only code, so try Python 2 grammars.
|
||||||
return [
|
return [
|
||||||
# Python 2.7 with future print_function import
|
# 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
|
```diff
|
||||||
--- Black
|
--- Black
|
||||||
+++ Ruff
|
+++ Ruff
|
||||||
@@ -1,15 +1,20 @@
|
@@ -1,7 +1,7 @@
|
||||||
# Unparenthesized walruses are now allowed in indices since Python 3.10.
|
# Unparenthesized walruses are now allowed in indices since Python 3.10.
|
||||||
-x[a:=0]
|
-x[a:=0]
|
||||||
-x[a:=0, b:=1]
|
-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]
|
+x[5, b := 0]
|
||||||
|
|
||||||
# Walruses are allowed inside generator expressions on function calls since 3.10.
|
# 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(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,
|
|
||||||
+)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ruff Output
|
## Ruff Output
|
||||||
|
@ -67,20 +49,15 @@ x[a := 0, b := 1]
|
||||||
x[5, b := 0]
|
x[5, b := 0]
|
||||||
|
|
||||||
# Walruses are allowed inside generator expressions on function calls since 3.10.
|
# 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:
|
if match.group(2) == data_not_available:
|
||||||
# Error OK to ignore.
|
# Error OK to ignore.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
f((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []))
|
f(a := b + c for c in range(10))
|
||||||
f((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []), x)
|
f((a := b + c for c in range(10)), x)
|
||||||
f(y=(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []))
|
f(y=(a := b + c for c in range(10)))
|
||||||
f(
|
f(x, (a := b + c for c in range(10)), y=z, **q)
|
||||||
x,
|
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []),
|
|
||||||
y=z,
|
|
||||||
**q,
|
|
||||||
)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Black Output
|
## 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)
|
x = (y := 0)
|
||||||
(z := (y := (x := 0)))
|
(z := (y := (x := 0)))
|
||||||
(info := (name, phone, *rest))
|
(info := (name, phone, *rest))
|
||||||
@@ -31,9 +31,9 @@
|
@@ -33,7 +33,7 @@
|
||||||
len(lines := f.readlines())
|
|
||||||
foo(x := 3, cat="vector")
|
|
||||||
foo(cat=(category := "vector"))
|
foo(cat=(category := "vector"))
|
||||||
-if any(len(longline := l) >= 100 for l in lines):
|
if any(len(longline := l) >= 100 for l in lines):
|
||||||
+if any((NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])):
|
|
||||||
print(longline)
|
print(longline)
|
||||||
-if env_base := os.environ.get("PYTHONUSERBASE", None):
|
-if env_base := os.environ.get("PYTHONUSERBASE", None):
|
||||||
+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())
|
len(lines := f.readlines())
|
||||||
foo(x := 3, cat="vector")
|
foo(x := 3, cat="vector")
|
||||||
foo(cat=(category := "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)
|
print(longline)
|
||||||
if (env_base := os.environ.get("PYTHONUSERBASE", None)):
|
if (env_base := os.environ.get("PYTHONUSERBASE", None)):
|
||||||
return env_base
|
return env_base
|
||||||
|
|
|
@ -363,21 +363,6 @@ last_call()
|
||||||
numpy[np.newaxis, :]
|
numpy[np.newaxis, :]
|
||||||
(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None)
|
(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}
|
{"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 @@
|
@@ -208,24 +214,14 @@
|
||||||
what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
|
what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
|
||||||
vars_to_remove
|
vars_to_remove
|
||||||
|
@ -435,15 +420,6 @@ last_call()
|
||||||
assert not Test, "Short message"
|
assert not Test, "Short message"
|
||||||
assert this is ComplexTest and not requirements.fit_in_a_single_line(
|
assert this is ComplexTest and not requirements.fit_in_a_single_line(
|
||||||
force=False
|
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 @@
|
@@ -328,13 +324,18 @@
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
@ -670,10 +646,10 @@ numpy[np.newaxis, :]
|
||||||
(SomeName)
|
(SomeName)
|
||||||
SomeName
|
SomeName
|
||||||
(Good, Bad, Ugly)
|
(Good, Bad, Ugly)
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
(i for i in (1, 2, 3))
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
((i**2) for i in (1, 2, 3))
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
((i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c")))
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
(((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3))
|
||||||
(*starred,)
|
(*starred,)
|
||||||
{
|
{
|
||||||
"id": "1",
|
"id": "1",
|
||||||
|
@ -738,7 +714,7 @@ for (x,) in (1,), (2,), (3,):
|
||||||
...
|
...
|
||||||
for y in ():
|
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():
|
for i in call():
|
||||||
...
|
...
|
||||||
|
|
|
@ -43,7 +43,7 @@ ham[lower + offset : upper + offset]
|
||||||
```diff
|
```diff
|
||||||
--- Black
|
--- Black
|
||||||
+++ Ruff
|
+++ Ruff
|
||||||
@@ -4,19 +4,21 @@
|
@@ -4,19 +4,19 @@
|
||||||
slice[d::d]
|
slice[d::d]
|
||||||
slice[0]
|
slice[0]
|
||||||
slice[-1]
|
slice[-1]
|
||||||
|
@ -63,16 +63,13 @@ ham[lower + offset : upper + offset]
|
||||||
+slice[lambda NOT_YET_IMPLEMENTED_lambda: True :, None::]
|
+slice[lambda NOT_YET_IMPLEMENTED_lambda: True :, None::]
|
||||||
slice[1 or 2 : True and False]
|
slice[1 or 2 : True and False]
|
||||||
slice[not so_simple : 1 < val <= 10]
|
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[:: [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)]]
|
+slice[ :: [i for i in range(42)]]
|
||||||
|
|
||||||
|
|
||||||
async def f():
|
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[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:upper], ham[lower:upper:], ham[lower::step]
|
||||||
# ham[lower+offset : upper+offset]
|
# 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[lambda NOT_YET_IMPLEMENTED_lambda: True :, None::]
|
||||||
slice[1 or 2 : True and False]
|
slice[1 or 2 : True and False]
|
||||||
slice[not so_simple : 1 < val <= 10]
|
slice[not so_simple : 1 < val <= 10]
|
||||||
slice[
|
slice[(1 for i in range(42)) : x]
|
||||||
(NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in []) : x
|
|
||||||
]
|
|
||||||
slice[ :: [i for i in range(42)]]
|
slice[ :: [i for i in range(42)]]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,7 @@ aaaaaaaaaaaaaa + [
|
||||||
]
|
]
|
||||||
(
|
(
|
||||||
aaaaaaaaaaaaaa
|
aaaaaaaaaaaaaa
|
||||||
+ (NOT_YET_IMPLEMENTED_generator_key for NOT_YET_IMPLEMENTED_generator_key in [])
|
+ (a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)
|
||||||
)
|
)
|
||||||
aaaaaaaaaaaaaa + {
|
aaaaaaaaaaaaaa + {
|
||||||
a
|
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
|
# 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
|
pass
|
||||||
with (a, *b):
|
with (a, *b):
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue