Update Black tests (#5438)

This commit is contained in:
Micha Reiser 2023-06-30 08:32:50 +02:00 committed by GitHub
parent f7969cf23c
commit ae25638b0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
166 changed files with 11066 additions and 237 deletions

View file

@ -12,7 +12,12 @@ fn black_compatibility() {
let content = fs::read_to_string(input_path).unwrap();
let options = PyFormatOptions::default();
let printed = format_module(&content, options.clone()).expect("Formatting to succeed");
let printed = format_module(&content, options.clone()).unwrap_or_else(|err| {
panic!(
"Formatting of {} to succeed but encountered error {err}",
input_path.display()
)
});
let expected_path = input_path.with_extension("py.expect");
let expected_output = fs::read_to_string(&expected_path)
@ -20,7 +25,7 @@ fn black_compatibility() {
let formatted_code = printed.as_code();
ensure_stability_when_formatting_twice(formatted_code, options);
ensure_stability_when_formatting_twice(formatted_code, options, input_path);
if formatted_code == expected_output {
// Black and Ruff formatting matches. Delete any existing snapshot files because the Black output
@ -95,7 +100,7 @@ fn format() {
let printed = format_module(&content, options.clone()).expect("Formatting to succeed");
let formatted_code = printed.as_code();
ensure_stability_when_formatting_twice(formatted_code, options);
ensure_stability_when_formatting_twice(formatted_code, options, input_path);
let mut snapshot = format!("## Input\n{}", CodeFrame::new("py", &content));
@ -112,7 +117,7 @@ fn format() {
format_module(&content, options.clone()).expect("Formatting to succeed");
let formatted_code = printed.as_code();
ensure_stability_when_formatting_twice(formatted_code, options.clone());
ensure_stability_when_formatting_twice(formatted_code, options.clone(), input_path);
writeln!(
snapshot,
@ -128,7 +133,7 @@ fn format() {
let printed = format_module(&content, options.clone()).expect("Formatting to succeed");
let formatted_code = printed.as_code();
ensure_stability_when_formatting_twice(formatted_code, options);
ensure_stability_when_formatting_twice(formatted_code, options, input_path);
writeln!(
snapshot,
@ -151,13 +156,18 @@ fn format() {
}
/// Format another time and make sure that there are no changes anymore
fn ensure_stability_when_formatting_twice(formatted_code: &str, options: PyFormatOptions) {
fn ensure_stability_when_formatting_twice(
formatted_code: &str,
options: PyFormatOptions,
input_path: &Path,
) {
let reformatted = match format_module(formatted_code, options) {
Ok(reformatted) => reformatted,
Err(err) => {
panic!(
"Expected formatted code to be valid syntax: {err}:\
"Expected formatted code of {} to be valid syntax: {err}:\
\n---\n{formatted_code}---\n",
input_path.display()
);
}
};
@ -168,7 +178,7 @@ fn ensure_stability_when_formatting_twice(formatted_code: &str, options: PyForma
.header("Formatted once", "Formatted twice")
.to_string();
panic!(
r#"Reformatting the formatted code a second time resulted in formatting changes.
r#"Reformatting the formatted code of {} a second time resulted in formatting changes.
---
{diff}---
@ -179,7 +189,8 @@ Formatted once:
Formatted twice:
---
{}---"#,
reformatted.as_code()
input_path.display(),
reformatted.as_code(),
);
}
}

View file

@ -0,0 +1,334 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/conditional_expression.py
---
## Input
```py
long_kwargs_single_line = my_function(
foo="test, this is a sample value",
bar=some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz,
baz="hello, this is a another value",
)
multiline_kwargs_indented = my_function(
foo="test, this is a sample value",
bar=some_long_value_name_foo_bar_baz
if some_boolean_variable
else some_fallback_value_foo_bar_baz,
baz="hello, this is a another value",
)
imploding_kwargs = my_function(
foo="test, this is a sample value",
bar=a
if foo
else b,
baz="hello, this is a another value",
)
imploding_line = (
1
if 1 + 1 == 2
else 0
)
exploding_line = "hello this is a slightly long string" if some_long_value_name_foo_bar_baz else "this one is a little shorter"
positional_argument_test(some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz)
def weird_default_argument(x=some_long_value_name_foo_bar_baz
if SOME_CONSTANT
else some_fallback_value_foo_bar_baz):
pass
nested = "hello this is a slightly long string" if (some_long_value_name_foo_bar_baz if
nesting_test_expressions else some_fallback_value_foo_bar_baz) \
else "this one is a little shorter"
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(
sql
for sql in (
"LIMIT %d" % limit if limit else None,
("OFFSET %d" % offset) if offset else None,
)
if sql
)
def something():
clone._iterable_class = (
NamedValuesListIterable
if named
else FlatValuesListIterable
if flat
else ValuesListIterable
)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,90 +1,48 @@
long_kwargs_single_line = my_function(
foo="test, this is a sample value",
- bar=(
- some_long_value_name_foo_bar_baz
- if some_boolean_variable
- else some_fallback_value_foo_bar_baz
- ),
+ bar=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false,
baz="hello, this is a another value",
)
multiline_kwargs_indented = my_function(
foo="test, this is a sample value",
- bar=(
- some_long_value_name_foo_bar_baz
- if some_boolean_variable
- else some_fallback_value_foo_bar_baz
- ),
+ bar=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false,
baz="hello, this is a another value",
)
imploding_kwargs = my_function(
foo="test, this is a sample value",
- bar=a if foo else b,
+ bar=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false,
baz="hello, this is a another value",
)
-imploding_line = 1 if 1 + 1 == 2 else 0
+imploding_line = NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
-exploding_line = (
- "hello this is a slightly long string"
- if some_long_value_name_foo_bar_baz
- else "this one is a little shorter"
-)
+exploding_line = NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
positional_argument_test(
- some_long_value_name_foo_bar_baz
- if some_boolean_variable
- else some_fallback_value_foo_bar_baz
+ NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
)
def weird_default_argument(
- x=(
- some_long_value_name_foo_bar_baz
- if SOME_CONSTANT
- else some_fallback_value_foo_bar_baz
- ),
+ x=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
):
pass
-nested = (
- "hello this is a slightly long string"
- if (
- some_long_value_name_foo_bar_baz
- if nesting_test_expressions
- else some_fallback_value_foo_bar_baz
- )
- else "this one is a little shorter"
-)
+nested = NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
-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 = (i for i 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
- )
+ return " ".join((i for i in []))
def something():
clone._iterable_class = (
- NamedValuesListIterable
- if named
- else FlatValuesListIterable if flat else ValuesListIterable
+ NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
)
```
## Ruff Output
```py
long_kwargs_single_line = my_function(
foo="test, this is a sample value",
bar=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false,
baz="hello, this is a another value",
)
multiline_kwargs_indented = my_function(
foo="test, this is a sample value",
bar=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false,
baz="hello, this is a another value",
)
imploding_kwargs = my_function(
foo="test, this is a sample value",
bar=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false,
baz="hello, this is a another value",
)
imploding_line = NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
exploding_line = NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
positional_argument_test(
NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
)
def weird_default_argument(
x=NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
):
pass
nested = NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
generator_expression = (i for i 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((i for i in []))
def something():
clone._iterable_class = (
NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
)
```
## Black Output
```py
long_kwargs_single_line = my_function(
foo="test, this is a sample value",
bar=(
some_long_value_name_foo_bar_baz
if some_boolean_variable
else some_fallback_value_foo_bar_baz
),
baz="hello, this is a another value",
)
multiline_kwargs_indented = my_function(
foo="test, this is a sample value",
bar=(
some_long_value_name_foo_bar_baz
if some_boolean_variable
else some_fallback_value_foo_bar_baz
),
baz="hello, this is a another value",
)
imploding_kwargs = my_function(
foo="test, this is a sample value",
bar=a if foo else b,
baz="hello, this is a another value",
)
imploding_line = 1 if 1 + 1 == 2 else 0
exploding_line = (
"hello this is a slightly long string"
if some_long_value_name_foo_bar_baz
else "this one is a little shorter"
)
positional_argument_test(
some_long_value_name_foo_bar_baz
if some_boolean_variable
else some_fallback_value_foo_bar_baz
)
def weird_default_argument(
x=(
some_long_value_name_foo_bar_baz
if SOME_CONSTANT
else some_fallback_value_foo_bar_baz
),
):
pass
nested = (
"hello this is a slightly long string"
if (
some_long_value_name_foo_bar_baz
if nesting_test_expressions
else some_fallback_value_foo_bar_baz
)
else "this one is a little shorter"
)
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(
sql
for sql in (
"LIMIT %d" % limit if limit else None,
("OFFSET %d" % offset) if offset else None,
)
if sql
)
def something():
clone._iterable_class = (
NamedValuesListIterable
if named
else FlatValuesListIterable if flat else ValuesListIterable
)
```

View file

@ -0,0 +1,55 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/blackd_diff.py
---
## Input
```py
def abc ():
return ["hello", "world",
"!"]
print( "Incorrect formatting"
)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,6 +1,5 @@
-def abc ():
- return ["hello", "world",
- "!"]
+def abc():
+ return ["hello", "world", "!"]
-print( "Incorrect formatting"
-)
+
+print("Incorrect formatting")
```
## Ruff Output
```py
def abc():
return ["hello", "world", "!"]
print("Incorrect formatting")
```
## Black Output
```py
def abc ():
return ["hello", "world",
"!"]
print( "Incorrect formatting"
)
```

View file

@ -0,0 +1,167 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/debug_visitor.py
---
## Input
```py
@dataclass
class DebugVisitor(Visitor[T]):
tree_depth: int = 0
def visit_default(self, node: LN) -> Iterator[T]:
indent = ' ' * (2 * self.tree_depth)
if isinstance(node, Node):
_type = type_repr(node.type)
out(f'{indent}{_type}', fg='yellow')
self.tree_depth += 1
for child in node.children:
yield from self.visit(child)
self.tree_depth -= 1
out(f'{indent}/{_type}', fg='yellow', bold=False)
else:
_type = token.tok_name.get(node.type, str(node.type))
out(f'{indent}{_type}', fg='blue', nl=False)
if node.prefix:
# We don't have to handle prefixes for `Node` objects since
# that delegates to the first child anyway.
out(f' {node.prefix!r}', fg='green', bold=False, nl=False)
out(f' {node.value!r}', fg='blue', bold=False)
@classmethod
def show(cls, code: str) -> None:
"""Pretty-prints a given string of `code`.
Convenience method for debugging.
"""
v: DebugVisitor[None] = DebugVisitor()
list(v.visit(lib2to3_parse(code)))
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,26 +1,26 @@
@dataclass
class DebugVisitor(Visitor[T]):
- tree_depth: int = 0
+ NOT_YET_IMPLEMENTED_StmtAnnAssign
def visit_default(self, node: LN) -> Iterator[T]:
- indent = ' ' * (2 * self.tree_depth)
+ indent = " " * (2 * self.tree_depth)
if isinstance(node, Node):
_type = type_repr(node.type)
- out(f'{indent}{_type}', fg='yellow')
- self.tree_depth += 1
+ out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="yellow")
+ NOT_YET_IMPLEMENTED_StmtAugAssign
for child in node.children:
- yield from self.visit(child)
+ NOT_YET_IMPLEMENTED_ExprYieldFrom
- self.tree_depth -= 1
- out(f'{indent}/{_type}', fg='yellow', bold=False)
+ NOT_YET_IMPLEMENTED_StmtAugAssign
+ out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="yellow", bold=False)
else:
_type = token.tok_name.get(node.type, str(node.type))
- out(f'{indent}{_type}', fg='blue', nl=False)
+ out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="blue", nl=False)
if node.prefix:
# We don't have to handle prefixes for `Node` objects since
# that delegates to the first child anyway.
- out(f' {node.prefix!r}', fg='green', bold=False, nl=False)
- out(f' {node.value!r}', fg='blue', bold=False)
+ out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="green", bold=False, nl=False)
+ out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="blue", bold=False)
@classmethod
def show(cls, code: str) -> None:
@@ -28,5 +28,5 @@
Convenience method for debugging.
"""
- v: DebugVisitor[None] = DebugVisitor()
+ NOT_YET_IMPLEMENTED_StmtAnnAssign
list(v.visit(lib2to3_parse(code)))
```
## Ruff Output
```py
@dataclass
class DebugVisitor(Visitor[T]):
NOT_YET_IMPLEMENTED_StmtAnnAssign
def visit_default(self, node: LN) -> Iterator[T]:
indent = " " * (2 * self.tree_depth)
if isinstance(node, Node):
_type = type_repr(node.type)
out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="yellow")
NOT_YET_IMPLEMENTED_StmtAugAssign
for child in node.children:
NOT_YET_IMPLEMENTED_ExprYieldFrom
NOT_YET_IMPLEMENTED_StmtAugAssign
out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="yellow", bold=False)
else:
_type = token.tok_name.get(node.type, str(node.type))
out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="blue", nl=False)
if node.prefix:
# We don't have to handle prefixes for `Node` objects since
# that delegates to the first child anyway.
out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="green", bold=False, nl=False)
out(NOT_YET_IMPLEMENTED_ExprJoinedStr, fg="blue", bold=False)
@classmethod
def show(cls, code: str) -> None:
"""Pretty-prints a given string of `code`.
Convenience method for debugging.
"""
NOT_YET_IMPLEMENTED_StmtAnnAssign
list(v.visit(lib2to3_parse(code)))
```
## Black Output
```py
@dataclass
class DebugVisitor(Visitor[T]):
tree_depth: int = 0
def visit_default(self, node: LN) -> Iterator[T]:
indent = ' ' * (2 * self.tree_depth)
if isinstance(node, Node):
_type = type_repr(node.type)
out(f'{indent}{_type}', fg='yellow')
self.tree_depth += 1
for child in node.children:
yield from self.visit(child)
self.tree_depth -= 1
out(f'{indent}/{_type}', fg='yellow', bold=False)
else:
_type = token.tok_name.get(node.type, str(node.type))
out(f'{indent}{_type}', fg='blue', nl=False)
if node.prefix:
# We don't have to handle prefixes for `Node` objects since
# that delegates to the first child anyway.
out(f' {node.prefix!r}', fg='green', bold=False, nl=False)
out(f' {node.value!r}', fg='blue', bold=False)
@classmethod
def show(cls, code: str) -> None:
"""Pretty-prints a given string of `code`.
Convenience method for debugging.
"""
v: DebugVisitor[None] = DebugVisitor()
list(v.visit(lib2to3_parse(code)))
```

View file

@ -0,0 +1,576 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py
---
## Input
```py
# This file doesn't use the standard decomposition.
# Decorator syntax test cases are separated by double # comments.
# Those before the 'output' comment are valid under the old syntax.
# Those after the 'ouput' comment require PEP614 relaxed syntax.
# Do not remove the double # separator before the first test case, it allows
# the comment before the test case to be ignored.
##
@decorator
def f():
...
##
@decorator()
def f():
...
##
@decorator(arg)
def f():
...
##
@decorator(kwarg=0)
def f():
...
##
@decorator(*args)
def f():
...
##
@decorator(**kwargs)
def f():
...
##
@decorator(*args, **kwargs)
def f():
...
##
@decorator(*args, **kwargs,)
def f():
...
##
@dotted.decorator
def f():
...
##
@dotted.decorator(arg)
def f():
...
##
@dotted.decorator(kwarg=0)
def f():
...
##
@dotted.decorator(*args)
def f():
...
##
@dotted.decorator(**kwargs)
def f():
...
##
@dotted.decorator(*args, **kwargs)
def f():
...
##
@dotted.decorator(*args, **kwargs,)
def f():
...
##
@double.dotted.decorator
def f():
...
##
@double.dotted.decorator(arg)
def f():
...
##
@double.dotted.decorator(kwarg=0)
def f():
...
##
@double.dotted.decorator(*args)
def f():
...
##
@double.dotted.decorator(**kwargs)
def f():
...
##
@double.dotted.decorator(*args, **kwargs)
def f():
...
##
@double.dotted.decorator(*args, **kwargs,)
def f():
...
##
@_(sequence["decorator"])
def f():
...
##
@eval("sequence['decorator']")
def f():
...
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,29 +1,182 @@
+# This file doesn't use the standard decomposition.
+# Decorator syntax test cases are separated by double # comments.
+# Those before the 'output' comment are valid under the old syntax.
+# Those after the 'ouput' comment require PEP614 relaxed syntax.
+# Do not remove the double # separator before the first test case, it allows
+# the comment before the test case to be ignored.
+
+##
+
+@decorator
+def f():
+ ...
+
+
+##
+
+@decorator()
+def f():
+ ...
+
+
+##
+
+@decorator(arg)
+def f():
+ ...
+
+
+##
+
+@decorator(kwarg=0)
+def f():
+ ...
+
+
+##
+
+@decorator(*NOT_YET_IMPLEMENTED_ExprStarred)
+def f():
+ ...
+
+
##
-@decorator()()
+@decorator(**kwargs)
def f():
...
+
##
-@(decorator)
+@decorator(*NOT_YET_IMPLEMENTED_ExprStarred, **kwargs)
def f():
...
+
##
-@sequence["decorator"]
+@decorator(
+ *NOT_YET_IMPLEMENTED_ExprStarred,
+ **kwargs,
+)
def f():
...
+
##
-@decorator[List[str]]
+@dotted.decorator
def f():
...
+
##
-@var := decorator
+@dotted.decorator(arg)
+def f():
+ ...
+
+
+##
+
+@dotted.decorator(kwarg=0)
+def f():
+ ...
+
+
+##
+
+@dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred)
+def f():
+ ...
+
+
+##
+
+@dotted.decorator(**kwargs)
+def f():
+ ...
+
+
+##
+
+@dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred, **kwargs)
+def f():
+ ...
+
+
+##
+
+@dotted.decorator(
+ *NOT_YET_IMPLEMENTED_ExprStarred,
+ **kwargs,
+)
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator(arg)
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator(kwarg=0)
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred)
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator(**kwargs)
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred, **kwargs)
+def f():
+ ...
+
+
+##
+
+@double.dotted.decorator(
+ *NOT_YET_IMPLEMENTED_ExprStarred,
+ **kwargs,
+)
+def f():
+ ...
+
+
+##
+
+@_(sequence["decorator"])
+def f():
+ ...
+
+
+##
+
+@eval("sequence['decorator']")
def f():
...
```
## Ruff Output
```py
# This file doesn't use the standard decomposition.
# Decorator syntax test cases are separated by double # comments.
# Those before the 'output' comment are valid under the old syntax.
# Those after the 'ouput' comment require PEP614 relaxed syntax.
# Do not remove the double # separator before the first test case, it allows
# the comment before the test case to be ignored.
##
@decorator
def f():
...
##
@decorator()
def f():
...
##
@decorator(arg)
def f():
...
##
@decorator(kwarg=0)
def f():
...
##
@decorator(*NOT_YET_IMPLEMENTED_ExprStarred)
def f():
...
##
@decorator(**kwargs)
def f():
...
##
@decorator(*NOT_YET_IMPLEMENTED_ExprStarred, **kwargs)
def f():
...
##
@decorator(
*NOT_YET_IMPLEMENTED_ExprStarred,
**kwargs,
)
def f():
...
##
@dotted.decorator
def f():
...
##
@dotted.decorator(arg)
def f():
...
##
@dotted.decorator(kwarg=0)
def f():
...
##
@dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred)
def f():
...
##
@dotted.decorator(**kwargs)
def f():
...
##
@dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred, **kwargs)
def f():
...
##
@dotted.decorator(
*NOT_YET_IMPLEMENTED_ExprStarred,
**kwargs,
)
def f():
...
##
@double.dotted.decorator
def f():
...
##
@double.dotted.decorator(arg)
def f():
...
##
@double.dotted.decorator(kwarg=0)
def f():
...
##
@double.dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred)
def f():
...
##
@double.dotted.decorator(**kwargs)
def f():
...
##
@double.dotted.decorator(*NOT_YET_IMPLEMENTED_ExprStarred, **kwargs)
def f():
...
##
@double.dotted.decorator(
*NOT_YET_IMPLEMENTED_ExprStarred,
**kwargs,
)
def f():
...
##
@_(sequence["decorator"])
def f():
...
##
@eval("sequence['decorator']")
def f():
...
```
## Black Output
```py
##
@decorator()()
def f():
...
##
@(decorator)
def f():
...
##
@sequence["decorator"]
def f():
...
##
@decorator[List[str]]
def f():
...
##
@var := decorator
def f():
...
```

View file

@ -0,0 +1,556 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_no_string_normalization.py
---
## Input
```py
class ALonelyClass:
'''
A multiline class docstring.
'''
def AnEquallyLonelyMethod(self):
'''
A multiline method docstring'''
pass
def one_function():
'''This is a docstring with a single line of text.'''
pass
def shockingly_the_quotes_are_normalized():
'''This is a multiline docstring.
This is a multiline docstring.
This is a multiline docstring.
'''
pass
def foo():
"""This is a docstring with
some lines of text here
"""
return
def baz():
'''"This" is a string with some
embedded "quotes"'''
return
def poit():
"""
Lorem ipsum dolor sit amet.
Consectetur adipiscing elit:
- sed do eiusmod tempor incididunt ut labore
- dolore magna aliqua
- enim ad minim veniam
- quis nostrud exercitation ullamco laboris nisi
- aliquip ex ea commodo consequat
"""
pass
def under_indent():
"""
These lines are indented in a way that does not
make sense.
"""
pass
def over_indent():
"""
This has a shallow indent
- But some lines are deeper
- And the closing quote is too deep
"""
pass
def single_line():
"""But with a newline after it!
"""
pass
def this():
r"""
'hey ho'
"""
def that():
""" "hey yah" """
def and_that():
"""
"hey yah" """
def and_this():
'''
"hey yah"'''
def believe_it_or_not_this_is_in_the_py_stdlib(): '''
"hey yah"'''
def shockingly_the_quotes_are_normalized_v2():
'''
Docstring Docstring Docstring
'''
pass
def backslash_space():
'\ '
def multiline_backslash_1():
'''
hey\there\
\ '''
def multiline_backslash_2():
'''
hey there \ '''
def multiline_backslash_3():
'''
already escaped \\ '''
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,73 +1,75 @@
class ALonelyClass:
- '''
+ """
A multiline class docstring.
- '''
+ """
def AnEquallyLonelyMethod(self):
- '''
- A multiline method docstring'''
+ """
+ A multiline method docstring"""
pass
def one_function():
- '''This is a docstring with a single line of text.'''
+ """This is a docstring with a single line of text."""
pass
def shockingly_the_quotes_are_normalized():
- '''This is a multiline docstring.
+ """This is a multiline docstring.
This is a multiline docstring.
This is a multiline docstring.
- '''
+ """
pass
def foo():
- """This is a docstring with
- some lines of text here
- """
+ """This is a docstring with
+ some lines of text here
+ """
return
def baz():
'''"This" is a string with some
- embedded "quotes"'''
+ embedded "quotes"'''
return
def poit():
"""
- Lorem ipsum dolor sit amet.
+ Lorem ipsum dolor sit amet.
- Consectetur adipiscing elit:
- - sed do eiusmod tempor incididunt ut labore
- - dolore magna aliqua
- - enim ad minim veniam
- - quis nostrud exercitation ullamco laboris nisi
- - aliquip ex ea commodo consequat
- """
+ Consectetur adipiscing elit:
+ - sed do eiusmod tempor incididunt ut labore
+ - dolore magna aliqua
+ - enim ad minim veniam
+ - quis nostrud exercitation ullamco laboris nisi
+ - aliquip ex ea commodo consequat
+ """
pass
def under_indent():
"""
- These lines are indented in a way that does not
- make sense.
- """
+ These lines are indented in a way that does not
+make sense.
+ """
pass
def over_indent():
"""
- This has a shallow indent
- - But some lines are deeper
- - And the closing quote is too deep
+ This has a shallow indent
+ - But some lines are deeper
+ - And the closing quote is too deep
"""
pass
def single_line():
- """But with a newline after it!"""
+ """But with a newline after it!
+
+ """
pass
@@ -83,41 +85,41 @@
def and_that():
"""
- "hey yah" """
+ "hey yah" """
def and_this():
- '''
- "hey yah"'''
+ '''
+ "hey yah"'''
def believe_it_or_not_this_is_in_the_py_stdlib():
- '''
- "hey yah"'''
+ '''
+"hey yah"'''
def shockingly_the_quotes_are_normalized_v2():
- '''
+ """
Docstring Docstring Docstring
- '''
+ """
pass
def backslash_space():
- '\ '
+ "\ "
def multiline_backslash_1():
- '''
+ """
hey\there\
- \ '''
+ \ """
def multiline_backslash_2():
- '''
- hey there \ '''
+ """
+ hey there \ """
def multiline_backslash_3():
- '''
- already escaped \\'''
+ """
+ already escaped \\ """
```
## Ruff Output
```py
class ALonelyClass:
"""
A multiline class docstring.
"""
def AnEquallyLonelyMethod(self):
"""
A multiline method docstring"""
pass
def one_function():
"""This is a docstring with a single line of text."""
pass
def shockingly_the_quotes_are_normalized():
"""This is a multiline docstring.
This is a multiline docstring.
This is a multiline docstring.
"""
pass
def foo():
"""This is a docstring with
some lines of text here
"""
return
def baz():
'''"This" is a string with some
embedded "quotes"'''
return
def poit():
"""
Lorem ipsum dolor sit amet.
Consectetur adipiscing elit:
- sed do eiusmod tempor incididunt ut labore
- dolore magna aliqua
- enim ad minim veniam
- quis nostrud exercitation ullamco laboris nisi
- aliquip ex ea commodo consequat
"""
pass
def under_indent():
"""
These lines are indented in a way that does not
make sense.
"""
pass
def over_indent():
"""
This has a shallow indent
- But some lines are deeper
- And the closing quote is too deep
"""
pass
def single_line():
"""But with a newline after it!
"""
pass
def this():
r"""
'hey ho'
"""
def that():
""" "hey yah" """
def and_that():
"""
"hey yah" """
def and_this():
'''
"hey yah"'''
def believe_it_or_not_this_is_in_the_py_stdlib():
'''
"hey yah"'''
def shockingly_the_quotes_are_normalized_v2():
"""
Docstring Docstring Docstring
"""
pass
def backslash_space():
"\ "
def multiline_backslash_1():
"""
hey\there\
\ """
def multiline_backslash_2():
"""
hey there \ """
def multiline_backslash_3():
"""
already escaped \\ """
```
## Black Output
```py
class ALonelyClass:
'''
A multiline class docstring.
'''
def AnEquallyLonelyMethod(self):
'''
A multiline method docstring'''
pass
def one_function():
'''This is a docstring with a single line of text.'''
pass
def shockingly_the_quotes_are_normalized():
'''This is a multiline docstring.
This is a multiline docstring.
This is a multiline docstring.
'''
pass
def foo():
"""This is a docstring with
some lines of text here
"""
return
def baz():
'''"This" is a string with some
embedded "quotes"'''
return
def poit():
"""
Lorem ipsum dolor sit amet.
Consectetur adipiscing elit:
- sed do eiusmod tempor incididunt ut labore
- dolore magna aliqua
- enim ad minim veniam
- quis nostrud exercitation ullamco laboris nisi
- aliquip ex ea commodo consequat
"""
pass
def under_indent():
"""
These lines are indented in a way that does not
make sense.
"""
pass
def over_indent():
"""
This has a shallow indent
- But some lines are deeper
- And the closing quote is too deep
"""
pass
def single_line():
"""But with a newline after it!"""
pass
def this():
r"""
'hey ho'
"""
def that():
""" "hey yah" """
def and_that():
"""
"hey yah" """
def and_this():
'''
"hey yah"'''
def believe_it_or_not_this_is_in_the_py_stdlib():
'''
"hey yah"'''
def shockingly_the_quotes_are_normalized_v2():
'''
Docstring Docstring Docstring
'''
pass
def backslash_space():
'\ '
def multiline_backslash_1():
'''
hey\there\
\ '''
def multiline_backslash_2():
'''
hey there \ '''
def multiline_backslash_3():
'''
already escaped \\'''
```

View file

@ -0,0 +1,68 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_preview_no_string_normalization.py
---
## Input
```py
def do_not_touch_this_prefix():
R"""There was a bug where docstring prefixes would be normalized even with -S."""
def do_not_touch_this_prefix2():
FR'There was a bug where docstring prefixes would be normalized even with -S.'
def do_not_touch_this_prefix3():
u'''There was a bug where docstring prefixes would be normalized even with -S.'''
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -3,8 +3,8 @@
def do_not_touch_this_prefix2():
- FR'There was a bug where docstring prefixes would be normalized even with -S.'
+ NOT_YET_IMPLEMENTED_ExprJoinedStr
def do_not_touch_this_prefix3():
- u'''There was a bug where docstring prefixes would be normalized even with -S.'''
+ """There was a bug where docstring prefixes would be normalized even with -S."""
```
## Ruff Output
```py
def do_not_touch_this_prefix():
R"""There was a bug where docstring prefixes would be normalized even with -S."""
def do_not_touch_this_prefix2():
NOT_YET_IMPLEMENTED_ExprJoinedStr
def do_not_touch_this_prefix3():
"""There was a bug where docstring prefixes would be normalized even with -S."""
```
## Black Output
```py
def do_not_touch_this_prefix():
R"""There was a bug where docstring prefixes would be normalized even with -S."""
def do_not_touch_this_prefix2():
FR'There was a bug where docstring prefixes would be normalized even with -S.'
def do_not_touch_this_prefix3():
u'''There was a bug where docstring prefixes would be normalized even with -S.'''
```

View file

@ -0,0 +1,220 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py
---
## Input
```py
from typing import Union
@bird
def zoo(): ...
class A: ...
@bar
class B:
def BMethod(self) -> None: ...
@overload
def BMethod(self, arg : List[str]) -> None: ...
class C: ...
@hmm
class D: ...
class E: ...
@baz
def foo() -> None:
...
class F (A , C): ...
def spam() -> None: ...
@overload
def spam(arg: str) -> str: ...
var : int = 1
def eggs() -> Union[str, int]: ...
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,32 +1,58 @@
-from typing import Union
+NOT_YET_IMPLEMENTED_StmtImportFrom
+
@bird
-def zoo(): ...
+def zoo():
+ ...
+
+
+class A:
+ ...
-class A: ...
@bar
class B:
- def BMethod(self) -> None: ...
+ def BMethod(self) -> None:
+ ...
+
@overload
- def BMethod(self, arg: List[str]) -> None: ...
+ def BMethod(self, arg: List[str]) -> None:
+ ...
-class C: ...
+class C:
+ ...
+
+
@hmm
-class D: ...
+class D:
+ ...
+
+
+class E:
+ ...
-class E: ...
@baz
-def foo() -> None: ...
+def foo() -> None:
+ ...
+
+
+class F(A, C):
+ ...
-class F(A, C): ...
-def spam() -> None: ...
+def spam() -> None:
+ ...
+
+
@overload
-def spam(arg: str) -> str: ...
+def spam(arg: str) -> str:
+ ...
+
+
+NOT_YET_IMPLEMENTED_StmtAnnAssign
-var: int = 1
-def eggs() -> Union[str, int]: ...
+def eggs() -> Union[str, int]:
+ ...
```
## Ruff Output
```py
NOT_YET_IMPLEMENTED_StmtImportFrom
@bird
def zoo():
...
class A:
...
@bar
class B:
def BMethod(self) -> None:
...
@overload
def BMethod(self, arg: List[str]) -> None:
...
class C:
...
@hmm
class D:
...
class E:
...
@baz
def foo() -> None:
...
class F(A, C):
...
def spam() -> None:
...
@overload
def spam(arg: str) -> str:
...
NOT_YET_IMPLEMENTED_StmtAnnAssign
def eggs() -> Union[str, int]:
...
```
## Black Output
```py
from typing import Union
@bird
def zoo(): ...
class A: ...
@bar
class B:
def BMethod(self) -> None: ...
@overload
def BMethod(self, arg: List[str]) -> None: ...
class C: ...
@hmm
class D: ...
class E: ...
@baz
def foo() -> None: ...
class F(A, C): ...
def spam() -> None: ...
@overload
def spam(arg: str) -> str: ...
var: int = 1
def eggs() -> Union[str, int]: ...
```

View file

@ -0,0 +1,44 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/power_op_newline.py
---
## Input
```py
importA;()<<0**0#
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,6 +1,2 @@
importA
-(
- ()
- << 0
- ** 0
-) #
+() << 0**0 #
```
## Ruff Output
```py
importA
() << 0**0 #
```
## Black Output
```py
importA
(
()
<< 0
** 0
) #
```

View file

@ -0,0 +1,244 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py
---
## Input
```py
''''''
'\''
'"'
"'"
"\""
"Hello"
"Don't do that"
'Here is a "'
'What\'s the deal here?'
"What's the deal \"here\"?"
"And \"here\"?"
"""Strings with "" in them"""
'''Strings with "" in them'''
'''Here's a "'''
'''Here's a " '''
'''Just a normal triple
quote'''
f"just a normal {f} string"
f'''This is a triple-quoted {f}-string'''
f'MOAR {" ".join([])}'
f"MOAR {' '.join([])}"
r"raw string ftw"
r'Date d\'expiration:(.*)'
r'Tricky "quote'
r'Not-so-tricky \"quote'
rf'{yay}'
'\n\
The \"quick\"\n\
brown fox\n\
jumps over\n\
the \'lazy\' dog.\n\
'
re.compile(r'[\\"]')
"x = ''; y = \"\""
"x = '''; y = \"\""
"x = ''''; y = \"\""
"x = '' ''; y = \"\""
"x = ''; y = \"\"\""
"x = '''; y = \"\"\"\""
"x = ''''; y = \"\"\"\"\""
"x = '' ''; y = \"\"\"\"\""
'unnecessary \"\"escaping'
"unnecessary \'\'escaping"
'\\""'
"\\''"
'Lots of \\\\\\\\\'quotes\''
f'{y * " "} \'{z}\''
f'{{y * " "}} \'{z}\''
f'\'{z}\' {y * " "}'
f'{y * x} \'{z}\''
'\'{z}\' {y * " "}'
'{y * x} \'{z}\''
# We must bail out if changing the quotes would introduce backslashes in f-string
# expressions. xref: https://github.com/psf/black/issues/2348
f"\"{b}\"{' ' * (long-len(b)+1)}: \"{sts}\",\n"
f"\"{a}\"{'hello' * b}\"{c}\""
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -15,16 +15,21 @@
"""Here's a " """
"""Just a normal triple
quote"""
-f"just a normal {f} string"
-f"""This is a triple-quoted {f}-string"""
-f'MOAR {" ".join([])}'
-f"MOAR {' '.join([])}"
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
r"raw string ftw"
-r"Date d\'expiration:(.*)"
+r"Date d'expiration:(.*)"
r'Tricky "quote'
-r"Not-so-tricky \"quote"
-rf"{yay}"
-"\nThe \"quick\"\nbrown fox\njumps over\nthe 'lazy' dog.\n"
+r'Not-so-tricky "quote'
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+"\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the 'lazy' dog.\n\
+"
re.compile(r'[\\"]')
"x = ''; y = \"\""
"x = '''; y = \"\""
@@ -39,14 +44,14 @@
'\\""'
"\\''"
"Lots of \\\\\\\\'quotes'"
-f'{y * " "} \'{z}\''
-f"{{y * \" \"}} '{z}'"
-f'\'{z}\' {y * " "}'
-f"{y * x} '{z}'"
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
"'{z}' {y * \" \"}"
"{y * x} '{z}'"
# We must bail out if changing the quotes would introduce backslashes in f-string
# expressions. xref: https://github.com/psf/black/issues/2348
-f"\"{b}\"{' ' * (long-len(b)+1)}: \"{sts}\",\n"
-f"\"{a}\"{'hello' * b}\"{c}\""
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
```
## Ruff Output
```py
""""""
"'"
'"'
"'"
'"'
"Hello"
"Don't do that"
'Here is a "'
"What's the deal here?"
'What\'s the deal "here"?'
'And "here"?'
"""Strings with "" in them"""
"""Strings with "" in them"""
'''Here's a "'''
"""Here's a " """
"""Just a normal triple
quote"""
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
r"raw string ftw"
r"Date d'expiration:(.*)"
r'Tricky "quote'
r'Not-so-tricky "quote'
NOT_YET_IMPLEMENTED_ExprJoinedStr
"\n\
The \"quick\"\n\
brown fox\n\
jumps over\n\
the 'lazy' dog.\n\
"
re.compile(r'[\\"]')
"x = ''; y = \"\""
"x = '''; y = \"\""
"x = ''''; y = \"\""
"x = '' ''; y = \"\""
'x = \'\'; y = """'
'x = \'\'\'; y = """"'
'x = \'\'\'\'; y = """""'
'x = \'\' \'\'; y = """""'
'unnecessary ""escaping'
"unnecessary ''escaping"
'\\""'
"\\''"
"Lots of \\\\\\\\'quotes'"
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
"'{z}' {y * \" \"}"
"{y * x} '{z}'"
# We must bail out if changing the quotes would introduce backslashes in f-string
# expressions. xref: https://github.com/psf/black/issues/2348
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
```
## Black Output
```py
""""""
"'"
'"'
"'"
'"'
"Hello"
"Don't do that"
'Here is a "'
"What's the deal here?"
'What\'s the deal "here"?'
'And "here"?'
"""Strings with "" in them"""
"""Strings with "" in them"""
'''Here's a "'''
"""Here's a " """
"""Just a normal triple
quote"""
f"just a normal {f} string"
f"""This is a triple-quoted {f}-string"""
f'MOAR {" ".join([])}'
f"MOAR {' '.join([])}"
r"raw string ftw"
r"Date d\'expiration:(.*)"
r'Tricky "quote'
r"Not-so-tricky \"quote"
rf"{yay}"
"\nThe \"quick\"\nbrown fox\njumps over\nthe 'lazy' dog.\n"
re.compile(r'[\\"]')
"x = ''; y = \"\""
"x = '''; y = \"\""
"x = ''''; y = \"\""
"x = '' ''; y = \"\""
'x = \'\'; y = """'
'x = \'\'\'; y = """"'
'x = \'\'\'\'; y = """""'
'x = \'\' \'\'; y = """""'
'unnecessary ""escaping'
"unnecessary ''escaping"
'\\""'
"\\''"
"Lots of \\\\\\\\'quotes'"
f'{y * " "} \'{z}\''
f"{{y * \" \"}} '{z}'"
f'\'{z}\' {y * " "}'
f"{y * x} '{z}'"
"'{z}' {y * \" \"}"
"{y * x} '{z}'"
# We must bail out if changing the quotes would introduce backslashes in f-string
# expressions. xref: https://github.com/psf/black/issues/2348
f"\"{b}\"{' ' * (long-len(b)+1)}: \"{sts}\",\n"
f"\"{a}\"{'hello' * b}\"{c}\""
```

View file

@ -0,0 +1,549 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py
---
## Input
```py
# Cases sampled from Lib/test/test_patma.py
# case black_test_patma_098
match x:
case -0j:
y = 0
# case black_test_patma_142
match x:
case bytes(z):
y = 0
# case black_test_patma_073
match x:
case 0 if 0:
y = 0
case 0 if 1:
y = 1
# case black_test_patma_006
match 3:
case 0 | 1 | 2 | 3:
x = True
# case black_test_patma_049
match x:
case [0, 1] | [1, 0]:
y = 0
# case black_check_sequence_then_mapping
match x:
case [*_]:
return "seq"
case {}:
return "map"
# case black_test_patma_035
match x:
case {0: [1, 2, {}]}:
y = 0
case {0: [1, 2, {}] | True} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
y = 1
case []:
y = 2
# case black_test_patma_107
match x:
case 0.25 + 1.75j:
y = 0
# case black_test_patma_097
match x:
case -0j:
y = 0
# case black_test_patma_007
match 4:
case 0 | 1 | 2 | 3:
x = True
# case black_test_patma_154
match x:
case 0 if x:
y = 0
# case black_test_patma_134
match x:
case {1: 0}:
y = 0
case {0: 0}:
y = 1
case {**z}:
y = 2
# case black_test_patma_185
match Seq():
case [*_]:
y = 0
# case black_test_patma_063
match x:
case 1:
y = 0
case 1:
y = 1
# case black_test_patma_248
match x:
case {"foo": bar}:
y = bar
# case black_test_patma_019
match (0, 1, 2):
case [0, 1, *x, 2]:
y = 0
# case black_test_patma_052
match x:
case [0]:
y = 0
case [1, 0] if (x := x[:0]):
y = 1
case [1, 0]:
y = 2
# case black_test_patma_191
match w:
case [x, y, *_]:
z = 0
# case black_test_patma_110
match x:
case -0.25 - 1.75j:
y = 0
# case black_test_patma_151
match (x,):
case [y]:
z = 0
# case black_test_patma_114
match x:
case A.B.C.D:
y = 0
# case black_test_patma_232
match x:
case None:
y = 0
# case black_test_patma_058
match x:
case 0:
y = 0
# case black_test_patma_233
match x:
case False:
y = 0
# case black_test_patma_078
match x:
case []:
y = 0
case [""]:
y = 1
case "":
y = 2
# case black_test_patma_156
match x:
case z:
y = 0
# case black_test_patma_189
match w:
case [x, y, *rest]:
z = 0
# case black_test_patma_042
match x:
case (0 as z) | (1 as z) | (2 as z) if z == x % 2:
y = 0
# case black_test_patma_034
match x:
case {0: [1, 2, {}]}:
y = 0
case {0: [1, 2, {}] | False} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
y = 1
case []:
y = 2
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,144 +1,60 @@
# Cases sampled from Lib/test/test_patma.py
# case black_test_patma_098
-match x:
- case -0j:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_142
-match x:
- case bytes(z):
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_073
-match x:
- case 0 if 0:
- y = 0
- case 0 if 1:
- y = 1
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_006
-match 3:
- case 0 | 1 | 2 | 3:
- x = True
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_049
-match x:
- case [0, 1] | [1, 0]:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_check_sequence_then_mapping
-match x:
- case [*_]:
- return "seq"
- case {}:
- return "map"
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_035
-match x:
- case {0: [1, 2, {}]}:
- y = 0
- case {0: [1, 2, {}] | True} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
- y = 1
- case []:
- y = 2
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_107
-match x:
- case 0.25 + 1.75j:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_097
-match x:
- case -0j:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_007
-match 4:
- case 0 | 1 | 2 | 3:
- x = True
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_154
-match x:
- case 0 if x:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_134
-match x:
- case {1: 0}:
- y = 0
- case {0: 0}:
- y = 1
- case {**z}:
- y = 2
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_185
-match Seq():
- case [*_]:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_063
-match x:
- case 1:
- y = 0
- case 1:
- y = 1
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_248
-match x:
- case {"foo": bar}:
- y = bar
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_019
-match (0, 1, 2):
- case [0, 1, *x, 2]:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_052
-match x:
- case [0]:
- y = 0
- case [1, 0] if (x := x[:0]):
- y = 1
- case [1, 0]:
- y = 2
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_191
-match w:
- case [x, y, *_]:
- z = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_110
-match x:
- case -0.25 - 1.75j:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_151
-match (x,):
- case [y]:
- z = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_114
-match x:
- case A.B.C.D:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_232
-match x:
- case None:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_058
-match x:
- case 0:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_233
-match x:
- case False:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_078
-match x:
- case []:
- y = 0
- case [""]:
- y = 1
- case "":
- y = 2
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_156
-match x:
- case z:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_189
-match w:
- case [x, y, *rest]:
- z = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_042
-match x:
- case (0 as z) | (1 as z) | (2 as z) if z == x % 2:
- y = 0
+NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_034
-match x:
- case {0: [1, 2, {}]}:
- y = 0
- case {0: [1, 2, {}] | False} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
- y = 1
- case []:
- y = 2
+NOT_YET_IMPLEMENTED_StmtMatch
```
## Ruff Output
```py
# Cases sampled from Lib/test/test_patma.py
# case black_test_patma_098
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_142
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_073
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_006
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_049
NOT_YET_IMPLEMENTED_StmtMatch
# case black_check_sequence_then_mapping
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_035
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_107
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_097
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_007
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_154
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_134
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_185
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_063
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_248
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_019
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_052
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_191
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_110
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_151
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_114
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_232
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_058
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_233
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_078
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_156
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_189
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_042
NOT_YET_IMPLEMENTED_StmtMatch
# case black_test_patma_034
NOT_YET_IMPLEMENTED_StmtMatch
```
## Black Output
```py
# Cases sampled from Lib/test/test_patma.py
# case black_test_patma_098
match x:
case -0j:
y = 0
# case black_test_patma_142
match x:
case bytes(z):
y = 0
# case black_test_patma_073
match x:
case 0 if 0:
y = 0
case 0 if 1:
y = 1
# case black_test_patma_006
match 3:
case 0 | 1 | 2 | 3:
x = True
# case black_test_patma_049
match x:
case [0, 1] | [1, 0]:
y = 0
# case black_check_sequence_then_mapping
match x:
case [*_]:
return "seq"
case {}:
return "map"
# case black_test_patma_035
match x:
case {0: [1, 2, {}]}:
y = 0
case {0: [1, 2, {}] | True} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
y = 1
case []:
y = 2
# case black_test_patma_107
match x:
case 0.25 + 1.75j:
y = 0
# case black_test_patma_097
match x:
case -0j:
y = 0
# case black_test_patma_007
match 4:
case 0 | 1 | 2 | 3:
x = True
# case black_test_patma_154
match x:
case 0 if x:
y = 0
# case black_test_patma_134
match x:
case {1: 0}:
y = 0
case {0: 0}:
y = 1
case {**z}:
y = 2
# case black_test_patma_185
match Seq():
case [*_]:
y = 0
# case black_test_patma_063
match x:
case 1:
y = 0
case 1:
y = 1
# case black_test_patma_248
match x:
case {"foo": bar}:
y = bar
# case black_test_patma_019
match (0, 1, 2):
case [0, 1, *x, 2]:
y = 0
# case black_test_patma_052
match x:
case [0]:
y = 0
case [1, 0] if (x := x[:0]):
y = 1
case [1, 0]:
y = 2
# case black_test_patma_191
match w:
case [x, y, *_]:
z = 0
# case black_test_patma_110
match x:
case -0.25 - 1.75j:
y = 0
# case black_test_patma_151
match (x,):
case [y]:
z = 0
# case black_test_patma_114
match x:
case A.B.C.D:
y = 0
# case black_test_patma_232
match x:
case None:
y = 0
# case black_test_patma_058
match x:
case 0:
y = 0
# case black_test_patma_233
match x:
case False:
y = 0
# case black_test_patma_078
match x:
case []:
y = 0
case [""]:
y = 1
case "":
y = 2
# case black_test_patma_156
match x:
case z:
y = 0
# case black_test_patma_189
match w:
case [x, y, *rest]:
z = 0
# case black_test_patma_042
match x:
case (0 as z) | (1 as z) | (2 as z) if z == x % 2:
y = 0
# case black_test_patma_034
match x:
case {0: [1, 2, {}]}:
y = 0
case {0: [1, 2, {}] | False} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
y = 1
case []:
y = 2
```

View file

@ -0,0 +1,443 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py
---
## Input
```py
import match
match something:
case [a as b]:
print(b)
case [a as b, c, d, e as f]:
print(f)
case Point(a as b):
print(b)
case Point(int() as x, int() as y):
print(x, y)
match = 1
case: int = re.match(something)
match re.match(case):
case type("match", match):
pass
case match:
pass
def func(match: case, case: match) -> case:
match Something():
case func(match, case):
...
case another:
...
match maybe, multiple:
case perhaps, 5:
pass
case perhaps, 6,:
pass
match more := (than, one), indeed,:
case _, (5, 6):
pass
case [[5], (6)], [7],:
pass
case _:
pass
match a, *b, c:
case [*_]:
assert "seq" == _
case {}:
assert "map" == b
match match(
case,
match(
match, case, match, looooooooooooooooooooooooooooooooooooong, match, case, match
),
case,
):
case case(
match=case,
case=re.match(
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong
),
):
pass
case [a as match]:
pass
case case:
pass
match match:
case case:
pass
match a, *b(), c:
case d, *f, g:
pass
match something:
case {
"key": key as key_1,
"password": PASS.ONE | PASS.TWO | PASS.THREE as password,
}:
pass
case {"maybe": something(complicated as this) as that}:
pass
match something:
case 1 as a:
pass
case 2 as b, 3 as c:
pass
case 4 as d, (5 as e), (6 | 7 as g), *h:
pass
match bar1:
case Foo(aa=Callable() as aa, bb=int()):
print(bar1.aa, bar1.bb)
case _:
print("no match", "\n")
match bar1:
case Foo(
normal=x, perhaps=[list, {"x": d, "y": 1.0}] as y, otherwise=something, q=t as u
):
pass
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,119 +1,43 @@
-import match
+NOT_YET_IMPLEMENTED_StmtImport
-match something:
- case [a as b]:
- print(b)
- case [a as b, c, d, e as f]:
- print(f)
- case Point(a as b):
- print(b)
- case Point(int() as x, int() as y):
- print(x, y)
+NOT_YET_IMPLEMENTED_StmtMatch
match = 1
-case: int = re.match(something)
+NOT_YET_IMPLEMENTED_StmtAnnAssign
-match re.match(case):
- case type("match", match):
- pass
- case match:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
def func(match: case, case: match) -> case:
- match Something():
- case func(match, case):
- ...
- case another:
- ...
+ NOT_YET_IMPLEMENTED_StmtMatch
-match maybe, multiple:
- case perhaps, 5:
- pass
- case perhaps, 6,:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match more := (than, one), indeed,:
- case _, (5, 6):
- pass
- case [[5], (6)], [7],:
- pass
- case _:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match a, *b, c:
- case [*_]:
- assert "seq" == _
- case {}:
- assert "map" == b
+NOT_YET_IMPLEMENTED_StmtMatch
-match match(
- case,
- match(
- match, case, match, looooooooooooooooooooooooooooooooooooong, match, case, match
- ),
- case,
-):
- case case(
- match=case,
- case=re.match(
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong
- ),
- ):
- pass
-
- case [a as match]:
- pass
-
- case case:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match match:
- case case:
- pass
-
-
-match a, *b(), c:
- case d, *f, g:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match something:
- case {
- "key": key as key_1,
- "password": PASS.ONE | PASS.TWO | PASS.THREE as password,
- }:
- pass
- case {"maybe": something(complicated as this) as that}:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match something:
- case 1 as a:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
- case 2 as b, 3 as c:
- pass
- case 4 as d, (5 as e), (6 | 7 as g), *h:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match bar1:
- case Foo(aa=Callable() as aa, bb=int()):
- print(bar1.aa, bar1.bb)
- case _:
- print("no match", "\n")
+NOT_YET_IMPLEMENTED_StmtMatch
-match bar1:
- case Foo(
- normal=x, perhaps=[list, {"x": d, "y": 1.0}] as y, otherwise=something, q=t as u
- ):
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
```
## Ruff Output
```py
NOT_YET_IMPLEMENTED_StmtImport
NOT_YET_IMPLEMENTED_StmtMatch
match = 1
NOT_YET_IMPLEMENTED_StmtAnnAssign
NOT_YET_IMPLEMENTED_StmtMatch
def func(match: case, case: match) -> case:
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
```
## Black Output
```py
import match
match something:
case [a as b]:
print(b)
case [a as b, c, d, e as f]:
print(f)
case Point(a as b):
print(b)
case Point(int() as x, int() as y):
print(x, y)
match = 1
case: int = re.match(something)
match re.match(case):
case type("match", match):
pass
case match:
pass
def func(match: case, case: match) -> case:
match Something():
case func(match, case):
...
case another:
...
match maybe, multiple:
case perhaps, 5:
pass
case perhaps, 6,:
pass
match more := (than, one), indeed,:
case _, (5, 6):
pass
case [[5], (6)], [7],:
pass
case _:
pass
match a, *b, c:
case [*_]:
assert "seq" == _
case {}:
assert "map" == b
match match(
case,
match(
match, case, match, looooooooooooooooooooooooooooooooooooong, match, case, match
),
case,
):
case case(
match=case,
case=re.match(
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong
),
):
pass
case [a as match]:
pass
case case:
pass
match match:
case case:
pass
match a, *b(), c:
case d, *f, g:
pass
match something:
case {
"key": key as key_1,
"password": PASS.ONE | PASS.TWO | PASS.THREE as password,
}:
pass
case {"maybe": something(complicated as this) as that}:
pass
match something:
case 1 as a:
pass
case 2 as b, 3 as c:
pass
case 4 as d, (5 as e), (6 | 7 as g), *h:
pass
match bar1:
case Foo(aa=Callable() as aa, bb=int()):
print(bar1.aa, bar1.bb)
case _:
print("no match", "\n")
match bar1:
case Foo(
normal=x, perhaps=[list, {"x": d, "y": 1.0}] as y, otherwise=something, q=t as u
):
pass
```

View file

@ -0,0 +1,425 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_generic.py
---
## Input
```py
re.match()
match = a
with match() as match:
match = f"{match}"
re.match()
match = a
with match() as match:
match = f"{match}"
def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
if not target_versions:
# No target_version specified, so try all grammars.
return [
# Python 3.7+
pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords,
# Python 3.0-3.6
pygram.python_grammar_no_print_statement_no_exec_statement,
# Python 2.7 with future print_function import
pygram.python_grammar_no_print_statement,
# Python 2.7
pygram.python_grammar,
]
match match:
case case:
match match:
case case:
pass
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
pygram.python_grammar_no_print_statement,
# Python 2.7
pygram.python_grammar,
]
re.match()
match = a
with match() as match:
match = f"{match}"
def test_patma_139(self):
x = False
match x:
case bool(z):
y = 0
self.assertIs(x, False)
self.assertEqual(y, 0)
self.assertIs(z, x)
# Python 3-compatible code, so only try Python 3 grammar.
grammars = []
if supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.10+
grammars.append(pygram.python_grammar_soft_keywords)
# If we have to parse both, try to parse async as a keyword first
if not supports_feature(
target_versions, Feature.ASYNC_IDENTIFIERS
) and not supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.7-3.9
grammars.append(
pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords
)
if not supports_feature(target_versions, Feature.ASYNC_KEYWORDS):
# Python 3.0-3.6
grammars.append(pygram.python_grammar_no_print_statement_no_exec_statement)
def test_patma_155(self):
x = 0
y = None
match x:
case 1e1000:
y = 0
self.assertEqual(x, 0)
self.assertIs(y, None)
x = range(3)
match x:
case [y, case as x, z]:
w = 0
# At least one of the above branches must have been taken, because every Python
# version has exactly one of the two 'ASYNC_*' flags
return grammars
def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node:
"""Given a string with source, return the lib2to3 Node."""
if not src_txt.endswith("\n"):
src_txt += "\n"
grammars = get_grammars(set(target_versions))
re.match()
match = a
with match() as match:
match = f"{match}"
re.match()
match = a
with match() as match:
match = f"{match}"
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,12 +1,12 @@
re.match()
match = a
with match() as match:
- match = f"{match}"
+ match = NOT_YET_IMPLEMENTED_ExprJoinedStr
re.match()
match = a
with match() as match:
- match = f"{match}"
+ match = NOT_YET_IMPLEMENTED_ExprJoinedStr
def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
@@ -23,13 +23,9 @@
pygram.python_grammar,
]
- match match:
- case case:
- match match:
- case case:
- pass
+ NOT_YET_IMPLEMENTED_StmtMatch
- if all(version.is_python2() for version in target_versions):
+ if all((i for i in [])):
# Python 2-only code, so try Python 2 grammars.
return [
# Python 2.7 with future print_function import
@@ -41,13 +37,11 @@
re.match()
match = a
with match() as match:
- match = f"{match}"
+ match = NOT_YET_IMPLEMENTED_ExprJoinedStr
def test_patma_139(self):
x = False
- match x:
- case bool(z):
- y = 0
+ NOT_YET_IMPLEMENTED_StmtMatch
self.assertIs(x, False)
self.assertEqual(y, 0)
self.assertIs(z, x)
@@ -72,16 +66,12 @@
def test_patma_155(self):
x = 0
y = None
- match x:
- case 1e1000:
- y = 0
+ NOT_YET_IMPLEMENTED_StmtMatch
self.assertEqual(x, 0)
self.assertIs(y, None)
x = range(3)
- match x:
- case [y, case as x, z]:
- w = 0
+ NOT_YET_IMPLEMENTED_StmtMatch
# At least one of the above branches must have been taken, because every Python
# version has exactly one of the two 'ASYNC_*' flags
@@ -91,7 +81,7 @@
def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node:
"""Given a string with source, return the lib2to3 Node."""
if not src_txt.endswith("\n"):
- src_txt += "\n"
+ NOT_YET_IMPLEMENTED_StmtAugAssign
grammars = get_grammars(set(target_versions))
@@ -99,9 +89,9 @@
re.match()
match = a
with match() as match:
- match = f"{match}"
+ match = NOT_YET_IMPLEMENTED_ExprJoinedStr
re.match()
match = a
with match() as match:
- match = f"{match}"
+ match = NOT_YET_IMPLEMENTED_ExprJoinedStr
```
## Ruff Output
```py
re.match()
match = a
with match() as match:
match = NOT_YET_IMPLEMENTED_ExprJoinedStr
re.match()
match = a
with match() as match:
match = NOT_YET_IMPLEMENTED_ExprJoinedStr
def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
if not target_versions:
# No target_version specified, so try all grammars.
return [
# Python 3.7+
pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords,
# Python 3.0-3.6
pygram.python_grammar_no_print_statement_no_exec_statement,
# Python 2.7 with future print_function import
pygram.python_grammar_no_print_statement,
# Python 2.7
pygram.python_grammar,
]
NOT_YET_IMPLEMENTED_StmtMatch
if all((i for i in [])):
# Python 2-only code, so try Python 2 grammars.
return [
# Python 2.7 with future print_function import
pygram.python_grammar_no_print_statement,
# Python 2.7
pygram.python_grammar,
]
re.match()
match = a
with match() as match:
match = NOT_YET_IMPLEMENTED_ExprJoinedStr
def test_patma_139(self):
x = False
NOT_YET_IMPLEMENTED_StmtMatch
self.assertIs(x, False)
self.assertEqual(y, 0)
self.assertIs(z, x)
# Python 3-compatible code, so only try Python 3 grammar.
grammars = []
if supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.10+
grammars.append(pygram.python_grammar_soft_keywords)
# If we have to parse both, try to parse async as a keyword first
if not supports_feature(
target_versions, Feature.ASYNC_IDENTIFIERS
) and not supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.7-3.9
grammars.append(
pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords
)
if not supports_feature(target_versions, Feature.ASYNC_KEYWORDS):
# Python 3.0-3.6
grammars.append(pygram.python_grammar_no_print_statement_no_exec_statement)
def test_patma_155(self):
x = 0
y = None
NOT_YET_IMPLEMENTED_StmtMatch
self.assertEqual(x, 0)
self.assertIs(y, None)
x = range(3)
NOT_YET_IMPLEMENTED_StmtMatch
# At least one of the above branches must have been taken, because every Python
# version has exactly one of the two 'ASYNC_*' flags
return grammars
def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node:
"""Given a string with source, return the lib2to3 Node."""
if not src_txt.endswith("\n"):
NOT_YET_IMPLEMENTED_StmtAugAssign
grammars = get_grammars(set(target_versions))
re.match()
match = a
with match() as match:
match = NOT_YET_IMPLEMENTED_ExprJoinedStr
re.match()
match = a
with match() as match:
match = NOT_YET_IMPLEMENTED_ExprJoinedStr
```
## Black Output
```py
re.match()
match = a
with match() as match:
match = f"{match}"
re.match()
match = a
with match() as match:
match = f"{match}"
def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
if not target_versions:
# No target_version specified, so try all grammars.
return [
# Python 3.7+
pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords,
# Python 3.0-3.6
pygram.python_grammar_no_print_statement_no_exec_statement,
# Python 2.7 with future print_function import
pygram.python_grammar_no_print_statement,
# Python 2.7
pygram.python_grammar,
]
match match:
case case:
match match:
case case:
pass
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
pygram.python_grammar_no_print_statement,
# Python 2.7
pygram.python_grammar,
]
re.match()
match = a
with match() as match:
match = f"{match}"
def test_patma_139(self):
x = False
match x:
case bool(z):
y = 0
self.assertIs(x, False)
self.assertEqual(y, 0)
self.assertIs(z, x)
# Python 3-compatible code, so only try Python 3 grammar.
grammars = []
if supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.10+
grammars.append(pygram.python_grammar_soft_keywords)
# If we have to parse both, try to parse async as a keyword first
if not supports_feature(
target_versions, Feature.ASYNC_IDENTIFIERS
) and not supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.7-3.9
grammars.append(
pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords
)
if not supports_feature(target_versions, Feature.ASYNC_KEYWORDS):
# Python 3.0-3.6
grammars.append(pygram.python_grammar_no_print_statement_no_exec_statement)
def test_patma_155(self):
x = 0
y = None
match x:
case 1e1000:
y = 0
self.assertEqual(x, 0)
self.assertIs(y, None)
x = range(3)
match x:
case [y, case as x, z]:
w = 0
# At least one of the above branches must have been taken, because every Python
# version has exactly one of the two 'ASYNC_*' flags
return grammars
def lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) -> Node:
"""Given a string with source, return the lib2to3 Node."""
if not src_txt.endswith("\n"):
src_txt += "\n"
grammars = get_grammars(set(target_versions))
re.match()
match = a
with match() as match:
match = f"{match}"
re.match()
match = a
with match() as match:
match = f"{match}"
```

View file

@ -0,0 +1,343 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_simple.py
---
## Input
```py
# Cases sampled from PEP 636 examples
match command.split():
case [action, obj]:
... # interpret action, obj
match command.split():
case [action]:
... # interpret single-verb action
case [action, obj]:
... # interpret action, obj
match command.split():
case ["quit"]:
print("Goodbye!")
quit_game()
case ["look"]:
current_room.describe()
case ["get", obj]:
character.get(obj, current_room)
case ["go", direction]:
current_room = current_room.neighbor(direction)
# The rest of your commands go here
match command.split():
case ["drop", *objects]:
for obj in objects:
character.drop(obj, current_room)
# The rest of your commands go here
match command.split():
case ["quit"]:
pass
case ["go", direction]:
print("Going:", direction)
case ["drop", *objects]:
print("Dropping: ", *objects)
case _:
print(f"Sorry, I couldn't understand {command!r}")
match command.split():
case ["north"] | ["go", "north"]:
current_room = current_room.neighbor("north")
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
... # Code for picking up the given object
match command.split():
case ["go", ("north" | "south" | "east" | "west")]:
current_room = current_room.neighbor(...)
# how do I know which direction to go?
match command.split():
case ["go", ("north" | "south" | "east" | "west") as direction]:
current_room = current_room.neighbor(direction)
match command.split():
case ["go", direction] if direction in current_room.exits:
current_room = current_room.neighbor(direction)
case ["go", _]:
print("Sorry, you can't go that way")
match event.get():
case Click(position=(x, y)):
handle_click_at(x, y)
case KeyPress(key_name="Q") | Quit():
game.quit()
case KeyPress(key_name="up arrow"):
game.go_north()
case KeyPress():
pass # Ignore other keystrokes
case other_event:
raise ValueError(f"Unrecognized event: {other_event}")
match event.get():
case Click((x, y), button=Button.LEFT): # This is a left click
handle_click_at(x, y)
case Click():
pass # ignore other clicks
def where_is(point):
match point:
case Point(x=0, y=0):
print("Origin")
case Point(x=0, y=y):
print(f"Y={y}")
case Point(x=x, y=0):
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,92 +1,27 @@
# Cases sampled from PEP 636 examples
-match command.split():
- case [action, obj]:
- ... # interpret action, obj
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case [action]:
- ... # interpret single-verb action
- case [action, obj]:
- ... # interpret action, obj
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["quit"]:
- print("Goodbye!")
- quit_game()
- case ["look"]:
- current_room.describe()
- case ["get", obj]:
- character.get(obj, current_room)
- case ["go", direction]:
- current_room = current_room.neighbor(direction)
- # The rest of your commands go here
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["drop", *objects]:
- for obj in objects:
- character.drop(obj, current_room)
- # The rest of your commands go here
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["quit"]:
- pass
- case ["go", direction]:
- print("Going:", direction)
- case ["drop", *objects]:
- print("Dropping: ", *objects)
- case _:
- print(f"Sorry, I couldn't understand {command!r}")
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["north"] | ["go", "north"]:
- current_room = current_room.neighbor("north")
- case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
- ... # Code for picking up the given object
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["go", ("north" | "south" | "east" | "west")]:
- current_room = current_room.neighbor(...)
- # how do I know which direction to go?
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["go", ("north" | "south" | "east" | "west") as direction]:
- current_room = current_room.neighbor(direction)
+NOT_YET_IMPLEMENTED_StmtMatch
-match command.split():
- case ["go", direction] if direction in current_room.exits:
- current_room = current_room.neighbor(direction)
- case ["go", _]:
- print("Sorry, you can't go that way")
+NOT_YET_IMPLEMENTED_StmtMatch
-match event.get():
- case Click(position=(x, y)):
- handle_click_at(x, y)
- case KeyPress(key_name="Q") | Quit():
- game.quit()
- case KeyPress(key_name="up arrow"):
- game.go_north()
- case KeyPress():
- pass # Ignore other keystrokes
- case other_event:
- raise ValueError(f"Unrecognized event: {other_event}")
+NOT_YET_IMPLEMENTED_StmtMatch
-match event.get():
- case Click((x, y), button=Button.LEFT): # This is a left click
- handle_click_at(x, y)
- case Click():
- pass # ignore other clicks
+NOT_YET_IMPLEMENTED_StmtMatch
def where_is(point):
- match point:
- case Point(x=0, y=0):
- print("Origin")
- case Point(x=0, y=y):
- print(f"Y={y}")
- case Point(x=x, y=0):
- print(f"X={x}")
- case Point():
- print("Somewhere else")
- case _:
- print("Not a point")
+ NOT_YET_IMPLEMENTED_StmtMatch
```
## Ruff Output
```py
# Cases sampled from PEP 636 examples
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
NOT_YET_IMPLEMENTED_StmtMatch
def where_is(point):
NOT_YET_IMPLEMENTED_StmtMatch
```
## Black Output
```py
# Cases sampled from PEP 636 examples
match command.split():
case [action, obj]:
... # interpret action, obj
match command.split():
case [action]:
... # interpret single-verb action
case [action, obj]:
... # interpret action, obj
match command.split():
case ["quit"]:
print("Goodbye!")
quit_game()
case ["look"]:
current_room.describe()
case ["get", obj]:
character.get(obj, current_room)
case ["go", direction]:
current_room = current_room.neighbor(direction)
# The rest of your commands go here
match command.split():
case ["drop", *objects]:
for obj in objects:
character.drop(obj, current_room)
# The rest of your commands go here
match command.split():
case ["quit"]:
pass
case ["go", direction]:
print("Going:", direction)
case ["drop", *objects]:
print("Dropping: ", *objects)
case _:
print(f"Sorry, I couldn't understand {command!r}")
match command.split():
case ["north"] | ["go", "north"]:
current_room = current_room.neighbor("north")
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
... # Code for picking up the given object
match command.split():
case ["go", ("north" | "south" | "east" | "west")]:
current_room = current_room.neighbor(...)
# how do I know which direction to go?
match command.split():
case ["go", ("north" | "south" | "east" | "west") as direction]:
current_room = current_room.neighbor(direction)
match command.split():
case ["go", direction] if direction in current_room.exits:
current_room = current_room.neighbor(direction)
case ["go", _]:
print("Sorry, you can't go that way")
match event.get():
case Click(position=(x, y)):
handle_click_at(x, y)
case KeyPress(key_name="Q") | Quit():
game.quit()
case KeyPress(key_name="up arrow"):
game.go_north()
case KeyPress():
pass # Ignore other keystrokes
case other_event:
raise ValueError(f"Unrecognized event: {other_event}")
match event.get():
case Click((x, y), button=Button.LEFT): # This is a left click
handle_click_at(x, y)
case Click():
pass # ignore other clicks
def where_is(point):
match point:
case Point(x=0, y=0):
print("Origin")
case Point(x=0, y=y):
print(f"Y={y}")
case Point(x=x, y=0):
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
```

View file

@ -0,0 +1,186 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_style.py
---
## Input
```py
match something:
case b(): print(1+1)
case c(
very_complex=True,
perhaps_even_loooooooooooooooooooooooooooooooooooooong=- 1
): print(1)
case c(
very_complex=True,
perhaps_even_loooooooooooooooooooooooooooooooooooooong=-1,
): print(2)
case a: pass
match(
arg # comment
)
match(
)
match(
)
case(
arg # comment
)
case(
)
case(
)
re.match(
something # fast
)
re.match(
)
match match(
):
case case(
arg, # comment
):
pass
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,35 +1,24 @@
-match something:
- case b():
- print(1 + 1)
- case c(
- very_complex=True, perhaps_even_loooooooooooooooooooooooooooooooooooooong=-1
- ):
- print(1)
- case c(
- very_complex=True,
- perhaps_even_loooooooooooooooooooooooooooooooooooooong=-1,
- ):
- print(2)
- case a:
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
-match(arg) # comment
+match(
+ arg, # comment
+)
match()
match()
-case(arg) # comment
+case(
+ arg, # comment
+)
case()
case()
-re.match(something) # fast
+re.match(
+ something, # fast
+)
re.match()
-match match():
- case case(
- arg, # comment
- ):
- pass
+NOT_YET_IMPLEMENTED_StmtMatch
```
## Ruff Output
```py
NOT_YET_IMPLEMENTED_StmtMatch
match(
arg, # comment
)
match()
match()
case(
arg, # comment
)
case()
case()
re.match(
something, # fast
)
re.match()
NOT_YET_IMPLEMENTED_StmtMatch
```
## Black Output
```py
match something:
case b():
print(1 + 1)
case c(
very_complex=True, perhaps_even_loooooooooooooooooooooooooooooooooooooong=-1
):
print(1)
case c(
very_complex=True,
perhaps_even_loooooooooooooooooooooooooooooooooooooong=-1,
):
print(2)
case a:
pass
match(arg) # comment
match()
match()
case(arg) # comment
case()
case()
re.match(something) # fast
re.match()
match match():
case case(
arg, # comment
):
pass
```

View file

@ -0,0 +1,96 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pep_572_py310.py
---
## Input
```py
# Unparenthesized walruses are now allowed in indices since Python 3.10.
x[a:=0]
x[a:=0, b:=1]
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 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)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,15 +1,15 @@
# Unparenthesized walruses are now allowed in indices since Python 3.10.
-x[a:=0]
-x[a:=0, b:=1]
-x[5, b:=0]
+x[NOT_YET_IMPLEMENTED_ExprNamedExpr]
+x[NOT_YET_IMPLEMENTED_ExprNamedExpr, NOT_YET_IMPLEMENTED_ExprNamedExpr]
+x[5, NOT_YET_IMPLEMENTED_ExprNamedExpr]
# 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((i for i 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((i for i in []))
+f((i for i in []), x)
+f(y=(i for i in []))
+f(x, (i for i in []), y=z, **q)
```
## Ruff Output
```py
# Unparenthesized walruses are now allowed in indices since Python 3.10.
x[NOT_YET_IMPLEMENTED_ExprNamedExpr]
x[NOT_YET_IMPLEMENTED_ExprNamedExpr, NOT_YET_IMPLEMENTED_ExprNamedExpr]
x[5, NOT_YET_IMPLEMENTED_ExprNamedExpr]
# Walruses are allowed inside generator expressions on function calls since 3.10.
if any((i for i in [])):
if match.group(2) == data_not_available:
# Error OK to ignore.
pass
f((i for i in []))
f((i for i in []), x)
f(y=(i for i in []))
f(x, (i for i in []), y=z, **q)
```
## Black Output
```py
# Unparenthesized walruses are now allowed in indices since Python 3.10.
x[a:=0]
x[a:=0, b:=1]
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 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)
```

View file

@ -0,0 +1,76 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/remove_newline_after_match.py
---
## Input
```py
def http_status(status):
match status:
case 400:
return "Bad request"
case 401:
return "Unauthorized"
case 403:
return "Forbidden"
case 404:
return "Not found"
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,13 +1,2 @@
def http_status(status):
- match status:
- case 400:
- return "Bad request"
-
- case 401:
- return "Unauthorized"
-
- case 403:
- return "Forbidden"
-
- case 404:
- return "Not found"
+ NOT_YET_IMPLEMENTED_StmtMatch
```
## Ruff Output
```py
def http_status(status):
NOT_YET_IMPLEMENTED_StmtMatch
```
## Black Output
```py
def http_status(status):
match status:
case 400:
return "Bad request"
case 401:
return "Unauthorized"
case 403:
return "Forbidden"
case 404:
return "Not found"
```

View file

@ -0,0 +1,136 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/starred_for_target.py
---
## Input
```py
for x in *a, *b:
print(x)
for x in a, b, *c:
print(x)
for x in *a, b, c:
print(x)
for x in *a, b, *c:
print(x)
async for x in *a, *b:
print(x)
async for x in *a, b, *c:
print(x)
async for x in a, b, *c:
print(x)
async for x in (
*loooooooooooooooooooooong,
very,
*loooooooooooooooooooooooooooooooooooooooooooooooong,
):
print(x)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,27 +1,19 @@
-for x in *a, *b:
+for x in *NOT_YET_IMPLEMENTED_ExprStarred, *NOT_YET_IMPLEMENTED_ExprStarred:
print(x)
-for x in a, b, *c:
+for x in a, b, *NOT_YET_IMPLEMENTED_ExprStarred:
print(x)
-for x in *a, b, c:
+for x in *NOT_YET_IMPLEMENTED_ExprStarred, b, c:
print(x)
-for x in *a, b, *c:
+for x in *NOT_YET_IMPLEMENTED_ExprStarred, b, *NOT_YET_IMPLEMENTED_ExprStarred:
print(x)
-async for x in *a, *b:
- print(x)
+NOT_YET_IMPLEMENTED_StmtAsyncFor
-async for x in *a, b, *c:
- print(x)
+NOT_YET_IMPLEMENTED_StmtAsyncFor
-async for x in a, b, *c:
- print(x)
+NOT_YET_IMPLEMENTED_StmtAsyncFor
-async for x in (
- *loooooooooooooooooooooong,
- very,
- *loooooooooooooooooooooooooooooooooooooooooooooooong,
-):
- print(x)
+NOT_YET_IMPLEMENTED_StmtAsyncFor
```
## Ruff Output
```py
for x in *NOT_YET_IMPLEMENTED_ExprStarred, *NOT_YET_IMPLEMENTED_ExprStarred:
print(x)
for x in a, b, *NOT_YET_IMPLEMENTED_ExprStarred:
print(x)
for x in *NOT_YET_IMPLEMENTED_ExprStarred, b, c:
print(x)
for x in *NOT_YET_IMPLEMENTED_ExprStarred, b, *NOT_YET_IMPLEMENTED_ExprStarred:
print(x)
NOT_YET_IMPLEMENTED_StmtAsyncFor
NOT_YET_IMPLEMENTED_StmtAsyncFor
NOT_YET_IMPLEMENTED_StmtAsyncFor
NOT_YET_IMPLEMENTED_StmtAsyncFor
```
## Black Output
```py
for x in *a, *b:
print(x)
for x in a, b, *c:
print(x)
for x in *a, b, c:
print(x)
for x in *a, b, *c:
print(x)
async for x in *a, *b:
print(x)
async for x in *a, b, *c:
print(x)
async for x in a, b, *c:
print(x)
async for x in (
*loooooooooooooooooooooong,
very,
*loooooooooooooooooooooooooooooooooooooooooooooooong,
):
print(x)
```

View file

@ -0,0 +1,240 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654.py
---
## Input
```py
try:
raise OSError("blah")
except* ExceptionGroup as e:
pass
try:
async with trio.open_nursery() as nursery:
# Make two concurrent calls to child()
nursery.start_soon(child)
nursery.start_soon(child)
except* ValueError:
pass
try:
try:
raise ValueError(42)
except:
try:
raise TypeError(int)
except* Exception:
pass
1 / 0
except Exception as e:
exc = e
try:
try:
raise FalsyEG("eg", [TypeError(1), ValueError(2)])
except* TypeError as e:
tes = e
raise
except* ValueError as e:
ves = e
pass
except Exception as e:
exc = e
try:
try:
raise orig
except* (TypeError, ValueError) as e:
raise SyntaxError(3) from e
except BaseException as e:
exc = e
try:
try:
raise orig
except* OSError as e:
raise TypeError(3) from e
except ExceptionGroup as e:
exc = e
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,5 +1,5 @@
try:
- raise OSError("blah")
+ NOT_YET_IMPLEMENTED_StmtRaise
except* ExceptionGroup as e:
pass
@@ -14,10 +14,10 @@
try:
try:
- raise ValueError(42)
+ NOT_YET_IMPLEMENTED_StmtRaise
except:
try:
- raise TypeError(int)
+ NOT_YET_IMPLEMENTED_StmtRaise
except* Exception:
pass
1 / 0
@@ -26,10 +26,10 @@
try:
try:
- raise FalsyEG("eg", [TypeError(1), ValueError(2)])
+ NOT_YET_IMPLEMENTED_StmtRaise
except* TypeError as e:
tes = e
- raise
+ NOT_YET_IMPLEMENTED_StmtRaise
except* ValueError as e:
ves = e
pass
@@ -38,16 +38,16 @@
try:
try:
- raise orig
+ NOT_YET_IMPLEMENTED_StmtRaise
except* (TypeError, ValueError) as e:
- raise SyntaxError(3) from e
+ NOT_YET_IMPLEMENTED_StmtRaise
except BaseException as e:
exc = e
try:
try:
- raise orig
+ NOT_YET_IMPLEMENTED_StmtRaise
except* OSError as e:
- raise TypeError(3) from e
+ NOT_YET_IMPLEMENTED_StmtRaise
except ExceptionGroup as e:
exc = e
```
## Ruff Output
```py
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* ExceptionGroup as e:
pass
try:
async with trio.open_nursery() as nursery:
# Make two concurrent calls to child()
nursery.start_soon(child)
nursery.start_soon(child)
except* ValueError:
pass
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* Exception:
pass
1 / 0
except Exception as e:
exc = e
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* TypeError as e:
tes = e
NOT_YET_IMPLEMENTED_StmtRaise
except* ValueError as e:
ves = e
pass
except Exception as e:
exc = e
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* (TypeError, ValueError) as e:
NOT_YET_IMPLEMENTED_StmtRaise
except BaseException as e:
exc = e
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* OSError as e:
NOT_YET_IMPLEMENTED_StmtRaise
except ExceptionGroup as e:
exc = e
```
## Black Output
```py
try:
raise OSError("blah")
except* ExceptionGroup as e:
pass
try:
async with trio.open_nursery() as nursery:
# Make two concurrent calls to child()
nursery.start_soon(child)
nursery.start_soon(child)
except* ValueError:
pass
try:
try:
raise ValueError(42)
except:
try:
raise TypeError(int)
except* Exception:
pass
1 / 0
except Exception as e:
exc = e
try:
try:
raise FalsyEG("eg", [TypeError(1), ValueError(2)])
except* TypeError as e:
tes = e
raise
except* ValueError as e:
ves = e
pass
except Exception as e:
exc = e
try:
try:
raise orig
except* (TypeError, ValueError) as e:
raise SyntaxError(3) from e
except BaseException as e:
exc = e
try:
try:
raise orig
except* OSError as e:
raise TypeError(3) from e
except ExceptionGroup as e:
exc = e
```

View file

@ -0,0 +1,243 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654_style.py
---
## Input
```py
try:
raise OSError("blah")
except * ExceptionGroup as e:
pass
try:
async with trio.open_nursery() as nursery:
# Make two concurrent calls to child()
nursery.start_soon(child)
nursery.start_soon(child)
except *ValueError:
pass
try:
try:
raise ValueError(42)
except:
try:
raise TypeError(int)
except *(Exception):
pass
1 / 0
except Exception as e:
exc = e
try:
try:
raise FalsyEG("eg", [TypeError(1), ValueError(2)])
except \
*TypeError as e:
tes = e
raise
except * ValueError as e:
ves = e
pass
except Exception as e:
exc = e
try:
try:
raise orig
except *(TypeError, ValueError, *OTHER_EXCEPTIONS) as e:
raise SyntaxError(3) from e
except BaseException as e:
exc = e
try:
try:
raise orig
except\
* OSError as e:
raise TypeError(3) from e
except ExceptionGroup as e:
exc = e
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,5 +1,5 @@
try:
- raise OSError("blah")
+ NOT_YET_IMPLEMENTED_StmtRaise
except* ExceptionGroup as e:
pass
@@ -14,10 +14,10 @@
try:
try:
- raise ValueError(42)
+ NOT_YET_IMPLEMENTED_StmtRaise
except:
try:
- raise TypeError(int)
+ NOT_YET_IMPLEMENTED_StmtRaise
except* Exception:
pass
1 / 0
@@ -26,10 +26,10 @@
try:
try:
- raise FalsyEG("eg", [TypeError(1), ValueError(2)])
+ NOT_YET_IMPLEMENTED_StmtRaise
except* TypeError as e:
tes = e
- raise
+ NOT_YET_IMPLEMENTED_StmtRaise
except* ValueError as e:
ves = e
pass
@@ -38,16 +38,16 @@
try:
try:
- raise orig
- except* (TypeError, ValueError, *OTHER_EXCEPTIONS) as e:
- raise SyntaxError(3) from e
+ NOT_YET_IMPLEMENTED_StmtRaise
+ except* (TypeError, ValueError, *NOT_YET_IMPLEMENTED_ExprStarred) as e:
+ NOT_YET_IMPLEMENTED_StmtRaise
except BaseException as e:
exc = e
try:
try:
- raise orig
+ NOT_YET_IMPLEMENTED_StmtRaise
except* OSError as e:
- raise TypeError(3) from e
+ NOT_YET_IMPLEMENTED_StmtRaise
except ExceptionGroup as e:
exc = e
```
## Ruff Output
```py
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* ExceptionGroup as e:
pass
try:
async with trio.open_nursery() as nursery:
# Make two concurrent calls to child()
nursery.start_soon(child)
nursery.start_soon(child)
except* ValueError:
pass
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* Exception:
pass
1 / 0
except Exception as e:
exc = e
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* TypeError as e:
tes = e
NOT_YET_IMPLEMENTED_StmtRaise
except* ValueError as e:
ves = e
pass
except Exception as e:
exc = e
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* (TypeError, ValueError, *NOT_YET_IMPLEMENTED_ExprStarred) as e:
NOT_YET_IMPLEMENTED_StmtRaise
except BaseException as e:
exc = e
try:
try:
NOT_YET_IMPLEMENTED_StmtRaise
except* OSError as e:
NOT_YET_IMPLEMENTED_StmtRaise
except ExceptionGroup as e:
exc = e
```
## Black Output
```py
try:
raise OSError("blah")
except* ExceptionGroup as e:
pass
try:
async with trio.open_nursery() as nursery:
# Make two concurrent calls to child()
nursery.start_soon(child)
nursery.start_soon(child)
except* ValueError:
pass
try:
try:
raise ValueError(42)
except:
try:
raise TypeError(int)
except* Exception:
pass
1 / 0
except Exception as e:
exc = e
try:
try:
raise FalsyEG("eg", [TypeError(1), ValueError(2)])
except* TypeError as e:
tes = e
raise
except* ValueError as e:
ves = e
pass
except Exception as e:
exc = e
try:
try:
raise orig
except* (TypeError, ValueError, *OTHER_EXCEPTIONS) as e:
raise SyntaxError(3) from e
except BaseException as e:
exc = e
try:
try:
raise orig
except* OSError as e:
raise TypeError(3) from e
except ExceptionGroup as e:
exc = e
```

View file

@ -0,0 +1,118 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py
---
## Input
```py
#!/usr/bin/env python3.6
x = 123456789
x = 123456
x = .1
x = 1.
x = 1E+1
x = 1E-1
x = 1.000_000_01
x = 123456789.123456789
x = 123456789.123456789E123456789
x = 123456789E123456789
x = 123456789J
x = 123456789.123456789J
x = 0XB1ACC
x = 0B1011
x = 0O777
x = 0.000000006
x = 10000
x = 133333
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -2,19 +2,19 @@
x = 123456789
x = 123456
-x = 0.1
-x = 1.0
-x = 1e1
-x = 1e-1
+x = .1
+x = 1.
+x = 1E+1
+x = 1E-1
x = 1.000_000_01
x = 123456789.123456789
-x = 123456789.123456789e123456789
-x = 123456789e123456789
-x = 123456789j
-x = 123456789.123456789j
-x = 0xB1ACC
-x = 0b1011
-x = 0o777
+x = 123456789.123456789E123456789
+x = 123456789E123456789
+x = 123456789J
+x = 123456789.123456789J
+x = 0XB1ACC
+x = 0B1011
+x = 0O777
x = 0.000000006
x = 10000
x = 133333
```
## Ruff Output
```py
#!/usr/bin/env python3.6
x = 123456789
x = 123456
x = .1
x = 1.
x = 1E+1
x = 1E-1
x = 1.000_000_01
x = 123456789.123456789
x = 123456789.123456789E123456789
x = 123456789E123456789
x = 123456789J
x = 123456789.123456789J
x = 0XB1ACC
x = 0B1011
x = 0O777
x = 0.000000006
x = 10000
x = 133333
```
## Black Output
```py
#!/usr/bin/env python3.6
x = 123456789
x = 123456
x = 0.1
x = 1.0
x = 1e1
x = 1e-1
x = 1.000_000_01
x = 123456789.123456789
x = 123456789.123456789e123456789
x = 123456789e123456789
x = 123456789j
x = 123456789.123456789j
x = 0xB1ACC
x = 0b1011
x = 0o777
x = 0.000000006
x = 10000
x = 133333
```

View file

@ -0,0 +1,72 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py
---
## Input
```py
#!/usr/bin/env python3.6
x = 123456789
x = 1_2_3_4_5_6_7
x = 1E+1
x = 0xb1acc
x = 0.00_00_006
x = 12_34_567J
x = .1_2
x = 1_2.
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -2,9 +2,9 @@
x = 123456789
x = 1_2_3_4_5_6_7
-x = 1e1
-x = 0xB1ACC
+x = 1E+1
+x = 0xb1acc
x = 0.00_00_006
-x = 12_34_567j
-x = 0.1_2
-x = 1_2.0
+x = 12_34_567J
+x = .1_2
+x = 1_2.
```
## Ruff Output
```py
#!/usr/bin/env python3.6
x = 123456789
x = 1_2_3_4_5_6_7
x = 1E+1
x = 0xb1acc
x = 0.00_00_006
x = 12_34_567J
x = .1_2
x = 1_2.
```
## Black Output
```py
#!/usr/bin/env python3.6
x = 123456789
x = 1_2_3_4_5_6_7
x = 1e1
x = 0xB1ACC
x = 0.00_00_006
x = 12_34_567j
x = 0.1_2
x = 1_2.0
```

View file

@ -0,0 +1,144 @@
---
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,29 +2,21 @@
def f():
- return (i * 2 async for i in arange(42))
+ return (i for i in [])
def g():
- return (
- something_long * something_long
- async for something_long in async_generator(with_an_argument)
- )
+ return (i for i in [])
async def func():
if test:
- out_batched = [
- i
- async for i in aitertools._async_map(
- self.async_inc, arange(8), batch_size=3
- )
- ]
+ out_batched = [i for i in []]
def awaited_generator_value(n):
- return (await awaitable for awaitable in awaitable_list)
+ return (i for i in [])
def make_arange(n):
- return (i * 2 for i in range(n) if await wrap(i))
+ return (i for i in [])
```
## Ruff Output
```py
#!/usr/bin/env python3.7
def f():
return (i for i in [])
def g():
return (i for i in [])
async def func():
if test:
out_batched = [i for i in []]
def awaited_generator_value(n):
return (i for i in [])
def make_arange(n):
return (i for i 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))
```

View file

@ -0,0 +1,174 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_570.py
---
## Input
```py
def positional_only_arg(a, /):
pass
def all_markers(a, b, /, c, d, *, e, f):
pass
def all_markers_with_args_and_kwargs(
a_long_one,
b_long_one,
/,
c_long_one,
d_long_one,
*args,
e_long_one,
f_long_one,
**kwargs,
):
pass
def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5):
pass
def long_one_with_long_parameter_names(
but_all_of_them,
are_positional_only,
arguments_mmmmkay,
so_this_is_only_valid_after,
three_point_eight,
/,
):
pass
lambda a, /: a
lambda a, b, /, c, d, *, e, f: a
lambda a, b, /, c, d, *args, e, f, **kwargs: args
lambda a, b=1, /, c=2, d=3, *, e=4, f=5: 1
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -35,10 +35,10 @@
pass
-lambda a, /: a
+lambda x: True
-lambda a, b, /, c, d, *, e, f: a
+lambda x: True
-lambda a, b, /, c, d, *args, e, f, **kwargs: args
+lambda x: True
-lambda a, b=1, /, c=2, d=3, *, e=4, f=5: 1
+lambda x: True
```
## Ruff Output
```py
def positional_only_arg(a, /):
pass
def all_markers(a, b, /, c, d, *, e, f):
pass
def all_markers_with_args_and_kwargs(
a_long_one,
b_long_one,
/,
c_long_one,
d_long_one,
*args,
e_long_one,
f_long_one,
**kwargs,
):
pass
def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5):
pass
def long_one_with_long_parameter_names(
but_all_of_them,
are_positional_only,
arguments_mmmmkay,
so_this_is_only_valid_after,
three_point_eight,
/,
):
pass
lambda x: True
lambda x: True
lambda x: True
lambda x: True
```
## Black Output
```py
def positional_only_arg(a, /):
pass
def all_markers(a, b, /, c, d, *, e, f):
pass
def all_markers_with_args_and_kwargs(
a_long_one,
b_long_one,
/,
c_long_one,
d_long_one,
*args,
e_long_one,
f_long_one,
**kwargs,
):
pass
def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5):
pass
def long_one_with_long_parameter_names(
but_all_of_them,
are_positional_only,
arguments_mmmmkay,
so_this_is_only_valid_after,
three_point_eight,
/,
):
pass
lambda a, /: a
lambda a, b, /, c, d, *, e, f: a
lambda a, b, /, c, d, *args, e, f, **kwargs: args
lambda a, b=1, /, c=2, d=3, *, e=4, f=5: 1
```

View file

@ -0,0 +1,247 @@
---
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
@@ -1,47 +1,47 @@
-(a := 1)
-(a := a)
-if (match := pattern.search(data)) is None:
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+if (NOT_YET_IMPLEMENTED_ExprNamedExpr) is None:
pass
-if match := pattern.search(data):
+if NOT_YET_IMPLEMENTED_ExprNamedExpr:
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)))
+[NOT_YET_IMPLEMENTED_ExprNamedExpr, y**2, y**3]
+filtered_data = [i for i in []]
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+y0 = NOT_YET_IMPLEMENTED_ExprNamedExpr
+foo(x=(NOT_YET_IMPLEMENTED_ExprNamedExpr))
-def foo(answer=(p := 42)):
+def foo(answer=(NOT_YET_IMPLEMENTED_ExprNamedExpr)):
pass
-def foo(answer: (p := 42) = 5):
+def foo(answer: (NOT_YET_IMPLEMENTED_ExprNamedExpr) = 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):
+lambda x: True
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+lambda x: True
+x = NOT_YET_IMPLEMENTED_ExprNamedExpr
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+(NOT_YET_IMPLEMENTED_ExprNamedExpr, 2)
+(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+len(NOT_YET_IMPLEMENTED_ExprNamedExpr)
+foo(NOT_YET_IMPLEMENTED_ExprNamedExpr, cat="vector")
+foo(cat=(NOT_YET_IMPLEMENTED_ExprNamedExpr))
+if any((i for i in [])):
print(longline)
-if env_base := os.environ.get("PYTHONUSERBASE", None):
+if NOT_YET_IMPLEMENTED_ExprNamedExpr:
return env_base
-if self._is_special and (ans := self._check_nans(context=context)):
+if self._is_special and (NOT_YET_IMPLEMENTED_ExprNamedExpr):
return ans
-foo(b := 2, a=1)
-foo((b := 2), a=1)
-foo(c=(b := 2), a=1)
+foo(NOT_YET_IMPLEMENTED_ExprNamedExpr, a=1)
+foo(NOT_YET_IMPLEMENTED_ExprNamedExpr, a=1)
+foo(c=(NOT_YET_IMPLEMENTED_ExprNamedExpr), a=1)
-while x := f(x):
+while NOT_YET_IMPLEMENTED_ExprNamedExpr:
pass
-while x := f(x):
+while NOT_YET_IMPLEMENTED_ExprNamedExpr:
pass
```
## Ruff Output
```py
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
if (NOT_YET_IMPLEMENTED_ExprNamedExpr) is None:
pass
if NOT_YET_IMPLEMENTED_ExprNamedExpr:
pass
[NOT_YET_IMPLEMENTED_ExprNamedExpr, y**2, y**3]
filtered_data = [i for i in []]
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
y0 = NOT_YET_IMPLEMENTED_ExprNamedExpr
foo(x=(NOT_YET_IMPLEMENTED_ExprNamedExpr))
def foo(answer=(NOT_YET_IMPLEMENTED_ExprNamedExpr)):
pass
def foo(answer: (NOT_YET_IMPLEMENTED_ExprNamedExpr) = 5):
pass
lambda x: True
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
lambda x: True
x = NOT_YET_IMPLEMENTED_ExprNamedExpr
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
(NOT_YET_IMPLEMENTED_ExprNamedExpr, 2)
(NOT_YET_IMPLEMENTED_ExprNamedExpr)
len(NOT_YET_IMPLEMENTED_ExprNamedExpr)
foo(NOT_YET_IMPLEMENTED_ExprNamedExpr, cat="vector")
foo(cat=(NOT_YET_IMPLEMENTED_ExprNamedExpr))
if any((i for i in [])):
print(longline)
if NOT_YET_IMPLEMENTED_ExprNamedExpr:
return env_base
if self._is_special and (NOT_YET_IMPLEMENTED_ExprNamedExpr):
return ans
foo(NOT_YET_IMPLEMENTED_ExprNamedExpr, a=1)
foo(NOT_YET_IMPLEMENTED_ExprNamedExpr, a=1)
foo(c=(NOT_YET_IMPLEMENTED_ExprNamedExpr), a=1)
while NOT_YET_IMPLEMENTED_ExprNamedExpr:
pass
while NOT_YET_IMPLEMENTED_ExprNamedExpr:
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
```

View file

@ -0,0 +1,113 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py
---
## Input
```py
#!/usr/bin/env python3.8
def starred_return():
my_list = ["value2", "value3"]
return "value1", *my_list
def starred_yield():
my_list = ["value2", "value3"]
yield "value1", *my_list
# all right hand side expressions allowed in regular assignments are now also allowed in
# annotated assignments
a : Tuple[ str, int] = "1", 2
a: Tuple[int , ... ] = b, *c, d
def t():
a : str = yield "a"
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -3,19 +3,19 @@
def starred_return():
my_list = ["value2", "value3"]
- return "value1", *my_list
+ return "value1", *NOT_YET_IMPLEMENTED_ExprStarred
def starred_yield():
my_list = ["value2", "value3"]
- yield "value1", *my_list
+ NOT_YET_IMPLEMENTED_ExprYield
# all right hand side expressions allowed in regular assignments are now also allowed in
# annotated assignments
-a: Tuple[str, int] = "1", 2
-a: Tuple[int, ...] = b, *c, d
+NOT_YET_IMPLEMENTED_StmtAnnAssign
+NOT_YET_IMPLEMENTED_StmtAnnAssign
def t():
- a: str = yield "a"
+ NOT_YET_IMPLEMENTED_StmtAnnAssign
```
## Ruff Output
```py
#!/usr/bin/env python3.8
def starred_return():
my_list = ["value2", "value3"]
return "value1", *NOT_YET_IMPLEMENTED_ExprStarred
def starred_yield():
my_list = ["value2", "value3"]
NOT_YET_IMPLEMENTED_ExprYield
# all right hand side expressions allowed in regular assignments are now also allowed in
# annotated assignments
NOT_YET_IMPLEMENTED_StmtAnnAssign
NOT_YET_IMPLEMENTED_StmtAnnAssign
def t():
NOT_YET_IMPLEMENTED_StmtAnnAssign
```
## Black Output
```py
#!/usr/bin/env python3.8
def starred_return():
my_list = ["value2", "value3"]
return "value1", *my_list
def starred_yield():
my_list = ["value2", "value3"]
yield "value1", *my_list
# all right hand side expressions allowed in regular assignments are now also allowed in
# annotated assignments
a: Tuple[str, int] = "1", 2
a: Tuple[int, ...] = b, *c, d
def t():
a: str = yield "a"
```

View file

@ -0,0 +1,60 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_39/pep_572_py39.py
---
## Input
```py
# Unparenthesized walruses are now allowed in set literals & set comprehensions
# since Python 3.9
{x := 1, 2, 3}
{x4 := x**5 for x in range(7)}
# We better not remove the parentheses here (since it's a 3.10 feature)
x[(a := 1)]
x[(a := 1), (b := 3)]
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,7 +1,7 @@
# Unparenthesized walruses are now allowed in set literals & set comprehensions
# since Python 3.9
-{x := 1, 2, 3}
-{x4 := x**5 for x in range(7)}
+{NOT_YET_IMPLEMENTED_ExprNamedExpr, 2, 3}
+{NOT_IMPLEMENTED_set_value for value in NOT_IMPLEMENTED_set}
# We better not remove the parentheses here (since it's a 3.10 feature)
-x[(a := 1)]
-x[(a := 1), (b := 3)]
+x[(NOT_YET_IMPLEMENTED_ExprNamedExpr)]
+x[((NOT_YET_IMPLEMENTED_ExprNamedExpr), (NOT_YET_IMPLEMENTED_ExprNamedExpr))]
```
## Ruff Output
```py
# Unparenthesized walruses are now allowed in set literals & set comprehensions
# since Python 3.9
{NOT_YET_IMPLEMENTED_ExprNamedExpr, 2, 3}
{NOT_IMPLEMENTED_set_value for value in NOT_IMPLEMENTED_set}
# We better not remove the parentheses here (since it's a 3.10 feature)
x[(NOT_YET_IMPLEMENTED_ExprNamedExpr)]
x[((NOT_YET_IMPLEMENTED_ExprNamedExpr), (NOT_YET_IMPLEMENTED_ExprNamedExpr))]
```
## Black Output
```py
# Unparenthesized walruses are now allowed in set literals & set comprehensions
# since Python 3.9
{x := 1, 2, 3}
{x4 := x**5 for x in range(7)}
# We better not remove the parentheses here (since it's a 3.10 feature)
x[(a := 1)]
x[(a := 1), (b := 3)]
```

View file

@ -0,0 +1,94 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py
---
## Input
```py
#!/usr/bin/env python3.9
@relaxed_decorator[0]
def f():
...
@relaxed_decorator[extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length]
def f():
...
@extremely_long_variable_name_that_doesnt_fit := complex.expression(with_long="arguments_value_that_wont_fit_at_the_end_of_the_line")
def f():
...
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,6 +1,5 @@
#!/usr/bin/env python3.9
-
@relaxed_decorator[0]
def f():
...
@@ -13,8 +12,6 @@
...
-@extremely_long_variable_name_that_doesnt_fit := complex.expression(
- with_long="arguments_value_that_wont_fit_at_the_end_of_the_line"
-)
+@NOT_YET_IMPLEMENTED_ExprNamedExpr
def f():
...
```
## Ruff Output
```py
#!/usr/bin/env python3.9
@relaxed_decorator[0]
def f():
...
@relaxed_decorator[
extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length
]
def f():
...
@NOT_YET_IMPLEMENTED_ExprNamedExpr
def f():
...
```
## Black Output
```py
#!/usr/bin/env python3.9
@relaxed_decorator[0]
def f():
...
@relaxed_decorator[
extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length
]
def f():
...
@extremely_long_variable_name_that_doesnt_fit := complex.expression(
with_long="arguments_value_that_wont_fit_at_the_end_of_the_line"
)
def f():
...
```

View file

@ -0,0 +1,216 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_39/remove_with_brackets.py
---
## Input
```py
with (open("bla.txt")):
pass
with (open("bla.txt")), (open("bla.txt")):
pass
with (open("bla.txt") as f):
pass
# Remove brackets within alias expression
with (open("bla.txt")) as f:
pass
# Remove brackets around one-line context managers
with (open("bla.txt") as f, (open("x"))):
pass
with ((open("bla.txt")) as f, open("x")):
pass
with (CtxManager1() as example1, CtxManager2() as example2):
...
# Brackets remain when using magic comma
with (CtxManager1() as example1, CtxManager2() as example2,):
...
# Brackets remain for multi-line context managers
with (CtxManager1() as example1, CtxManager2() as example2, CtxManager2() as example2, CtxManager2() as example2, CtxManager2() as example2):
...
# Don't touch assignment expressions
with (y := open("./test.py")) as f:
pass
# Deeply nested examples
# N.B. Multiple brackets are only possible
# around the context manager itself.
# Only one brackets is allowed around the
# alias expression or comma-delimited context managers.
with (((open("bla.txt")))):
pass
with (((open("bla.txt")))), (((open("bla.txt")))):
pass
with (((open("bla.txt")))) as f:
pass
with ((((open("bla.txt")))) as f):
pass
with ((((CtxManager1()))) as example1, (((CtxManager2()))) as example2):
...
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -39,7 +39,7 @@
...
# Don't touch assignment expressions
-with (y := open("./test.py")) as f:
+with NOT_YET_IMPLEMENTED_ExprNamedExpr as f:
pass
# Deeply nested examples
```
## Ruff Output
```py
with open("bla.txt"):
pass
with open("bla.txt"), open("bla.txt"):
pass
with open("bla.txt") as f:
pass
# Remove brackets within alias expression
with open("bla.txt") as f:
pass
# Remove brackets around one-line context managers
with open("bla.txt") as f, open("x"):
pass
with open("bla.txt") as f, open("x"):
pass
with CtxManager1() as example1, CtxManager2() as example2:
...
# Brackets remain when using magic comma
with (
CtxManager1() as example1,
CtxManager2() as example2,
):
...
# Brackets remain for multi-line context managers
with (
CtxManager1() as example1,
CtxManager2() as example2,
CtxManager2() as example2,
CtxManager2() as example2,
CtxManager2() as example2,
):
...
# Don't touch assignment expressions
with NOT_YET_IMPLEMENTED_ExprNamedExpr as f:
pass
# Deeply nested examples
# N.B. Multiple brackets are only possible
# around the context manager itself.
# Only one brackets is allowed around the
# alias expression or comma-delimited context managers.
with open("bla.txt"):
pass
with open("bla.txt"), open("bla.txt"):
pass
with open("bla.txt") as f:
pass
with open("bla.txt") as f:
pass
with CtxManager1() as example1, CtxManager2() as example2:
...
```
## Black Output
```py
with open("bla.txt"):
pass
with open("bla.txt"), open("bla.txt"):
pass
with open("bla.txt") as f:
pass
# Remove brackets within alias expression
with open("bla.txt") as f:
pass
# Remove brackets around one-line context managers
with open("bla.txt") as f, open("x"):
pass
with open("bla.txt") as f, open("x"):
pass
with CtxManager1() as example1, CtxManager2() as example2:
...
# Brackets remain when using magic comma
with (
CtxManager1() as example1,
CtxManager2() as example2,
):
...
# Brackets remain for multi-line context managers
with (
CtxManager1() as example1,
CtxManager2() as example2,
CtxManager2() as example2,
CtxManager2() as example2,
CtxManager2() as example2,
):
...
# Don't touch assignment expressions
with (y := open("./test.py")) as f:
pass
# Deeply nested examples
# N.B. Multiple brackets are only possible
# around the context manager itself.
# Only one brackets is allowed around the
# alias expression or comma-delimited context managers.
with open("bla.txt"):
pass
with open("bla.txt"), open("bla.txt"):
pass
with open("bla.txt") as f:
pass
with open("bla.txt") as f:
pass
with CtxManager1() as example1, CtxManager2() as example2:
...
```

View file

@ -140,13 +140,6 @@ async def wat():
if inner_imports.are_evil():
# Explains why we have this if.
@@ -93,4 +93,4 @@
# Some closing comments.
# Maybe Vim or Emacs directives for formatting.
-# Who knows.
\ No newline at end of file
+# Who knows.
```
## Ruff Output
@ -348,6 +341,7 @@ async def wat():
# Some closing comments.
# Maybe Vim or Emacs directives for formatting.
# Who knows.```
# Who knows.
```

View file

@ -266,15 +266,15 @@ last_call()
```diff
--- Black
+++ Ruff
@@ -1,5 +1,6 @@
+...
@@ -1,6 +1,6 @@
...
"some_string"
-b"\\xa3"
+b"NOT_YET_IMPLEMENTED_BYTE_STRING"
Name
None
True
@@ -23,40 +24,46 @@
@@ -24,40 +24,46 @@
1 >> v2
1 % finished
1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
@ -346,7 +346,7 @@ last_call()
()
(1,)
(1, 2)
@@ -68,40 +75,37 @@
@@ -69,40 +75,37 @@
2,
3,
]
@ -405,9 +405,12 @@ last_call()
Python3 > Python2 > COBOL
Life is Life
call()
@@ -116,8 +120,8 @@
@@ -115,10 +118,10 @@
arg,
another,
kwarg="hey",
**kwargs,
- **kwargs
+ **kwargs,
) # note: no trailing comma pre-3.6
-call(*gidgets[:2])
-call(a, *gidgets[:2])
@ -416,7 +419,7 @@ last_call()
call(**self.screen_kwargs)
call(b, **self.screen_kwargs)
lukasz.langa.pl
@@ -130,34 +134,28 @@
@@ -131,34 +134,28 @@
tuple[str, ...]
tuple[str, int, float, dict[str, int]]
tuple[
@ -424,9 +427,6 @@ last_call()
- int,
- float,
- dict[str, int],
-]
-very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
+ (
+ str,
+ int,
@ -434,6 +434,9 @@ last_call()
+ dict[str, int],
+ )
]
-very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
-]
-xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
- sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
-)
@ -464,7 +467,7 @@ last_call()
numpy[0, :]
numpy[:, i]
numpy[0, :2]
@@ -171,20 +169,27 @@
@@ -172,20 +169,27 @@
numpy[1 : c + 1, c]
numpy[-(c + 1) :, d]
numpy[:, l[-2]]
@ -500,7 +503,7 @@ last_call()
{
"id": "1",
"type": "type",
@@ -199,32 +204,22 @@
@@ -200,32 +204,22 @@
c = 1
d = (1,) + a + (2,)
e = (1,).count(1)
@ -513,7 +516,7 @@ last_call()
)
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(
@ -521,7 +524,7 @@ last_call()
- )
- .order_by(models.Customer.id.asc())
- .all()
-)
)
-result = (
- session.query(models.Customer.id)
- .filter(
@ -543,7 +546,7 @@ last_call()
Ø = set()
authors.łukasz.say_thanks()
mapping = {
@@ -236,29 +231,27 @@
@@ -237,29 +231,27 @@
def gen():
@ -584,7 +587,7 @@ last_call()
...
for i in call():
...
@@ -327,13 +320,18 @@
@@ -328,13 +320,18 @@
):
return True
if (
@ -606,7 +609,7 @@ last_call()
^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n
):
return True
@@ -341,7 +339,8 @@
@@ -342,7 +339,8 @@
~aaaaaaaaaaaaaaaa.a
+ aaaaaaaaaaaaaaaa.b
- aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e
@ -995,6 +998,7 @@ last_call()
## Black Output
```py
...
"some_string"
b"\\xa3"
Name
@ -1111,7 +1115,7 @@ call(
arg,
another,
kwarg="hey",
**kwargs,
**kwargs
) # note: no trailing comma pre-3.6
call(*gidgets[:2])
call(a, *gidgets[:2])

View file

@ -198,18 +198,17 @@ d={'a':1,
```diff
--- Black
+++ Ruff
@@ -1,16 +1,14 @@
@@ -1,15 +1,14 @@
#!/usr/bin/env python3
-import asyncio
-import sys
-
-from third_party import X, Y, Z
+NOT_YET_IMPLEMENTED_StmtImport
+NOT_YET_IMPLEMENTED_StmtImport
-from library import some_connection, some_decorator
-from third_party import X, Y, Z
+NOT_YET_IMPLEMENTED_StmtImportFrom
-from library import some_connection, some_decorator
+NOT_YET_IMPLEMENTED_StmtImportFrom
# fmt: off
-from third_party import (X,
@ -221,7 +220,7 @@ d={'a':1,
# Comment 1
# Comment 2
@@ -18,30 +16,54 @@
@@ -17,30 +16,54 @@
# fmt: off
def func_no_args():
@ -297,7 +296,7 @@ d={'a':1,
def spaces_types(
@@ -51,7 +73,7 @@
@@ -50,7 +73,7 @@
d: dict = {},
e: bool = True,
f: int = -1,
@ -306,7 +305,7 @@ d={'a':1,
h: str = "",
i: str = r"",
):
@@ -64,55 +86,54 @@
@@ -63,55 +86,54 @@
something = {
# fmt: off
@ -381,7 +380,7 @@ d={'a':1,
# fmt: on
@@ -133,10 +154,10 @@
@@ -132,10 +154,10 @@
"""Another known limitation."""
# fmt: on
# fmt: off
@ -396,7 +395,7 @@ d={'a':1,
# fmt: on
# fmt: off
# ...but comments still get reformatted even though they should not be
@@ -151,12 +172,10 @@
@@ -150,12 +172,10 @@
ast_args.kw_defaults,
parameters,
implicit_default=True,
@ -411,7 +410,7 @@ d={'a':1,
# fmt: on
_type_comment_re = re.compile(
r"""
@@ -179,7 +198,7 @@
@@ -178,7 +198,7 @@
$
""",
# fmt: off
@ -420,7 +419,7 @@ d={'a':1,
# fmt: on
)
@@ -217,8 +236,7 @@
@@ -216,8 +236,7 @@
xxxxxxxxxx_xxxxxxxxxxx_xxxxxxx_xxxxxxxxx=5,
)
# fmt: off
@ -691,7 +690,6 @@ import sys
from third_party import X, Y, Z
from library import some_connection, some_decorator
# fmt: off
from third_party import (X,
Y, Z)

View file

@ -0,0 +1,114 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtpass_imports.py
---
## Input
```py
# Regression test for https://github.com/psf/black/issues/3438
import ast
import collections # fmt: skip
import dataclasses
# fmt: off
import os
# fmt: on
import pathlib
import re # fmt: skip
import secrets
# fmt: off
import sys
# fmt: on
import tempfile
import zoneinfo
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,19 +1,19 @@
# Regression test for https://github.com/psf/black/issues/3438
-import ast
-import collections # fmt: skip
-import dataclasses
+NOT_YET_IMPLEMENTED_StmtImport
+NOT_YET_IMPLEMENTED_StmtImport # fmt: skip
+NOT_YET_IMPLEMENTED_StmtImport
# fmt: off
-import os
+NOT_YET_IMPLEMENTED_StmtImport
# fmt: on
-import pathlib
+NOT_YET_IMPLEMENTED_StmtImport
-import re # fmt: skip
-import secrets
+NOT_YET_IMPLEMENTED_StmtImport # fmt: skip
+NOT_YET_IMPLEMENTED_StmtImport
# fmt: off
-import sys
+NOT_YET_IMPLEMENTED_StmtImport
# fmt: on
-import tempfile
-import zoneinfo
+NOT_YET_IMPLEMENTED_StmtImport
+NOT_YET_IMPLEMENTED_StmtImport
```
## Ruff Output
```py
# Regression test for https://github.com/psf/black/issues/3438
NOT_YET_IMPLEMENTED_StmtImport
NOT_YET_IMPLEMENTED_StmtImport # fmt: skip
NOT_YET_IMPLEMENTED_StmtImport
# fmt: off
NOT_YET_IMPLEMENTED_StmtImport
# fmt: on
NOT_YET_IMPLEMENTED_StmtImport
NOT_YET_IMPLEMENTED_StmtImport # fmt: skip
NOT_YET_IMPLEMENTED_StmtImport
# fmt: off
NOT_YET_IMPLEMENTED_StmtImport
# fmt: on
NOT_YET_IMPLEMENTED_StmtImport
NOT_YET_IMPLEMENTED_StmtImport
```
## Black Output
```py
# Regression test for https://github.com/psf/black/issues/3438
import ast
import collections # fmt: skip
import dataclasses
# fmt: off
import os
# fmt: on
import pathlib
import re # fmt: skip
import secrets
# fmt: off
import sys
# fmt: on
import tempfile
import zoneinfo
```

View file

@ -14,6 +14,8 @@ f"{f'''{'nested'} inner'''} outer"
f"\"{f'{nested} inner'}\" outer"
f"space between opening braces: { {a for a in (1, 2, 3)}}"
f'Hello \'{tricky + "example"}\''
f"Tried directories {str(rootdirs)} \
but none started with prefix {parentdir_prefix}"
```
## Black Differences
@ -21,7 +23,7 @@ f'Hello \'{tricky + "example"}\''
```diff
--- Black
+++ Ruff
@@ -1,9 +1,9 @@
@@ -1,11 +1,10 @@
-f"f-string without formatted values is just a string"
-f"{{NOT a formatted value}}"
-f'{{NOT \'a\' "formatted" "value"}}'
@ -31,6 +33,9 @@ f'Hello \'{tricky + "example"}\''
-f"\"{f'{nested} inner'}\" outer"
-f"space between opening braces: { {a for a in (1, 2, 3)}}"
-f'Hello \'{tricky + "example"}\''
-f"Tried directories {str(rootdirs)} \
-but none started with prefix {parentdir_prefix}"
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
+NOT_YET_IMPLEMENTED_ExprJoinedStr
@ -54,6 +59,7 @@ NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
NOT_YET_IMPLEMENTED_ExprJoinedStr
```
## Black Output
@ -68,6 +74,8 @@ f"{f'''{'nested'} inner'''} outer"
f"\"{f'{nested} inner'}\" outer"
f"space between opening braces: { {a for a in (1, 2, 3)}}"
f'Hello \'{tricky + "example"}\''
f"Tried directories {str(rootdirs)} \
but none started with prefix {parentdir_prefix}"
```

View file

@ -41,7 +41,7 @@ def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r''
def spaces_types(a: int = 1, b: tuple = (), c: list = [], d: dict = {}, e: bool = True, f: int = -1, g: int = 1 if False else 2, h: str = "", i: str = r''): ...
def spaces2(result= _core.Value(None)):
assert fut is self._read_fut, (fut, self._read_fut)
# EMPTY LINE WITH WHITESPACE (this comment will be removed)
def example(session):
result = session.query(models.Customer.id).filter(
models.Customer.account_id == account_id,
@ -111,14 +111,14 @@ def __await__(): return (yield)
#!/usr/bin/env python3
-import asyncio
-import sys
+NOT_YET_IMPLEMENTED_StmtImport
+NOT_YET_IMPLEMENTED_StmtImport
-
-from third_party import X, Y, Z
+NOT_YET_IMPLEMENTED_StmtImportFrom
+NOT_YET_IMPLEMENTED_StmtImport
+NOT_YET_IMPLEMENTED_StmtImport
-from library import some_connection, some_decorator
-
+NOT_YET_IMPLEMENTED_StmtImportFrom
-f"trigger 3.6 mode"
+NOT_YET_IMPLEMENTED_StmtImportFrom
+NOT_YET_IMPLEMENTED_ExprJoinedStr
@ -170,12 +170,13 @@ def __await__(): return (yield)
h: str = "",
i: str = r"",
):
@@ -64,19 +73,16 @@
@@ -64,19 +73,17 @@
def spaces2(result=_core.Value(None)):
- assert fut is self._read_fut, (fut, self._read_fut)
+ NOT_YET_IMPLEMENTED_StmtAssert
+ # EMPTY LINE WITH WHITESPACE (this comment will be removed)
def example(session):
@ -197,7 +198,7 @@ def __await__(): return (yield)
def long_lines():
@@ -87,7 +93,7 @@
@@ -87,7 +94,7 @@
ast_args.kw_defaults,
parameters,
implicit_default=True,
@ -206,7 +207,7 @@ def __await__(): return (yield)
)
typedargslist.extend(
gen_annotated_params(
@@ -96,7 +102,7 @@
@@ -96,7 +103,7 @@
parameters,
implicit_default=True,
# trailing standalone comment
@ -215,7 +216,7 @@ def __await__(): return (yield)
)
_type_comment_re = re.compile(
r"""
@@ -135,14 +141,8 @@
@@ -135,14 +142,8 @@
a,
**kwargs,
) -> A:
@ -313,6 +314,7 @@ def spaces_types(
def spaces2(result=_core.Value(None)):
NOT_YET_IMPLEMENTED_StmtAssert
# EMPTY LINE WITH WHITESPACE (this comment will be removed)
def example(session):

View file

@ -36,38 +36,6 @@ ham[lower:upper], ham[lower:upper:], ham[lower::step]
# ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
slice[::, ::]
slice[
# A
:
# B
:
# C
]
slice[
# A
1:
# B
2:
# C
3
]
slice[
# A
1
+ 2 :
# B
3 :
# C
4
]
x[
1: # A
2: # B
3 # C
]
```
## Black Differences
@ -75,7 +43,7 @@ x[
```diff
--- Black
+++ Ruff
@@ -4,30 +4,30 @@
@@ -4,28 +4,28 @@
slice[d::d]
slice[0]
slice[-1]
@ -113,27 +81,6 @@ x[
-ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
+ham[ : upper_fn(x) : step_fn(x)], ham[ :: step_fn(x)]
ham[lower + offset : upper + offset]
slice[::, ::]
@@ -49,11 +49,14 @@
slice[
# A
- 1
- + 2 :
+ 1 + 2 :
# B
- 3 :
+ 3 :
# C
4
]
-x[1:2:3] # A # B # C
+x[
+ 1: # A
+ 2: # B
+ 3 # C
+]
```
## Ruff Output
@ -170,37 +117,6 @@ ham[lower:upper], ham[lower:upper:], ham[lower::step]
# ham[lower+offset : upper+offset]
ham[ : upper_fn(x) : step_fn(x)], ham[ :: step_fn(x)]
ham[lower + offset : upper + offset]
slice[::, ::]
slice[
# A
:
# B
:
# C
]
slice[
# A
1:
# B
2:
# C
3
]
slice[
# A
1 + 2 :
# B
3 :
# C
4
]
x[
1: # A
2: # B
3 # C
]
```
## Black Output
@ -237,34 +153,6 @@ ham[lower:upper], ham[lower:upper:], ham[lower::step]
# ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
slice[::, ::]
slice[
# A
:
# B
:
# C
]
slice[
# A
1:
# B
2:
# C
3
]
slice[
# A
1
+ 2 :
# B
3 :
# C
4
]
x[1:2:3] # A # B # C
```

View file

@ -0,0 +1,31 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py
---
## Input
```py
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1 +0,0 @@
-
```
## Ruff Output
```py
```
## Black Output
```py
```