mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-09 18:02:19 +00:00
Update Black tests (#5438)
This commit is contained in:
parent
f7969cf23c
commit
ae25638b0b
166 changed files with 11066 additions and 237 deletions
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -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"
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -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)))
|
||||
```
|
||||
|
||||
|
|
@ -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():
|
||||
...
|
||||
```
|
||||
|
||||
|
|
@ -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 \\'''
|
||||
```
|
||||
|
||||
|
|
@ -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.'''
|
||||
```
|
||||
|
||||
|
|
@ -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]: ...
|
||||
```
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
) #
|
||||
```
|
||||
|
||||
|
|
@ -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}\""
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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}"
|
||||
```
|
||||
|
||||
|
|
@ -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")
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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)
|
||||
```
|
||||
|
||||
|
|
@ -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"
|
||||
```
|
||||
|
||||
|
|
@ -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)
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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))
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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"
|
||||
```
|
||||
|
||||
|
|
@ -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)]
|
||||
```
|
||||
|
||||
|
|
@ -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():
|
||||
...
|
||||
```
|
||||
|
||||
|
|
@ -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:
|
||||
...
|
||||
```
|
||||
|
||||
|
|
@ -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.
|
||||
```
|
||||
|
||||
|
|
@ -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])
|
|
@ -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)
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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}"
|
||||
```
|
||||
|
||||
|
|
@ -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):
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
```
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue