mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-03 15:15:33 +00:00
test(ruff_python_formatter): Run all Black tests (#2993)
This PR changes the testing infrastructure to run all black tests and: * Pass if Ruff and Black generate the same formatting * Fail and write a markdown snapshot that shows the input code, the differences between Black and Ruff, Ruffs output, and Blacks output This is achieved by introducing a new `fixture` macro (open to better name suggestions) that "duplicates" the attributed test for every file that matches the specified glob pattern. Creating a new test for each file over having a test that iterates over all files has the advantage that you can run a single test, and that test failures indicate which case is failing. The `fixture` macro also makes it straightforward to e.g. setup our own spec tests that test very specific formatting by creating a new folder and use insta to assert the formatted output.
This commit is contained in:
parent
262e768fd3
commit
ed33b75bad
119 changed files with 12989 additions and 981 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -2075,13 +2075,26 @@ dependencies = [
|
||||||
"insta",
|
"insta",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ruff_formatter",
|
"ruff_formatter",
|
||||||
|
"ruff_testing_macros",
|
||||||
"ruff_text_size",
|
"ruff_text_size",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustpython-common",
|
"rustpython-common",
|
||||||
"rustpython-parser",
|
"rustpython-parser",
|
||||||
|
"similar",
|
||||||
"test-case",
|
"test-case",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruff_testing_macros"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff_text_size"
|
name = "ruff_text_size"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
|
@ -18,3 +18,5 @@ rustpython-parser = { workspace = true }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = { version = "1.19.0", features = [] }
|
insta = { version = "1.19.0", features = [] }
|
||||||
test-case = { version = "2.2.2" }
|
test-case = { version = "2.2.2" }
|
||||||
|
ruff_testing_macros = { path = "../ruff_testing_macros" }
|
||||||
|
similar = "2.2.1"
|
||||||
|
|
6
crates/ruff_python_formatter/resources/test/fixtures/black/.editorconfig
vendored
Normal file
6
crates/ruff_python_formatter/resources/test/fixtures/black/.editorconfig
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Check http://editorconfig.org for more information
|
||||||
|
# This is the main config file for this project:
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*.py.expect]
|
||||||
|
insert_final_newline = false
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
x = (123456789).bit_count()
|
x = (123456789).bit_count()
|
||||||
x = (123456).__abs__()
|
x = (123456).__abs__()
|
||||||
x = (0.1).is_integer()
|
x = (0.1).is_integer()
|
||||||
|
@ -25,4 +20,3 @@ if (10).real:
|
||||||
|
|
||||||
y = 100[no]
|
y = 100[no]
|
||||||
y = 100(no)
|
y = 100(no)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
print("hello, world")
|
|
@ -0,0 +1,4 @@
|
||||||
|
for ((x in {}) or {})["a"] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam={"x": 3}: not spam.get(l.strip())
|
||||||
|
lambda x=lambda y={1: 3}: y["x" : lambda y: {1: 2}]: x
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
class SimpleClassWithBlankParentheses:
|
class SimpleClassWithBlankParentheses:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -33,4 +28,3 @@ class NormalClass:
|
||||||
def func_for_testing(self, first, second):
|
def func_for_testing(self, first, second):
|
||||||
sum = first + second
|
sum = first + second
|
||||||
return sum
|
return sum
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
class ClassSimplest:
|
class ClassSimplest:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -168,4 +163,3 @@ class ClassWithDecoInitAndVarsAndDocstringWithInner2:
|
||||||
@deco
|
@deco
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
import core, time, a
|
import core, time, a
|
||||||
|
|
||||||
from . import A, B, C
|
from . import A, B, C
|
||||||
|
@ -102,4 +97,3 @@ if True:
|
||||||
"Delay": 5,
|
"Delay": 5,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
def bob(): # pylint: disable=W9016
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def bobtwo(): # some comment here
|
||||||
|
pass
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# fmt: on
|
# fmt: on
|
||||||
# Some license here.
|
# Some license here.
|
||||||
|
@ -99,4 +94,3 @@ async def wat():
|
||||||
# Some closing comments.
|
# Some closing comments.
|
||||||
# Maybe Vim or Emacs directives for formatting.
|
# Maybe Vim or Emacs directives for formatting.
|
||||||
# Who knows.
|
# Who knows.
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
)
|
)
|
||||||
|
@ -176,4 +171,3 @@ instruction() # comment with bad spacing
|
||||||
|
|
||||||
# END COMMENTS
|
# END COMMENTS
|
||||||
# MORE END COMMENTS
|
# MORE END COMMENTS
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# The percent-percent comments are Spyder IDE cells.
|
# The percent-percent comments are Spyder IDE cells.
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,4 +46,3 @@ def func():
|
||||||
|
|
||||||
|
|
||||||
# %%
|
# %%
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
)
|
)
|
||||||
|
@ -97,4 +92,3 @@ def foo3(list_a, list_b):
|
||||||
)
|
)
|
||||||
.filter(User.xyz.is_(None))
|
.filter(User.xyz.is_(None))
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
while True:
|
while True:
|
||||||
if something.changed:
|
if something.changed:
|
||||||
do.stuff() # trailing comment
|
do.stuff() # trailing comment
|
||||||
|
@ -76,4 +71,3 @@ def g():
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
from typing import Any, Tuple
|
from typing import Any, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,4 +116,3 @@ call_to_some_function_asdf(
|
||||||
)
|
)
|
||||||
|
|
||||||
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
|
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# The percent-percent comments are Spyder IDE cells.
|
# The percent-percent comments are Spyder IDE cells.
|
||||||
# Both `#%%`` and `# %%` are accepted, so `black` standardises
|
# Both `#%%`` and `# %%` are accepted, so `black` standardises
|
||||||
# to the latter.
|
# to the latter.
|
||||||
|
|
||||||
# %%
|
# %%
|
||||||
# %%
|
# %%
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Test for https://github.com/psf/black/issues/246.
|
# Test for https://github.com/psf/black/issues/246.
|
||||||
|
|
||||||
some = statement
|
some = statement
|
||||||
|
@ -164,4 +159,3 @@ def foo():
|
||||||
# A standalone comment
|
# A standalone comment
|
||||||
def bar():
|
def bar():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
from .config import (
|
from .config import (
|
||||||
ConfigTypeAttributes,
|
ConfigTypeAttributes,
|
||||||
Int,
|
Int,
|
||||||
|
@ -26,4 +21,3 @@ def function(a: int = 42):
|
||||||
# There's a NBSP + 3 spaces before
|
# There's a NBSP + 3 spaces before
|
||||||
# And 4 spaces on the next line
|
# And 4 spaces on the next line
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
class C:
|
class C:
|
||||||
def test(self) -> None:
|
def test(self) -> None:
|
||||||
with patch("black.out", print):
|
with patch("black.out", print):
|
||||||
|
@ -184,4 +179,3 @@ class C:
|
||||||
key9: value9,
|
key9: value9,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
class C:
|
class C:
|
||||||
def test(self) -> None:
|
def test(self) -> None:
|
||||||
with patch("black.out", print):
|
with patch("black.out", print):
|
||||||
|
@ -184,4 +179,3 @@ class C:
|
||||||
key9: value9,
|
key9: value9,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
class MyClass:
|
class MyClass:
|
||||||
"""Multiline
|
"""Multiline
|
||||||
class docstring
|
class docstring
|
||||||
|
@ -222,4 +217,3 @@ def stable_quote_normalization_with_immediate_inner_single_quote(self):
|
||||||
|
|
||||||
<text here, since without another non-empty line black is stable>
|
<text here, since without another non-empty line black is stable>
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Make sure when the file ends with class's docstring,
|
# Make sure when the file ends with class's docstring,
|
||||||
# It doesn't add extra blank lines.
|
# It doesn't add extra blank lines.
|
||||||
class ClassWithDocstring:
|
class ClassWithDocstring:
|
||||||
"""A docstring."""
|
"""A docstring."""
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
def docstring_almost_at_line_limit():
|
def docstring_almost_at_line_limit():
|
||||||
"""long docstring................................................................."""
|
"""long docstring................................................................."""
|
||||||
|
|
||||||
|
@ -51,4 +46,3 @@ def single_quote_docstring_over_line_limit():
|
||||||
|
|
||||||
def single_quote_docstring_over_line_limit2():
|
def single_quote_docstring_over_line_limit2():
|
||||||
"We do not want to put the closing quote on a new line as that is invalid (see GH-3141)."
|
"We do not want to put the closing quote on a new line as that is invalid (see GH-3141)."
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
"""Docstring."""
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,4 +87,3 @@ def g():
|
||||||
syms.argument,
|
syms.argument,
|
||||||
}:
|
}:
|
||||||
return NO
|
return NO
|
||||||
|
|
|
@ -1,466 +0,0 @@
|
||||||
--- [Deterministic header]
|
|
||||||
+++ [Deterministic header]
|
|
||||||
@@ -1,8 +1,8 @@
|
|
||||||
...
|
|
||||||
-'some_string'
|
|
||||||
-b'\\xa3'
|
|
||||||
+"some_string"
|
|
||||||
+b"\\xa3"
|
|
||||||
Name
|
|
||||||
None
|
|
||||||
True
|
|
||||||
False
|
|
||||||
1
|
|
||||||
@@ -21,99 +21,135 @@
|
|
||||||
Name1 or (Name2 and Name3) or Name4
|
|
||||||
Name1 or Name2 and Name3 or Name4
|
|
||||||
v1 << 2
|
|
||||||
1 >> v2
|
|
||||||
1 % finished
|
|
||||||
-1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8
|
|
||||||
-((1 + v2) - (v3 * 4)) ^ (((5 ** v6) / 7) // 8)
|
|
||||||
+1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
|
|
||||||
+((1 + v2) - (v3 * 4)) ^ (((5**v6) / 7) // 8)
|
|
||||||
not great
|
|
||||||
~great
|
|
||||||
+value
|
|
||||||
-1
|
|
||||||
~int and not v1 ^ 123 + v2 | True
|
|
||||||
(~int) and (not ((v1 ^ (123 + v2)) | True))
|
|
||||||
-+really ** -confusing ** ~operator ** -precedence
|
|
||||||
-flags & ~ select.EPOLLIN and waiters.write_task is not None
|
|
||||||
++(really ** -(confusing ** ~(operator**-precedence)))
|
|
||||||
+flags & ~select.EPOLLIN and waiters.write_task is not None
|
|
||||||
lambda arg: None
|
|
||||||
lambda a=True: a
|
|
||||||
lambda a, b, c=True: a
|
|
||||||
-lambda a, b, c=True, *, d=(1 << v2), e='str': a
|
|
||||||
-lambda a, b, c=True, *vararg, d=(v1 << 2), e='str', **kwargs: a + b
|
|
||||||
+lambda a, b, c=True, *, d=(1 << v2), e="str": a
|
|
||||||
+lambda a, b, c=True, *vararg, d=(v1 << 2), e="str", **kwargs: a + b
|
|
||||||
manylambdas = lambda x=lambda y=lambda z=1: z: y(): x()
|
|
||||||
-foo = (lambda port_id, ignore_missing: {"port1": port1_resource, "port2": port2_resource}[port_id])
|
|
||||||
+foo = lambda port_id, ignore_missing: {
|
|
||||||
+ "port1": port1_resource,
|
|
||||||
+ "port2": port2_resource,
|
|
||||||
+}[port_id]
|
|
||||||
1 if True else 2
|
|
||||||
str or None if True else str or bytes or None
|
|
||||||
(str or None) if True else (str or bytes or None)
|
|
||||||
str or None if (1 if True else 2) else str or bytes or None
|
|
||||||
(str or None) if (1 if True else 2) else (str or bytes or None)
|
|
||||||
-((super_long_variable_name or None) if (1 if super_long_test_name else 2) else (str or bytes or None))
|
|
||||||
-{'2.7': dead, '3.7': (long_live or die_hard)}
|
|
||||||
-{'2.7': dead, '3.7': (long_live or die_hard), **{'3.6': verygood}}
|
|
||||||
+(
|
|
||||||
+ (super_long_variable_name or None)
|
|
||||||
+ if (1 if super_long_test_name else 2)
|
|
||||||
+ else (str or bytes or None)
|
|
||||||
+)
|
|
||||||
+{"2.7": dead, "3.7": (long_live or die_hard)}
|
|
||||||
+{"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}}
|
|
||||||
{**a, **b, **c}
|
|
||||||
-{'2.7', '3.6', '3.7', '3.8', '3.9', ('4.0' if gilectomy else '3.10')}
|
|
||||||
-({'a': 'b'}, (True or False), (+value), 'string', b'bytes') or None
|
|
||||||
+{"2.7", "3.6", "3.7", "3.8", "3.9", ("4.0" if gilectomy else "3.10")}
|
|
||||||
+({"a": "b"}, (True or False), (+value), "string", b"bytes") or None
|
|
||||||
()
|
|
||||||
(1,)
|
|
||||||
(1, 2)
|
|
||||||
(1, 2, 3)
|
|
||||||
[]
|
|
||||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]
|
|
||||||
-[1, 2, 3,]
|
|
||||||
+[
|
|
||||||
+ 1,
|
|
||||||
+ 2,
|
|
||||||
+ 3,
|
|
||||||
+]
|
|
||||||
[*a]
|
|
||||||
[*range(10)]
|
|
||||||
-[*a, 4, 5,]
|
|
||||||
-[4, *a, 5,]
|
|
||||||
-[this_is_a_very_long_variable_which_will_force_a_delimiter_split, element, another, *more]
|
|
||||||
+[
|
|
||||||
+ *a,
|
|
||||||
+ 4,
|
|
||||||
+ 5,
|
|
||||||
+]
|
|
||||||
+[
|
|
||||||
+ 4,
|
|
||||||
+ *a,
|
|
||||||
+ 5,
|
|
||||||
+]
|
|
||||||
+[
|
|
||||||
+ this_is_a_very_long_variable_which_will_force_a_delimiter_split,
|
|
||||||
+ element,
|
|
||||||
+ another,
|
|
||||||
+ *more,
|
|
||||||
+]
|
|
||||||
{i for i in (1, 2, 3)}
|
|
||||||
-{(i ** 2) for i in (1, 2, 3)}
|
|
||||||
-{(i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}
|
|
||||||
-{((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3)}
|
|
||||||
+{(i**2) for i in (1, 2, 3)}
|
|
||||||
+{(i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c"))}
|
|
||||||
+{((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3)}
|
|
||||||
[i for i in (1, 2, 3)]
|
|
||||||
-[(i ** 2) for i in (1, 2, 3)]
|
|
||||||
-[(i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]
|
|
||||||
-[((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3)]
|
|
||||||
+[(i**2) for i in (1, 2, 3)]
|
|
||||||
+[(i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c"))]
|
|
||||||
+[((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3)]
|
|
||||||
{i: 0 for i in (1, 2, 3)}
|
|
||||||
-{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}
|
|
||||||
+{i: j for i, j in ((1, "a"), (2, "b"), (3, "c"))}
|
|
||||||
{a: b * 2 for a, b in dictionary.items()}
|
|
||||||
{a: b * -2 for a, b in dictionary.items()}
|
|
||||||
-{k: v for k, v in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension}
|
|
||||||
+{
|
|
||||||
+ k: v
|
|
||||||
+ for k, v in this_is_a_very_long_variable_which_will_cause_a_trailing_comma_which_breaks_the_comprehension
|
|
||||||
+}
|
|
||||||
Python3 > Python2 > COBOL
|
|
||||||
Life is Life
|
|
||||||
call()
|
|
||||||
call(arg)
|
|
||||||
-call(kwarg='hey')
|
|
||||||
-call(arg, kwarg='hey')
|
|
||||||
-call(arg, another, kwarg='hey', **kwargs)
|
|
||||||
-call(this_is_a_very_long_variable_which_will_force_a_delimiter_split, arg, another, kwarg='hey', **kwargs) # note: no trailing comma pre-3.6
|
|
||||||
+call(kwarg="hey")
|
|
||||||
+call(arg, kwarg="hey")
|
|
||||||
+call(arg, another, kwarg="hey", **kwargs)
|
|
||||||
+call(
|
|
||||||
+ this_is_a_very_long_variable_which_will_force_a_delimiter_split,
|
|
||||||
+ arg,
|
|
||||||
+ another,
|
|
||||||
+ kwarg="hey",
|
|
||||||
+ **kwargs
|
|
||||||
+) # note: no trailing comma pre-3.6
|
|
||||||
call(*gidgets[:2])
|
|
||||||
call(a, *gidgets[:2])
|
|
||||||
call(**self.screen_kwargs)
|
|
||||||
call(b, **self.screen_kwargs)
|
|
||||||
lukasz.langa.pl
|
|
||||||
call.me(maybe)
|
|
||||||
-1 .real
|
|
||||||
-1.0 .real
|
|
||||||
+(1).real
|
|
||||||
+(1.0).real
|
|
||||||
....__class__
|
|
||||||
list[str]
|
|
||||||
dict[str, int]
|
|
||||||
tuple[str, ...]
|
|
||||||
+tuple[str, int, float, dict[str, int]]
|
|
||||||
tuple[
|
|
||||||
- str, int, float, dict[str, int]
|
|
||||||
-]
|
|
||||||
-tuple[str, int, float, dict[str, int],]
|
|
||||||
+ str,
|
|
||||||
+ int,
|
|
||||||
+ float,
|
|
||||||
+ 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__)
|
|
||||||
)
|
|
||||||
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
|
|
||||||
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
|
|
||||||
)
|
|
||||||
-xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[
|
|
||||||
- ..., List[SomeClass]
|
|
||||||
-] = classmethod(sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)) # type: ignore
|
|
||||||
+xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod(
|
|
||||||
+ sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
|
|
||||||
+) # type: ignore
|
|
||||||
slice[0]
|
|
||||||
slice[0:1]
|
|
||||||
slice[0:1:2]
|
|
||||||
slice[:]
|
|
||||||
slice[:-1]
|
|
||||||
@@ -137,118 +173,199 @@
|
|
||||||
numpy[-(c + 1) :, d]
|
|
||||||
numpy[:, l[-2]]
|
|
||||||
numpy[:, ::-1]
|
|
||||||
numpy[np.newaxis, :]
|
|
||||||
(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None)
|
|
||||||
-{'2.7': dead, '3.7': long_live or die_hard}
|
|
||||||
-{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}
|
|
||||||
+{"2.7": dead, "3.7": long_live or die_hard}
|
|
||||||
+{"2.7", "3.6", "3.7", "3.8", "3.9", "4.0" if gilectomy else "3.10"}
|
|
||||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]
|
|
||||||
(SomeName)
|
|
||||||
SomeName
|
|
||||||
(Good, Bad, Ugly)
|
|
||||||
(i for i in (1, 2, 3))
|
|
||||||
-((i ** 2) for i in (1, 2, 3))
|
|
||||||
-((i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))
|
|
||||||
-(((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3))
|
|
||||||
+((i**2) for i in (1, 2, 3))
|
|
||||||
+((i**2) for i, _ in ((1, "a"), (2, "b"), (3, "c")))
|
|
||||||
+(((i**2) + j) for i in (1, 2, 3) for j in (1, 2, 3))
|
|
||||||
(*starred,)
|
|
||||||
-{"id": "1","type": "type","started_at": now(),"ended_at": now() + timedelta(days=10),"priority": 1,"import_session_id": 1,**kwargs}
|
|
||||||
+{
|
|
||||||
+ "id": "1",
|
|
||||||
+ "type": "type",
|
|
||||||
+ "started_at": now(),
|
|
||||||
+ "ended_at": now() + timedelta(days=10),
|
|
||||||
+ "priority": 1,
|
|
||||||
+ "import_session_id": 1,
|
|
||||||
+ **kwargs,
|
|
||||||
+}
|
|
||||||
a = (1,)
|
|
||||||
-b = 1,
|
|
||||||
+b = (1,)
|
|
||||||
c = 1
|
|
||||||
d = (1,) + a + (2,)
|
|
||||||
e = (1,).count(1)
|
|
||||||
f = 1, *range(10)
|
|
||||||
g = 1, *"ten"
|
|
||||||
-what_is_up_with_those_new_coord_names = (coord_names + set(vars_to_create)) + set(vars_to_remove)
|
|
||||||
-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(models.Customer.account_id == account_id, models.Customer.email == email_address).order_by(models.Customer.id.asc()).all()
|
|
||||||
-result = session.query(models.Customer.id).filter(models.Customer.account_id == account_id, models.Customer.email == email_address).order_by(models.Customer.id.asc(),).all()
|
|
||||||
+what_is_up_with_those_new_coord_names = (coord_names + set(vars_to_create)) + set(
|
|
||||||
+ vars_to_remove
|
|
||||||
+)
|
|
||||||
+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(
|
|
||||||
+ models.Customer.account_id == account_id, models.Customer.email == email_address
|
|
||||||
+ )
|
|
||||||
+ .order_by(models.Customer.id.asc())
|
|
||||||
+ .all()
|
|
||||||
+)
|
|
||||||
+result = (
|
|
||||||
+ session.query(models.Customer.id)
|
|
||||||
+ .filter(
|
|
||||||
+ models.Customer.account_id == account_id, models.Customer.email == email_address
|
|
||||||
+ )
|
|
||||||
+ .order_by(
|
|
||||||
+ models.Customer.id.asc(),
|
|
||||||
+ )
|
|
||||||
+ .all()
|
|
||||||
+)
|
|
||||||
Ø = set()
|
|
||||||
authors.łukasz.say_thanks()
|
|
||||||
mapping = {
|
|
||||||
A: 0.25 * (10.0 / 12),
|
|
||||||
B: 0.1 * (10.0 / 12),
|
|
||||||
C: 0.1 * (10.0 / 12),
|
|
||||||
D: 0.1 * (10.0 / 12),
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
def gen():
|
|
||||||
yield from outside_of_generator
|
|
||||||
- a = (yield)
|
|
||||||
- b = ((yield))
|
|
||||||
- c = (((yield)))
|
|
||||||
+ a = yield
|
|
||||||
+ b = yield
|
|
||||||
+ c = yield
|
|
||||||
+
|
|
||||||
|
|
||||||
async def f():
|
|
||||||
await some.complicated[0].call(with_args=(True or (1 is not 1)))
|
|
||||||
-print(* [] or [1])
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+print(*[] or [1])
|
|
||||||
print(**{1: 3} if False else {x: x for x in range(3)})
|
|
||||||
-print(* lambda x: x)
|
|
||||||
-assert(not Test),("Short message")
|
|
||||||
-assert this is ComplexTest and not requirements.fit_in_a_single_line(force=False), "Short message"
|
|
||||||
-assert(((parens is TooMany)))
|
|
||||||
-for x, in (1,), (2,), (3,): ...
|
|
||||||
-for y in (): ...
|
|
||||||
-for z in (i for i in (1, 2, 3)): ...
|
|
||||||
-for i in (call()): ...
|
|
||||||
-for j in (1 + (2 + 3)): ...
|
|
||||||
-while(this and that): ...
|
|
||||||
-for addr_family, addr_type, addr_proto, addr_canonname, addr_sockaddr in socket.getaddrinfo('google.com', 'http'):
|
|
||||||
+print(*lambda x: x)
|
|
||||||
+assert not Test, "Short message"
|
|
||||||
+assert this is ComplexTest and not requirements.fit_in_a_single_line(
|
|
||||||
+ force=False
|
|
||||||
+), "Short message"
|
|
||||||
+assert parens is TooMany
|
|
||||||
+for (x,) in (1,), (2,), (3,):
|
|
||||||
+ ...
|
|
||||||
+for y in ():
|
|
||||||
+ ...
|
|
||||||
+for z in (i for i in (1, 2, 3)):
|
|
||||||
+ ...
|
|
||||||
+for i in call():
|
|
||||||
+ ...
|
|
||||||
+for j in 1 + (2 + 3):
|
|
||||||
+ ...
|
|
||||||
+while this and that:
|
|
||||||
+ ...
|
|
||||||
+for (
|
|
||||||
+ addr_family,
|
|
||||||
+ addr_type,
|
|
||||||
+ addr_proto,
|
|
||||||
+ addr_canonname,
|
|
||||||
+ addr_sockaddr,
|
|
||||||
+) in socket.getaddrinfo("google.com", "http"):
|
|
||||||
pass
|
|
||||||
-a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
-a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp not in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
-a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp is qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
-a = aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp is not qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
-if (
|
|
||||||
- threading.current_thread() != threading.main_thread() and
|
|
||||||
- threading.current_thread() != threading.main_thread() or
|
|
||||||
- signal.getsignal(signal.SIGINT) != signal.default_int_handler
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /
|
|
||||||
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- ~ aaaa.a + aaaa.b - aaaa.c * aaaa.d / aaaa.e | aaaa.f & aaaa.g % aaaa.h ^ aaaa.i << aaaa.k >> aaaa.l ** aaaa.m // aaaa.n
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- ~ aaaaaaaa.a + aaaaaaaa.b - aaaaaaaa.c @ aaaaaaaa.d / aaaaaaaa.e | aaaaaaaa.f & aaaaaaaa.g % aaaaaaaa.h ^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l ** aaaaaaaa.m // aaaaaaaa.n
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-if (
|
|
||||||
- ~ aaaaaaaaaaaaaaaa.a + aaaaaaaaaaaaaaaa.b - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e | aaaaaaaaaaaaaaaa.f & aaaaaaaaaaaaaaaa.g % aaaaaaaaaaaaaaaa.h ^ aaaaaaaaaaaaaaaa.i << aaaaaaaaaaaaaaaa.k >> aaaaaaaaaaaaaaaa.l ** aaaaaaaaaaaaaaaa.m // aaaaaaaaaaaaaaaa.n
|
|
||||||
-):
|
|
||||||
- return True
|
|
||||||
-aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaa * (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa) / (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
|
|
||||||
+a = (
|
|
||||||
+ aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
|
|
||||||
+ in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
+)
|
|
||||||
+a = (
|
|
||||||
+ aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
|
|
||||||
+ not in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
+)
|
|
||||||
+a = (
|
|
||||||
+ aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
|
|
||||||
+ is qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
+)
|
|
||||||
+a = (
|
|
||||||
+ aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
|
|
||||||
+ is not qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
|
||||||
+)
|
|
||||||
+if (
|
|
||||||
+ threading.current_thread() != threading.main_thread()
|
|
||||||
+ and threading.current_thread() != threading.main_thread()
|
|
||||||
+ or signal.getsignal(signal.SIGINT) != signal.default_int_handler
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ / aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ ~aaaa.a + aaaa.b - aaaa.c * aaaa.d / aaaa.e
|
|
||||||
+ | aaaa.f & aaaa.g % aaaa.h ^ aaaa.i << aaaa.k >> aaaa.l**aaaa.m // aaaa.n
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ ~aaaaaaaa.a + aaaaaaaa.b - aaaaaaaa.c @ aaaaaaaa.d / aaaaaaaa.e
|
|
||||||
+ | aaaaaaaa.f & aaaaaaaa.g % aaaaaaaa.h
|
|
||||||
+ ^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+if (
|
|
||||||
+ ~aaaaaaaaaaaaaaaa.a
|
|
||||||
+ + aaaaaaaaaaaaaaaa.b
|
|
||||||
+ - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e
|
|
||||||
+ | aaaaaaaaaaaaaaaa.f & aaaaaaaaaaaaaaaa.g % aaaaaaaaaaaaaaaa.h
|
|
||||||
+ ^ aaaaaaaaaaaaaaaa.i
|
|
||||||
+ << aaaaaaaaaaaaaaaa.k
|
|
||||||
+ >> aaaaaaaaaaaaaaaa.l**aaaaaaaaaaaaaaaa.m // aaaaaaaaaaaaaaaa.n
|
|
||||||
+):
|
|
||||||
+ return True
|
|
||||||
+(
|
|
||||||
+ aaaaaaaaaaaaaaaa
|
|
||||||
+ + aaaaaaaaaaaaaaaa
|
|
||||||
+ - aaaaaaaaaaaaaaaa
|
|
||||||
+ * (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
|
|
||||||
+ / (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
|
|
||||||
+)
|
|
||||||
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa
|
|
||||||
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+(
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+)
|
|
||||||
bbbb >> bbbb * bbbb
|
|
||||||
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ^bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+(
|
|
||||||
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ ^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+ ^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
||||||
+)
|
|
||||||
last_call()
|
|
||||||
# standalone comment at ENDMARKER
|
|
|
@ -1,9 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
...
|
|
||||||
"some_string"
|
"some_string"
|
||||||
b"\\xa3"
|
b"\\xa3"
|
||||||
Name
|
Name
|
||||||
|
@ -374,4 +368,3 @@ bbbb >> bbbb * bbbb
|
||||||
)
|
)
|
||||||
last_call()
|
last_call()
|
||||||
# standalone comment at ENDMARKER
|
# standalone comment at ENDMARKER
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
@ -227,4 +222,3 @@ yield 'hello'
|
||||||
l=[1,2,3]
|
l=[1,2,3]
|
||||||
d={'a':1,
|
d={'a':1,
|
||||||
'b':2}
|
'b':2}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
TmSt = 1
|
TmSt = 1
|
||||||
|
@ -43,4 +38,3 @@ def test_calculate_fades():
|
||||||
]
|
]
|
||||||
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
x = [
|
x = [
|
||||||
1, 2,
|
1, 2,
|
||||||
|
@ -18,4 +13,3 @@ x = [
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
x = [1, 2, 3, 4]
|
x = [1, 2, 3, 4]
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
@test([
|
@test([
|
||||||
1, 2,
|
1, 2,
|
||||||
|
@ -23,4 +18,3 @@ def f():
|
||||||
)
|
)
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Regression test for https://github.com/psf/black/issues/3129.
|
# Regression test for https://github.com/psf/black/issues/3129.
|
||||||
setup(
|
setup(
|
||||||
entry_points={
|
entry_points={
|
||||||
|
@ -90,4 +85,3 @@ if x:
|
||||||
elif unformatted:
|
elif unformatted:
|
||||||
# fmt: on
|
# fmt: on
|
||||||
will_be_formatted()
|
will_be_formatted()
|
||||||
|
|
3
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py.expect
vendored
Normal file
3
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py.expect
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
a, b = 1, 2
|
||||||
|
c = 6 # fmt: skip
|
||||||
|
d = 5
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
l1 = [
|
l1 = [
|
||||||
"This list should be broken up",
|
"This list should be broken up",
|
||||||
"into multiple lines",
|
"into multiple lines",
|
||||||
|
@ -14,4 +9,3 @@ l3 = [
|
||||||
"trailing comma",
|
"trailing comma",
|
||||||
"so I should be braked",
|
"so I should be braked",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
a = 3
|
a = 3
|
||||||
# fmt: off
|
# fmt: off
|
||||||
b, c = 1, 2
|
b, c = 1, 2
|
||||||
|
@ -13,4 +8,3 @@ f = [
|
||||||
"This is a very long line that should be formatted into a clearer line ",
|
"This is a very long line that should be formatted into a clearer line ",
|
||||||
"by rearranging.",
|
"by rearranging.",
|
||||||
]
|
]
|
||||||
|
|
7
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py.expect
vendored
Normal file
7
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py.expect
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
a = 2
|
||||||
|
# fmt: skip
|
||||||
|
l = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
]
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
a, b, c = 3, 4, 5
|
a, b, c = 3, 4, 5
|
||||||
if (
|
if (
|
||||||
a == 3
|
a == 3
|
||||||
|
@ -12,4 +7,3 @@ if (
|
||||||
print("I'm good!")
|
print("I'm good!")
|
||||||
else:
|
else:
|
||||||
print("I'm bad")
|
print("I'm bad")
|
||||||
|
|
5
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py.expect
vendored
Normal file
5
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py.expect
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class A:
|
||||||
|
def f(self):
|
||||||
|
for line in range(10):
|
||||||
|
if True:
|
||||||
|
pass # fmt: skip
|
|
@ -1,10 +1,4 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
a = "this is some code"
|
a = "this is some code"
|
||||||
b = 5 # fmt:skip
|
b = 5 # fmt:skip
|
||||||
c = 9 # fmt: skip
|
c = 9 # fmt: skip
|
||||||
d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" # fmt:skip
|
d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" # fmt:skip
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Make sure a leading comment is not removed.
|
# Make sure a leading comment is not removed.
|
||||||
def some_func( unformatted, args ): # fmt: skip
|
def some_func( unformatted, args ): # fmt: skip
|
||||||
print("I am some_func")
|
print("I am some_func")
|
||||||
|
@ -65,4 +60,3 @@ with give_me_context( unformatted, args ): # fmt: skip
|
||||||
async def test_async_with():
|
async def test_async_with():
|
||||||
async with give_me_async_context( unformatted, args ): # fmt: skip
|
async with give_me_async_context( unformatted, args ): # fmt: skip
|
||||||
print("Do something")
|
print("Do something")
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
f"f-string without formatted values is just a string"
|
f"f-string without formatted values is just a string"
|
||||||
f"{{NOT a formatted value}}"
|
f"{{NOT a formatted value}}"
|
||||||
f'{{NOT \'a\' "formatted" "value"}}'
|
f'{{NOT \'a\' "formatted" "value"}}'
|
||||||
|
@ -12,4 +7,3 @@ f"{f'''{'nested'} inner'''} outer"
|
||||||
f"\"{f'{nested} inner'}\" outer"
|
f"\"{f'{nested} inner'}\" outer"
|
||||||
f"space between opening braces: { {a for a in (1, 2, 3)}}"
|
f"space between opening braces: { {a for a in (1, 2, 3)}}"
|
||||||
f'Hello \'{tricky + "example"}\''
|
f'Hello \'{tricky + "example"}\''
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
@ -151,4 +146,3 @@ def f(
|
||||||
|
|
||||||
def __await__():
|
def __await__():
|
||||||
return (yield)
|
return (yield)
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
---
|
|
||||||
source: crates/ruff_python_formatter/src/lib.rs
|
|
||||||
expression: adjust_quotes(formatted.print()?.as_code())
|
|
||||||
---
|
|
||||||
def f(
|
def f(
|
||||||
a,
|
a,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
@ -68,4 +64,3 @@ else:
|
||||||
|
|
||||||
with hmm_but_this_should_get_two_preceding_newlines():
|
with hmm_but_this_should_get_two_preceding_newlines():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
def f(
|
def f(
|
||||||
a,
|
a,
|
||||||
):
|
):
|
||||||
|
@ -117,4 +112,3 @@ some_module.some_function(
|
||||||
argument5,
|
argument5,
|
||||||
argument6,
|
argument6,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
"""The asyncio package, tracking PEP 3156."""
|
"""The asyncio package, tracking PEP 3156."""
|
||||||
|
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
|
@ -67,4 +62,3 @@ __all__ = (
|
||||||
+ streams.__all__
|
+ streams.__all__
|
||||||
+ tasks.__all__
|
+ tasks.__all__
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# We should not treat the trailing comma
|
# We should not treat the trailing comma
|
||||||
# in a single-element subscript.
|
# in a single-element subscript.
|
||||||
a: tuple[int,]
|
a: tuple[int,]
|
||||||
|
@ -25,4 +20,3 @@ small_list = [
|
||||||
list_of_types = [
|
list_of_types = [
|
||||||
tuple[int,],
|
tuple[int,],
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
def function(**kwargs):
|
def function(**kwargs):
|
||||||
t = a**2 + b**3
|
t = a**2 + b**3
|
||||||
return t**2
|
return t**2
|
||||||
|
@ -66,4 +61,3 @@ if hasattr(view, "sum_of_weights"):
|
||||||
return np.divide(
|
return np.divide(
|
||||||
where=view.sum_of_weights_of_weight_long**2 > view.sum_of_weights_squared, # type: ignore
|
where=view.sum_of_weights_of_weight_long**2 > view.sum_of_weights_squared, # type: ignore
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Test cases separate from `prefer_rhs_split.py` that contains unformatted source.
|
# Test cases separate from `prefer_rhs_split.py` that contains unformatted source.
|
||||||
|
|
||||||
# Left hand side fits in a single line but will still be exploded by the
|
# Left hand side fits in a single line but will still be exploded by the
|
||||||
|
@ -24,4 +19,3 @@ expression: formatted
|
||||||
xxxxxxxxx_yyy_zzzzzzzz[
|
xxxxxxxxx_yyy_zzzzzzzz[
|
||||||
xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1)
|
xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1)
|
||||||
] = 1
|
] = 1
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,4 +91,3 @@ async def main():
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
await (yield)
|
await (yield)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# These brackets are redundant, therefore remove.
|
# These brackets are redundant, therefore remove.
|
||||||
try:
|
try:
|
||||||
a.something
|
a.something
|
||||||
|
@ -45,4 +40,3 @@ except (
|
||||||
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
|
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
|
||||||
) as err:
|
) as err:
|
||||||
raise err
|
raise err
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Only remove tuple brackets after `for`
|
# Only remove tuple brackets after `for`
|
||||||
for k, v in d.items():
|
for k, v in d.items():
|
||||||
print(k, v)
|
print(k, v)
|
||||||
|
@ -30,4 +25,3 @@ for (
|
||||||
# Test deeply nested brackets
|
# Test deeply nested brackets
|
||||||
for k, v in d.items():
|
for k, v in d.items():
|
||||||
print(k, v)
|
print(k, v)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,4 +76,3 @@ with open("/path/to/file.txt", mode="w") as file:
|
||||||
with open("/path/to/file.txt", mode="r") as read_file:
|
with open("/path/to/file.txt", mode="r") as read_file:
|
||||||
with open("/path/to/output_file.txt", mode="w") as write_file:
|
with open("/path/to/output_file.txt", mode="w") as write_file:
|
||||||
write_file.writelines(read_file.readlines())
|
write_file.writelines(read_file.readlines())
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
x = 1
|
x = 1
|
||||||
x = 1.2
|
x = 1.2
|
||||||
|
|
||||||
|
@ -88,4 +83,3 @@ def example7():
|
||||||
|
|
||||||
def example8():
|
def example8():
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# Control
|
# Control
|
||||||
def double(a: int) -> int:
|
def double(a: int) -> int:
|
||||||
return 2 * a
|
return 2 * a
|
||||||
|
@ -123,4 +118,3 @@ def foo() -> (
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
return 2
|
return 2
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
# We should not remove the trailing comma in a single-element subscript.
|
# We should not remove the trailing comma in a single-element subscript.
|
||||||
a: tuple[int,]
|
a: tuple[int,]
|
||||||
b = tuple[int,]
|
b = tuple[int,]
|
||||||
|
@ -28,4 +23,3 @@ func1(arg1).func2(arg2).func3(arg3).func4(arg4).func5(arg5)
|
||||||
(a, b, c, d) = func1(arg1) and func2(arg2)
|
(a, b, c, d) = func1(arg1) and func2(arg2)
|
||||||
|
|
||||||
func(argument1, (one, two), argument4, argument5, argument6)
|
func(argument1, (one, two), argument4, argument5, argument6)
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
slice[a.b : c.d]
|
slice[a.b : c.d]
|
||||||
slice[d :: d + 1]
|
slice[d :: d + 1]
|
||||||
slice[d + 1 :: d]
|
slice[d + 1 :: d]
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
name = "Łukasz"
|
name = "Łukasz"
|
||||||
|
@ -23,4 +18,3 @@ def docstring_multiline():
|
||||||
R"""
|
R"""
|
||||||
clear out all of the issues opened in that time :p
|
clear out all of the issues opened in that time :p
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
importA
|
importA
|
||||||
(
|
(
|
||||||
()
|
()
|
||||||
|
@ -61,4 +56,3 @@ assert a_function(
|
||||||
very_long_arguments_that_surpass_the_limit,
|
very_long_arguments_that_surpass_the_limit,
|
||||||
which_is_eighty_eight_in_this_case_plus_a_bit_more,
|
which_is_eighty_eight_in_this_case_plus_a_bit_more,
|
||||||
) == {"x": "this need to pass the line limit as well", "b": "but only by a little bit"}
|
) == {"x": "this need to pass the line limit as well", "b": "but only by a little bit"}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
if e1234123412341234.winerror not in (
|
if e1234123412341234.winerror not in (
|
||||||
_winapi.ERROR_SEM_TIMEOUT,
|
_winapi.ERROR_SEM_TIMEOUT,
|
||||||
_winapi.ERROR_PIPE_BUSY,
|
_winapi.ERROR_PIPE_BUSY,
|
||||||
|
@ -37,4 +32,3 @@ class A:
|
||||||
3,
|
3,
|
||||||
) < self.connection.mysql_version < (10, 5, 2):
|
) < self.connection.mysql_version < (10, 5, 2):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
if e123456.get_tk_patchlevel() >= (8, 6, 0, "final") or (
|
if e123456.get_tk_patchlevel() >= (8, 6, 0, "final") or (
|
||||||
8,
|
8,
|
||||||
5,
|
5,
|
||||||
8,
|
8,
|
||||||
) <= get_tk_patchlevel() < (8, 6):
|
) <= get_tk_patchlevel() < (8, 6):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
if True:
|
if True:
|
||||||
if True:
|
if True:
|
||||||
if True:
|
if True:
|
||||||
|
@ -11,4 +6,3 @@ if True:
|
||||||
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
|
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
|
||||||
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
|
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
|
||||||
) % {"reported_username": reported_username, "report_reason": report_reason}
|
) % {"reported_username": reported_username, "report_reason": report_reason}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
zero(
|
zero(
|
||||||
one,
|
one,
|
||||||
).two(
|
).two(
|
||||||
|
@ -53,4 +48,3 @@ assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
|
||||||
).xxxxxxxxxxxxxxxxxx(), (
|
).xxxxxxxxxxxxxxxxxx(), (
|
||||||
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
ä = 1
|
||||||
|
µ = 2
|
||||||
|
蟒 = 3
|
||||||
|
x󠄀 = 4
|
||||||
|
មុ = 1
|
||||||
|
Q̇_per_meter = 4
|
||||||
|
|
||||||
|
A᧚ = 3
|
||||||
|
A፩ = 8
|
|
@ -1,7 +1,3 @@
|
||||||
---
|
|
||||||
source: crates/ruff_python_formatter/src/lib.rs
|
|
||||||
expression: formatted.print()?.as_code()
|
|
||||||
---
|
|
||||||
# This is a standalone comment.
|
# This is a standalone comment.
|
||||||
(
|
(
|
||||||
sdfjklsdfsjldkflkjsf,
|
sdfjklsdfsjldkflkjsf,
|
0
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py.expect
vendored
Normal file
0
crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py.expect
vendored
Normal file
|
@ -20,8 +20,6 @@ mod format;
|
||||||
mod newlines;
|
mod newlines;
|
||||||
mod parentheses;
|
mod parentheses;
|
||||||
pub mod shared_traits;
|
pub mod shared_traits;
|
||||||
#[cfg(test)]
|
|
||||||
mod test;
|
|
||||||
pub mod trivia;
|
pub mod trivia;
|
||||||
|
|
||||||
pub fn fmt(contents: &str) -> Result<Formatted<ASTFormatContext>> {
|
pub fn fmt(contents: &str) -> Result<Formatted<ASTFormatContext>> {
|
||||||
|
@ -57,70 +55,98 @@ pub fn fmt(contents: &str) -> Result<Formatted<ASTFormatContext>> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use test_case::test_case;
|
|
||||||
|
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::test::test_resource_path;
|
use ruff_testing_macros::fixture;
|
||||||
|
use similar::TextDiff;
|
||||||
|
use std::fmt::{Formatter, Write};
|
||||||
|
|
||||||
|
#[fixture(
|
||||||
|
pattern = "resources/test/fixtures/black/**/*.py",
|
||||||
|
// Excluded tests because they reach unreachable when attaching tokens
|
||||||
|
exclude = [
|
||||||
|
"*comments.py",
|
||||||
|
"*comments[3,5,8].py",
|
||||||
|
"*comments_non_breaking_space.py",
|
||||||
|
"*docstring_preview.py",
|
||||||
|
"*docstring.py",
|
||||||
|
"*fmtonoff.py",
|
||||||
|
"*fmtskip8.py",
|
||||||
|
])
|
||||||
|
]
|
||||||
|
#[test]
|
||||||
|
fn black_test(input_path: &Path) -> Result<()> {
|
||||||
|
let content = fs::read_to_string(input_path)?;
|
||||||
|
|
||||||
#[test_case(Path::new("simple_cases/beginning_backslash.py"); "beginning_backslash")]
|
|
||||||
#[test_case(Path::new("simple_cases/class_blank_parentheses.py"); "class_blank_parentheses")]
|
|
||||||
#[test_case(Path::new("simple_cases/class_methods_new_line.py"); "class_methods_new_line")]
|
|
||||||
#[test_case(Path::new("simple_cases/import_spacing.py"); "import_spacing")]
|
|
||||||
#[test_case(Path::new("simple_cases/one_element_subscript.py"); "one_element_subscript")]
|
|
||||||
#[test_case(Path::new("simple_cases/power_op_spacing.py"); "power_op_spacing")]
|
|
||||||
#[test_case(Path::new("simple_cases/remove_newline_after_code_block_open.py"); "remove_newline_after_code_block_open")]
|
|
||||||
#[test_case(Path::new("simple_cases/slices.py"); "slices")]
|
|
||||||
#[test_case(Path::new("simple_cases/tricky_unicode_symbols.py"); "tricky_unicode_symbols")]
|
|
||||||
// Passing except that `1, 2, 3,` should be `(1, 2, 3)`.
|
|
||||||
#[test_case(Path::new("simple_cases/tupleassign.py"); "tupleassign")]
|
|
||||||
// Passing except that `CliRunner().invoke(...)` arguments are improperly wrapped.
|
|
||||||
#[test_case(Path::new("simple_cases/function2.py"); "function2")]
|
|
||||||
fn passing(path: &Path) -> Result<()> {
|
|
||||||
let snapshot = format!("{}", path.display());
|
|
||||||
let content = std::fs::read_to_string(test_resource_path(
|
|
||||||
Path::new("fixtures/black").join(path).as_path(),
|
|
||||||
))?;
|
|
||||||
let formatted = fmt(&content)?;
|
let formatted = fmt(&content)?;
|
||||||
insta::assert_display_snapshot!(snapshot, formatted.print()?.as_code());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case(Path::new("simple_cases/collections.py"); "collections")]
|
let expected_path = input_path.with_extension("py.expect");
|
||||||
#[test_case(Path::new("simple_cases/bracketmatch.py"); "bracketmatch")]
|
let expected_output = fs::read_to_string(&expected_path)
|
||||||
fn passing_modulo_string_normalization(path: &Path) -> Result<()> {
|
.unwrap_or_else(|_| panic!("Expected Black output file '{expected_path:?}' to exist"));
|
||||||
fn adjust_quotes(contents: &str) -> String {
|
|
||||||
// Replace all single quotes with double quotes.
|
let printed = formatted.print()?;
|
||||||
contents.replace('\'', "\"")
|
let formatted_code = printed.as_code();
|
||||||
|
|
||||||
|
if formatted_code == expected_output {
|
||||||
|
// Black and Ruff formatting matches. Delete any existing snapshot files because the Black output
|
||||||
|
// already perfectly captures the expected output.
|
||||||
|
// The following code mimics insta's logic generating the snapshot name for a test.
|
||||||
|
let workspace_path = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
let snapshot_name = insta::_function_name!()
|
||||||
|
.strip_prefix(&format!("{}::", module_path!()))
|
||||||
|
.unwrap();
|
||||||
|
let module_path = module_path!().replace("::", "__");
|
||||||
|
|
||||||
|
let snapshot_path = Path::new(&workspace_path)
|
||||||
|
.join("src/snapshots")
|
||||||
|
.join(&format!(
|
||||||
|
"{module_path}__{}.snap",
|
||||||
|
snapshot_name.replace(&['/', '\\'][..], "__")
|
||||||
|
));
|
||||||
|
|
||||||
|
if snapshot_path.exists() && snapshot_path.is_file() {
|
||||||
|
// SAFETY: This is a convenience feature. That's why we don't want to abort
|
||||||
|
// when deleting a no longer needed snapshot fails.
|
||||||
|
fs::remove_file(&snapshot_path).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_snapshot_path = snapshot_path.with_extension("snap.new");
|
||||||
|
if new_snapshot_path.exists() && new_snapshot_path.is_file() {
|
||||||
|
// SAFETY: This is a convenience feature. That's why we don't want to abort
|
||||||
|
// when deleting a no longer needed snapshot fails.
|
||||||
|
fs::remove_file(&new_snapshot_path).ok();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Black and Ruff have different formatting. Write out a snapshot that covers the differences
|
||||||
|
// today.
|
||||||
|
let mut snapshot = String::new();
|
||||||
|
write!(snapshot, "{}", Header::new("Input"))?;
|
||||||
|
write!(snapshot, "{}", CodeFrame::new("py", &content))?;
|
||||||
|
|
||||||
|
write!(snapshot, "{}", Header::new("Black Differences"))?;
|
||||||
|
|
||||||
|
let diff = TextDiff::from_lines(expected_output.as_str(), formatted_code)
|
||||||
|
.unified_diff()
|
||||||
|
.header("Black", "Ruff")
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
write!(snapshot, "{}", CodeFrame::new("diff", &diff))?;
|
||||||
|
|
||||||
|
write!(snapshot, "{}", Header::new("Ruff Output"))?;
|
||||||
|
write!(snapshot, "{}", CodeFrame::new("py", formatted_code))?;
|
||||||
|
|
||||||
|
write!(snapshot, "{}", Header::new("Black Output"))?;
|
||||||
|
write!(snapshot, "{}", CodeFrame::new("py", &expected_output))?;
|
||||||
|
|
||||||
|
insta::with_settings!({ omit_expression => false, input_file => input_path }, {
|
||||||
|
insta::assert_snapshot!(snapshot);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let snapshot = format!("{}", path.display());
|
|
||||||
let content = std::fs::read_to_string(test_resource_path(
|
|
||||||
Path::new("fixtures/black").join(path).as_path(),
|
|
||||||
))?;
|
|
||||||
let formatted = fmt(&content)?;
|
|
||||||
insta::assert_display_snapshot!(snapshot, adjust_quotes(formatted.print()?.as_code()));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ignore]
|
|
||||||
// Lots of deviations, _mostly_ related to string normalization and wrapping.
|
|
||||||
#[test_case(Path::new("simple_cases/expression.py"); "expression")]
|
|
||||||
// Passing apart from a trailing end-of-line comment within an if statement, which is being
|
|
||||||
// inappropriately associated with the if statement rather than the line it's on.
|
|
||||||
#[test_case(Path::new("simple_cases/comments.py"); "comments")]
|
|
||||||
#[test_case(Path::new("simple_cases/function.py"); "function")]
|
|
||||||
#[test_case(Path::new("simple_cases/function_trailing_comma.py"); "function_trailing_comma")]
|
|
||||||
#[test_case(Path::new("simple_cases/composition.py"); "composition")]
|
|
||||||
fn failing(path: &Path) -> Result<()> {
|
|
||||||
let snapshot = format!("{}", path.display());
|
|
||||||
let content = std::fs::read_to_string(test_resource_path(
|
|
||||||
Path::new("fixtures/black").join(path).as_path(),
|
|
||||||
))?;
|
|
||||||
let formatted = fmt(&content)?;
|
|
||||||
insta::assert_display_snapshot!(snapshot, formatted.print()?.as_code());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,4 +176,41 @@ mod tests {
|
||||||
}"#
|
}"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Header<'a> {
|
||||||
|
title: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Header<'a> {
|
||||||
|
fn new(title: &'a str) -> Self {
|
||||||
|
Self { title }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Header<'_> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "## {}", self.title)?;
|
||||||
|
writeln!(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CodeFrame<'a> {
|
||||||
|
language: &'a str,
|
||||||
|
code: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CodeFrame<'a> {
|
||||||
|
fn new(language: &'a str, code: &'a str) -> Self {
|
||||||
|
Self { language, code }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for CodeFrame<'_> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "```{}", self.language)?;
|
||||||
|
writeln!(f, "{}", self.code)?;
|
||||||
|
writeln!(f, "```")?;
|
||||||
|
writeln!(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
def bob(): # pylint: disable=W9016
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def bobtwo(): # some comment here
|
|
||||||
pass
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
a, b = 1, 2
|
|
||||||
c = 6 # fmt: skip
|
|
||||||
d = 5
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
a = 2
|
|
||||||
# fmt: skip
|
|
||||||
l = [
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
]
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
class A:
|
|
||||||
def f(self):
|
|
||||||
for line in range(10):
|
|
||||||
if True:
|
|
||||||
pass # fmt: skip
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
source: src/source_code/mod.rs
|
|
||||||
assertion_line: 0
|
|
||||||
expression: formatted
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/attribute_access_on_number_literals.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
x = 123456789 .bit_count()
|
||||||
|
x = (123456).__abs__()
|
||||||
|
x = .1.is_integer()
|
||||||
|
x = 1. .imag
|
||||||
|
x = 1E+1.imag
|
||||||
|
x = 1E-1.real
|
||||||
|
x = 123456789.123456789.hex()
|
||||||
|
x = 123456789.123456789E123456789 .real
|
||||||
|
x = 123456789E123456789 .conjugate()
|
||||||
|
x = 123456789J.real
|
||||||
|
x = 123456789.123456789J.__add__(0b1011.bit_length())
|
||||||
|
x = 0XB1ACC.conjugate()
|
||||||
|
x = 0B1011 .conjugate()
|
||||||
|
x = 0O777 .real
|
||||||
|
x = 0.000000006 .hex()
|
||||||
|
x = -100.0000J
|
||||||
|
|
||||||
|
if 10 .real:
|
||||||
|
...
|
||||||
|
|
||||||
|
y = 100[no]
|
||||||
|
y = 100(no)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,22 +1,22 @@
|
||||||
|
-x = (123456789).bit_count()
|
||||||
|
+x = 123456789.bit_count()
|
||||||
|
x = (123456).__abs__()
|
||||||
|
-x = (0.1).is_integer()
|
||||||
|
-x = (1.0).imag
|
||||||
|
-x = (1e1).imag
|
||||||
|
-x = (1e-1).real
|
||||||
|
-x = (123456789.123456789).hex()
|
||||||
|
-x = (123456789.123456789e123456789).real
|
||||||
|
-x = (123456789e123456789).conjugate()
|
||||||
|
-x = 123456789j.real
|
||||||
|
-x = 123456789.123456789j.__add__(0b1011.bit_length())
|
||||||
|
-x = 0xB1ACC.conjugate()
|
||||||
|
-x = 0b1011.conjugate()
|
||||||
|
-x = 0o777.real
|
||||||
|
-x = (0.000000006).hex()
|
||||||
|
-x = -100.0000j
|
||||||
|
+x = .1.is_integer()
|
||||||
|
+x = 1..imag
|
||||||
|
+x = 1E+1.imag
|
||||||
|
+x = 1E-1.real
|
||||||
|
+x = 123456789.123456789.hex()
|
||||||
|
+x = 123456789.123456789E123456789.real
|
||||||
|
+x = 123456789E123456789.conjugate()
|
||||||
|
+x = 123456789J.real
|
||||||
|
+x = 123456789.123456789J.__add__(0b1011.bit_length())
|
||||||
|
+x = 0XB1ACC.conjugate()
|
||||||
|
+x = 0B1011.conjugate()
|
||||||
|
+x = 0O777.real
|
||||||
|
+x = 0.000000006.hex()
|
||||||
|
+x = -100.0000J
|
||||||
|
|
||||||
|
-if (10).real:
|
||||||
|
+if 10.real:
|
||||||
|
...
|
||||||
|
|
||||||
|
y = 100[no]
|
||||||
|
-y = 100(no)
|
||||||
|
\ No newline at end of file
|
||||||
|
+y = 100((no))
|
||||||
|
\ No newline at end of file
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
x = 123456789.bit_count()
|
||||||
|
x = (123456).__abs__()
|
||||||
|
x = .1.is_integer()
|
||||||
|
x = 1..imag
|
||||||
|
x = 1E+1.imag
|
||||||
|
x = 1E-1.real
|
||||||
|
x = 123456789.123456789.hex()
|
||||||
|
x = 123456789.123456789E123456789.real
|
||||||
|
x = 123456789E123456789.conjugate()
|
||||||
|
x = 123456789J.real
|
||||||
|
x = 123456789.123456789J.__add__(0b1011.bit_length())
|
||||||
|
x = 0XB1ACC.conjugate()
|
||||||
|
x = 0B1011.conjugate()
|
||||||
|
x = 0O777.real
|
||||||
|
x = 0.000000006.hex()
|
||||||
|
x = -100.0000J
|
||||||
|
|
||||||
|
if 10.real:
|
||||||
|
...
|
||||||
|
|
||||||
|
y = 100[no]
|
||||||
|
y = 100((no))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
x = (123456789).bit_count()
|
||||||
|
x = (123456).__abs__()
|
||||||
|
x = (0.1).is_integer()
|
||||||
|
x = (1.0).imag
|
||||||
|
x = (1e1).imag
|
||||||
|
x = (1e-1).real
|
||||||
|
x = (123456789.123456789).hex()
|
||||||
|
x = (123456789.123456789e123456789).real
|
||||||
|
x = (123456789e123456789).conjugate()
|
||||||
|
x = 123456789j.real
|
||||||
|
x = 123456789.123456789j.__add__(0b1011.bit_length())
|
||||||
|
x = 0xB1ACC.conjugate()
|
||||||
|
x = 0b1011.conjugate()
|
||||||
|
x = 0o777.real
|
||||||
|
x = (0.000000006).hex()
|
||||||
|
x = -100.0000j
|
||||||
|
|
||||||
|
if (10).real:
|
||||||
|
...
|
||||||
|
|
||||||
|
y = 100[no]
|
||||||
|
y = 100(no)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/bracketmatch.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
for ((x in {}) or {})['a'] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam = {
|
||||||
|
"x": 3
|
||||||
|
}: not spam.get(l.strip())
|
||||||
|
lambda x=lambda y={1: 3}: y['x':lambda y: {1: 2}]: x
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-for ((x in {}) or {})["a"] in x:
|
||||||
|
+for ((x in {}) or {})['a'] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam={"x": 3}: not spam.get(l.strip())
|
||||||
|
-lambda x=lambda y={1: 3}: y["x" : lambda y: {1: 2}]: x
|
||||||
|
\ No newline at end of file
|
||||||
|
+lambda x=lambda y={1: 3}: y['x' : lambda y: {1: 2}]: x
|
||||||
|
\ No newline at end of file
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
for ((x in {}) or {})['a'] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam={"x": 3}: not spam.get(l.strip())
|
||||||
|
lambda x=lambda y={1: 3}: y['x' : lambda y: {1: 2}]: x
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
for ((x in {}) or {})["a"] in x:
|
||||||
|
pass
|
||||||
|
pem_spam = lambda l, spam={"x": 3}: not spam.get(l.strip())
|
||||||
|
lambda x=lambda y={1: 3}: y["x" : lambda y: {1: 2}]: x
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_blank_parentheses.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
class SimpleClassWithBlankParentheses():
|
||||||
|
pass
|
||||||
|
class ClassWithSpaceParentheses ( ):
|
||||||
|
first_test_data = 90
|
||||||
|
second_test_data = 100
|
||||||
|
def test_func(self):
|
||||||
|
return None
|
||||||
|
class ClassWithEmptyFunc(object):
|
||||||
|
|
||||||
|
def func_with_blank_parentheses():
|
||||||
|
return 5
|
||||||
|
|
||||||
|
|
||||||
|
def public_func_with_blank_parentheses():
|
||||||
|
return None
|
||||||
|
def class_under_the_func_with_blank_parentheses():
|
||||||
|
class InsideFunc():
|
||||||
|
pass
|
||||||
|
class NormalClass (
|
||||||
|
):
|
||||||
|
def func_for_testing(self, first, second):
|
||||||
|
sum = first + second
|
||||||
|
return sum
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -27,4 +27,4 @@
|
||||||
|
class NormalClass:
|
||||||
|
def func_for_testing(self, first, second):
|
||||||
|
sum = first + second
|
||||||
|
- return sum
|
||||||
|
\ No newline at end of file
|
||||||
|
+ return sum
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class SimpleClassWithBlankParentheses:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithSpaceParentheses:
|
||||||
|
first_test_data = 90
|
||||||
|
second_test_data = 100
|
||||||
|
|
||||||
|
def test_func(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithEmptyFunc(object):
|
||||||
|
def func_with_blank_parentheses():
|
||||||
|
return 5
|
||||||
|
|
||||||
|
|
||||||
|
def public_func_with_blank_parentheses():
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def class_under_the_func_with_blank_parentheses():
|
||||||
|
class InsideFunc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NormalClass:
|
||||||
|
def func_for_testing(self, first, second):
|
||||||
|
sum = first + second
|
||||||
|
return sum
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class SimpleClassWithBlankParentheses:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithSpaceParentheses:
|
||||||
|
first_test_data = 90
|
||||||
|
second_test_data = 100
|
||||||
|
|
||||||
|
def test_func(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithEmptyFunc(object):
|
||||||
|
def func_with_blank_parentheses():
|
||||||
|
return 5
|
||||||
|
|
||||||
|
|
||||||
|
def public_func_with_blank_parentheses():
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def class_under_the_func_with_blank_parentheses():
|
||||||
|
class InsideFunc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NormalClass:
|
||||||
|
def func_for_testing(self, first, second):
|
||||||
|
sum = first + second
|
||||||
|
return sum
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,468 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_methods_new_line.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
class ClassSimplest:
|
||||||
|
pass
|
||||||
|
class ClassWithSingleField:
|
||||||
|
a = 1
|
||||||
|
class ClassWithJustTheDocstring:
|
||||||
|
"""Just a docstring."""
|
||||||
|
class ClassWithInit:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithTheDocstringAndInit:
|
||||||
|
"""Just a docstring."""
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithInitAndVars:
|
||||||
|
cls_var = 100
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithInitAndVarsAndDocstring:
|
||||||
|
"""Test class"""
|
||||||
|
cls_var = 100
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInit:
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInitAndVars:
|
||||||
|
cls_var = 100
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstring:
|
||||||
|
"""Test class"""
|
||||||
|
cls_var = 100
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassSimplestWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
class ClassSimplestWithInnerWithDocstring:
|
||||||
|
class Inner:
|
||||||
|
"""Just a docstring."""
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithSingleFieldWithInner:
|
||||||
|
a = 1
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
class ClassWithJustTheDocstringWithInner:
|
||||||
|
"""Just a docstring."""
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
class ClassWithInitWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithInitAndVarsWithInner:
|
||||||
|
cls_var = 100
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithInitAndVarsAndDocstringWithInner:
|
||||||
|
"""Test class"""
|
||||||
|
cls_var = 100
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInitWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInitAndVarsWithInner:
|
||||||
|
cls_var = 100
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstringWithInner:
|
||||||
|
"""Test class"""
|
||||||
|
cls_var = 100
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstringWithInner2:
|
||||||
|
"""Test class"""
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
cls_var = 100
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -162,4 +162,4 @@
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
- pass
|
||||||
|
\ No newline at end of file
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class ClassSimplest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithSingleField:
|
||||||
|
a = 1
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithJustTheDocstring:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInit:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithTheDocstringAndInit:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVars:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVarsAndDocstring:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInit:
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVars:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstring:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassSimplestWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassSimplestWithInnerWithDocstring:
|
||||||
|
class Inner:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithSingleFieldWithInner:
|
||||||
|
a = 1
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithJustTheDocstringWithInner:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVarsWithInner:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVarsAndDocstringWithInner:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsWithInner:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstringWithInner:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstringWithInner2:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class ClassSimplest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithSingleField:
|
||||||
|
a = 1
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithJustTheDocstring:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInit:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithTheDocstringAndInit:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVars:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVarsAndDocstring:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInit:
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVars:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstring:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassSimplestWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassSimplestWithInnerWithDocstring:
|
||||||
|
class Inner:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithSingleFieldWithInner:
|
||||||
|
a = 1
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithJustTheDocstringWithInner:
|
||||||
|
"""Just a docstring."""
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVarsWithInner:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithInitAndVarsAndDocstringWithInner:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitWithInner:
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsWithInner:
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstringWithInner:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDecoInitAndVarsAndDocstringWithInner2:
|
||||||
|
"""Test class"""
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
pass
|
||||||
|
|
||||||
|
cls_var = 100
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/collections.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
import core, time, a
|
||||||
|
|
||||||
|
from . import A, B, C
|
||||||
|
|
||||||
|
# keeps existing trailing comma
|
||||||
|
from foo import (
|
||||||
|
bar,
|
||||||
|
)
|
||||||
|
|
||||||
|
# also keeps existing structure
|
||||||
|
from foo import (
|
||||||
|
baz,
|
||||||
|
qux,
|
||||||
|
)
|
||||||
|
|
||||||
|
# `as` works as well
|
||||||
|
from foo import (
|
||||||
|
xyzzy as magic,
|
||||||
|
)
|
||||||
|
|
||||||
|
a = {1,2,3,}
|
||||||
|
b = {
|
||||||
|
1,2,
|
||||||
|
3}
|
||||||
|
c = {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
}
|
||||||
|
x = 1,
|
||||||
|
y = narf(),
|
||||||
|
nested = {(1,2,3),(4,5,6),}
|
||||||
|
nested_no_trailing_comma = {(1,2,3),(4,5,6)}
|
||||||
|
nested_long_lines = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "cccccccccccccccccccccccccccccccccccccccc", (1, 2, 3), "dddddddddddddddddddddddddddddddddddddddd"]
|
||||||
|
{"oneple": (1,),}
|
||||||
|
{"oneple": (1,)}
|
||||||
|
['ls', 'lsoneple/%s' % (foo,)]
|
||||||
|
x = {"oneple": (1,)}
|
||||||
|
y = {"oneple": (1,),}
|
||||||
|
assert False, ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa wraps %s" % bar)
|
||||||
|
|
||||||
|
# looping over a 1-tuple should also not get wrapped
|
||||||
|
for x in (1,):
|
||||||
|
pass
|
||||||
|
for (x,) in (1,), (2,), (3,):
|
||||||
|
pass
|
||||||
|
|
||||||
|
[1, 2, 3,]
|
||||||
|
|
||||||
|
division_result_tuple = (6/2,)
|
||||||
|
print("foo %r", (foo.bar,))
|
||||||
|
|
||||||
|
if True:
|
||||||
|
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
|
||||||
|
Config.IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING
|
||||||
|
| {pylons.controllers.WSGIController}
|
||||||
|
)
|
||||||
|
|
||||||
|
if True:
|
||||||
|
ec2client.get_waiter('instance_stopped').wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
'Delay': 5,
|
||||||
|
})
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={"Delay": 5,},
|
||||||
|
)
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id], WaiterConfig={"Delay": 5,},
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -47,7 +47,7 @@
|
||||||
|
"oneple": (1,),
|
||||||
|
}
|
||||||
|
{"oneple": (1,)}
|
||||||
|
-["ls", "lsoneple/%s" % (foo,)]
|
||||||
|
+['ls', 'lsoneple/%s' % (foo,)]
|
||||||
|
x = {"oneple": (1,)}
|
||||||
|
y = {
|
||||||
|
"oneple": (1,),
|
||||||
|
@@ -79,10 +79,10 @@
|
||||||
|
)
|
||||||
|
|
||||||
|
if True:
|
||||||
|
- ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
+ ec2client.get_waiter('instance_stopped').wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
- "Delay": 5,
|
||||||
|
+ 'Delay': 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
@@ -96,4 +96,4 @@
|
||||||
|
WaiterConfig={
|
||||||
|
"Delay": 5,
|
||||||
|
},
|
||||||
|
- )
|
||||||
|
\ No newline at end of file
|
||||||
|
+ )
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
import core, time, a
|
||||||
|
|
||||||
|
from . import A, B, C
|
||||||
|
|
||||||
|
# keeps existing trailing comma
|
||||||
|
from foo import (
|
||||||
|
bar,
|
||||||
|
)
|
||||||
|
|
||||||
|
# also keeps existing structure
|
||||||
|
from foo import (
|
||||||
|
baz,
|
||||||
|
qux,
|
||||||
|
)
|
||||||
|
|
||||||
|
# `as` works as well
|
||||||
|
from foo import (
|
||||||
|
xyzzy as magic,
|
||||||
|
)
|
||||||
|
|
||||||
|
a = {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
}
|
||||||
|
b = {1, 2, 3}
|
||||||
|
c = {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
}
|
||||||
|
x = (1,)
|
||||||
|
y = (narf(),)
|
||||||
|
nested = {
|
||||||
|
(1, 2, 3),
|
||||||
|
(4, 5, 6),
|
||||||
|
}
|
||||||
|
nested_no_trailing_comma = {(1, 2, 3), (4, 5, 6)}
|
||||||
|
nested_long_lines = [
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||||
|
"cccccccccccccccccccccccccccccccccccccccc",
|
||||||
|
(1, 2, 3),
|
||||||
|
"dddddddddddddddddddddddddddddddddddddddd",
|
||||||
|
]
|
||||||
|
{
|
||||||
|
"oneple": (1,),
|
||||||
|
}
|
||||||
|
{"oneple": (1,)}
|
||||||
|
['ls', 'lsoneple/%s' % (foo,)]
|
||||||
|
x = {"oneple": (1,)}
|
||||||
|
y = {
|
||||||
|
"oneple": (1,),
|
||||||
|
}
|
||||||
|
assert False, (
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa wraps %s"
|
||||||
|
% bar
|
||||||
|
)
|
||||||
|
|
||||||
|
# looping over a 1-tuple should also not get wrapped
|
||||||
|
for x in (1,):
|
||||||
|
pass
|
||||||
|
for (x,) in (1,), (2,), (3,):
|
||||||
|
pass
|
||||||
|
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
]
|
||||||
|
|
||||||
|
division_result_tuple = (6 / 2,)
|
||||||
|
print("foo %r", (foo.bar,))
|
||||||
|
|
||||||
|
if True:
|
||||||
|
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
|
||||||
|
Config.IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING
|
||||||
|
| {pylons.controllers.WSGIController}
|
||||||
|
)
|
||||||
|
|
||||||
|
if True:
|
||||||
|
ec2client.get_waiter('instance_stopped').wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
'Delay': 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
"Delay": 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
"Delay": 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
import core, time, a
|
||||||
|
|
||||||
|
from . import A, B, C
|
||||||
|
|
||||||
|
# keeps existing trailing comma
|
||||||
|
from foo import (
|
||||||
|
bar,
|
||||||
|
)
|
||||||
|
|
||||||
|
# also keeps existing structure
|
||||||
|
from foo import (
|
||||||
|
baz,
|
||||||
|
qux,
|
||||||
|
)
|
||||||
|
|
||||||
|
# `as` works as well
|
||||||
|
from foo import (
|
||||||
|
xyzzy as magic,
|
||||||
|
)
|
||||||
|
|
||||||
|
a = {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
}
|
||||||
|
b = {1, 2, 3}
|
||||||
|
c = {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
}
|
||||||
|
x = (1,)
|
||||||
|
y = (narf(),)
|
||||||
|
nested = {
|
||||||
|
(1, 2, 3),
|
||||||
|
(4, 5, 6),
|
||||||
|
}
|
||||||
|
nested_no_trailing_comma = {(1, 2, 3), (4, 5, 6)}
|
||||||
|
nested_long_lines = [
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||||
|
"cccccccccccccccccccccccccccccccccccccccc",
|
||||||
|
(1, 2, 3),
|
||||||
|
"dddddddddddddddddddddddddddddddddddddddd",
|
||||||
|
]
|
||||||
|
{
|
||||||
|
"oneple": (1,),
|
||||||
|
}
|
||||||
|
{"oneple": (1,)}
|
||||||
|
["ls", "lsoneple/%s" % (foo,)]
|
||||||
|
x = {"oneple": (1,)}
|
||||||
|
y = {
|
||||||
|
"oneple": (1,),
|
||||||
|
}
|
||||||
|
assert False, (
|
||||||
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa wraps %s"
|
||||||
|
% bar
|
||||||
|
)
|
||||||
|
|
||||||
|
# looping over a 1-tuple should also not get wrapped
|
||||||
|
for x in (1,):
|
||||||
|
pass
|
||||||
|
for (x,) in (1,), (2,), (3,):
|
||||||
|
pass
|
||||||
|
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
]
|
||||||
|
|
||||||
|
division_result_tuple = (6 / 2,)
|
||||||
|
print("foo %r", (foo.bar,))
|
||||||
|
|
||||||
|
if True:
|
||||||
|
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
|
||||||
|
Config.IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING
|
||||||
|
| {pylons.controllers.WSGIController}
|
||||||
|
)
|
||||||
|
|
||||||
|
if True:
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
"Delay": 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
"Delay": 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ec2client.get_waiter("instance_stopped").wait(
|
||||||
|
InstanceIds=[instance.id],
|
||||||
|
WaiterConfig={
|
||||||
|
"Delay": 5,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comment_after_escaped_newline.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
def bob(): \
|
||||||
|
# pylint: disable=W9016
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def bobtwo(): \
|
||||||
|
\
|
||||||
|
# some comment here
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,6 +1,8 @@
|
||||||
|
-def bob(): # pylint: disable=W9016
|
||||||
|
+def bob():
|
||||||
|
+ # pylint: disable=W9016
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
-def bobtwo(): # some comment here
|
||||||
|
- pass
|
||||||
|
\ No newline at end of file
|
||||||
|
+def bobtwo():
|
||||||
|
+ # some comment here
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
def bob():
|
||||||
|
# pylint: disable=W9016
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def bobtwo():
|
||||||
|
# some comment here
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
def bob(): # pylint: disable=W9016
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def bobtwo(): # some comment here
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,734 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments2.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent # NOT DRY
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent as component # DRY
|
||||||
|
)
|
||||||
|
|
||||||
|
# Please keep __all__ alphabetized within each category.
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
# Super-special typing primitives.
|
||||||
|
'Any',
|
||||||
|
'Callable',
|
||||||
|
'ClassVar',
|
||||||
|
|
||||||
|
# ABCs (from collections.abc).
|
||||||
|
'AbstractSet', # collections.abc.Set.
|
||||||
|
'ByteString',
|
||||||
|
'Container',
|
||||||
|
|
||||||
|
# Concrete collection types.
|
||||||
|
'Counter',
|
||||||
|
'Deque',
|
||||||
|
'Dict',
|
||||||
|
'DefaultDict',
|
||||||
|
'List',
|
||||||
|
'Set',
|
||||||
|
'FrozenSet',
|
||||||
|
'NamedTuple', # Not really a type.
|
||||||
|
'Generator',
|
||||||
|
]
|
||||||
|
|
||||||
|
not_shareables = [
|
||||||
|
# singletons
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
NotImplemented, ...,
|
||||||
|
# builtin types and objects
|
||||||
|
type,
|
||||||
|
object,
|
||||||
|
object(),
|
||||||
|
Exception(),
|
||||||
|
42,
|
||||||
|
100.0,
|
||||||
|
"spam",
|
||||||
|
# user-defined types and objects
|
||||||
|
Cheese,
|
||||||
|
Cheese("Wensleydale"),
|
||||||
|
SubBytes(b"spam"),
|
||||||
|
]
|
||||||
|
|
||||||
|
if 'PYTHON' in os.environ:
|
||||||
|
add_compiler(compiler_from_env())
|
||||||
|
else:
|
||||||
|
# for compiler in compilers.values():
|
||||||
|
# add_compiler(compiler)
|
||||||
|
add_compiler(compilers[(7.0, 32)])
|
||||||
|
# add_compiler(compilers[(7.1, 64)])
|
||||||
|
|
||||||
|
# Comment before function.
|
||||||
|
def inline_comments_in_brackets_ruin_everything():
|
||||||
|
if typedargslist:
|
||||||
|
parameters.children = [
|
||||||
|
children[0], # (1
|
||||||
|
body,
|
||||||
|
children[-1] # )1
|
||||||
|
]
|
||||||
|
parameters.children = [
|
||||||
|
children[0],
|
||||||
|
body,
|
||||||
|
children[-1], # type: ignore
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
parameters.children = [
|
||||||
|
parameters.children[0], # (2 what if this was actually long
|
||||||
|
body,
|
||||||
|
parameters.children[-1], # )2
|
||||||
|
]
|
||||||
|
parameters.children = [parameters.what_if_this_was_actually_long.children[0], body, parameters.children[-1]] # type: ignore
|
||||||
|
if (self._proc is not None
|
||||||
|
# has the child process finished?
|
||||||
|
and self._returncode is None
|
||||||
|
# the child process has finished, but the
|
||||||
|
# transport hasn't been notified yet?
|
||||||
|
and self._proc.poll() is None):
|
||||||
|
pass
|
||||||
|
# no newline before or after
|
||||||
|
short = [
|
||||||
|
# one
|
||||||
|
1,
|
||||||
|
# two
|
||||||
|
2]
|
||||||
|
|
||||||
|
# no newline after
|
||||||
|
call(arg1, arg2, """
|
||||||
|
short
|
||||||
|
""", arg3=True)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
call2(
|
||||||
|
#short
|
||||||
|
arg1,
|
||||||
|
#but
|
||||||
|
arg2,
|
||||||
|
#multiline
|
||||||
|
"""
|
||||||
|
short
|
||||||
|
""",
|
||||||
|
# yup
|
||||||
|
arg3=True)
|
||||||
|
lcomp = [
|
||||||
|
element # yup
|
||||||
|
for element in collection # yup
|
||||||
|
if element is not None # right
|
||||||
|
]
|
||||||
|
lcomp2 = [
|
||||||
|
# hello
|
||||||
|
element
|
||||||
|
# yup
|
||||||
|
for element in collection
|
||||||
|
# right
|
||||||
|
if element is not None
|
||||||
|
]
|
||||||
|
lcomp3 = [
|
||||||
|
# This one is actually too long to fit in a single line.
|
||||||
|
element.split('\n', 1)[0]
|
||||||
|
# yup
|
||||||
|
for element in collection.select_elements()
|
||||||
|
# right
|
||||||
|
if element is not None
|
||||||
|
]
|
||||||
|
while True:
|
||||||
|
if False:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# and round and round we go
|
||||||
|
# and round and round we go
|
||||||
|
|
||||||
|
# let's return
|
||||||
|
return Node(
|
||||||
|
syms.simple_stmt,
|
||||||
|
[
|
||||||
|
Node(statement, result),
|
||||||
|
Leaf(token.NEWLINE, '\n') # FIXME: \r\n?
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_FILES = [CONFIG_FILE, ] + SHARED_CONFIG_FILES + USER_CONFIG_FILES # type: Final
|
||||||
|
|
||||||
|
class Test:
|
||||||
|
def _init_host(self, parsed) -> None:
|
||||||
|
if (parsed.hostname is None or # type: ignore
|
||||||
|
not parsed.hostname.strip()):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#######################
|
||||||
|
### SECTION COMMENT ###
|
||||||
|
#######################
|
||||||
|
|
||||||
|
|
||||||
|
instruction()#comment with bad spacing
|
||||||
|
|
||||||
|
# END COMMENTS
|
||||||
|
# MORE END COMMENTS
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,31 +1,31 @@
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
- MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
|
+ MyLovelyCompanyTeamProjectComponent,
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
- MyLovelyCompanyTeamProjectComponent as component, # DRY
|
||||||
|
+ MyLovelyCompanyTeamProjectComponent as component,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Please keep __all__ alphabetized within each category.
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
# Super-special typing primitives.
|
||||||
|
- "Any",
|
||||||
|
- "Callable",
|
||||||
|
- "ClassVar",
|
||||||
|
+ 'Any',
|
||||||
|
+ 'Callable',
|
||||||
|
+ 'ClassVar',
|
||||||
|
# ABCs (from collections.abc).
|
||||||
|
- "AbstractSet", # collections.abc.Set.
|
||||||
|
- "ByteString",
|
||||||
|
- "Container",
|
||||||
|
+ 'AbstractSet',
|
||||||
|
+ 'ByteString',
|
||||||
|
+ 'Container',
|
||||||
|
# Concrete collection types.
|
||||||
|
- "Counter",
|
||||||
|
- "Deque",
|
||||||
|
- "Dict",
|
||||||
|
- "DefaultDict",
|
||||||
|
- "List",
|
||||||
|
- "Set",
|
||||||
|
- "FrozenSet",
|
||||||
|
- "NamedTuple", # Not really a type.
|
||||||
|
- "Generator",
|
||||||
|
+ 'Counter',
|
||||||
|
+ 'Deque',
|
||||||
|
+ 'Dict',
|
||||||
|
+ 'DefaultDict',
|
||||||
|
+ 'List',
|
||||||
|
+ 'Set',
|
||||||
|
+ 'FrozenSet',
|
||||||
|
+ 'NamedTuple',
|
||||||
|
+ 'Generator',
|
||||||
|
]
|
||||||
|
|
||||||
|
not_shareables = [
|
||||||
|
@@ -48,38 +48,45 @@
|
||||||
|
SubBytes(b"spam"),
|
||||||
|
]
|
||||||
|
|
||||||
|
-if "PYTHON" in os.environ:
|
||||||
|
+if 'PYTHON' in os.environ:
|
||||||
|
add_compiler(compiler_from_env())
|
||||||
|
else:
|
||||||
|
# for compiler in compilers.values():
|
||||||
|
# add_compiler(compiler)
|
||||||
|
add_compiler(compilers[(7.0, 32)])
|
||||||
|
- # add_compiler(compilers[(7.1, 64)])
|
||||||
|
|
||||||
|
|
||||||
|
+# add_compiler(compilers[(7.1, 64)])
|
||||||
|
+
|
||||||
|
# Comment before function.
|
||||||
|
def inline_comments_in_brackets_ruin_everything():
|
||||||
|
if typedargslist:
|
||||||
|
- parameters.children = [children[0], body, children[-1]] # (1 # )1
|
||||||
|
+ parameters.children = [children[0], body, children[-1]]
|
||||||
|
parameters.children = [
|
||||||
|
children[0],
|
||||||
|
body,
|
||||||
|
- children[-1], # type: ignore
|
||||||
|
+ children[-1],
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
parameters.children = [
|
||||||
|
- parameters.children[0], # (2 what if this was actually long
|
||||||
|
+ parameters.children[0],
|
||||||
|
body,
|
||||||
|
- parameters.children[-1], # )2
|
||||||
|
+ parameters.children[-1],
|
||||||
|
]
|
||||||
|
- parameters.children = [parameters.what_if_this_was_actually_long.children[0], body, parameters.children[-1]] # type: ignore
|
||||||
|
+ parameters.children = [
|
||||||
|
+ parameters.what_if_this_was_actually_long.children[0],
|
||||||
|
+ body,
|
||||||
|
+ parameters.children[-1],
|
||||||
|
+ ]
|
||||||
|
if (
|
||||||
|
self._proc is not None
|
||||||
|
- # has the child process finished?
|
||||||
|
- and self._returncode is None
|
||||||
|
- # the child process has finished, but the
|
||||||
|
+ and # has the child process finished?
|
||||||
|
+ self._returncode
|
||||||
|
+ is None
|
||||||
|
+ and # the child process has finished, but the
|
||||||
|
# transport hasn't been notified yet?
|
||||||
|
- and self._proc.poll() is None
|
||||||
|
+ self._proc.poll()
|
||||||
|
+ is None
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
# no newline before or after
|
||||||
|
@@ -103,47 +110,47 @@
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
call2(
|
||||||
|
- # short
|
||||||
|
+ #short
|
||||||
|
arg1,
|
||||||
|
- # but
|
||||||
|
+ #but
|
||||||
|
arg2,
|
||||||
|
- # multiline
|
||||||
|
+ #multiline
|
||||||
|
"""
|
||||||
|
short
|
||||||
|
""",
|
||||||
|
- # yup
|
||||||
|
- arg3=True,
|
||||||
|
+ arg3=# yup
|
||||||
|
+ True,
|
||||||
|
)
|
||||||
|
- lcomp = [
|
||||||
|
- element for element in collection if element is not None # yup # yup # right
|
||||||
|
- ]
|
||||||
|
+ lcomp = [element for element in collection if element is not None] # yup # yup # right
|
||||||
|
lcomp2 = [
|
||||||
|
# hello
|
||||||
|
element
|
||||||
|
- # yup
|
||||||
|
- for element in collection
|
||||||
|
- # right
|
||||||
|
- if element is not None
|
||||||
|
+ for # yup
|
||||||
|
+ element in collection
|
||||||
|
+ if # right
|
||||||
|
+ element
|
||||||
|
+ is not None
|
||||||
|
]
|
||||||
|
lcomp3 = [
|
||||||
|
# This one is actually too long to fit in a single line.
|
||||||
|
- element.split("\n", 1)[0]
|
||||||
|
- # yup
|
||||||
|
- for element in collection.select_elements()
|
||||||
|
- # right
|
||||||
|
- if element is not None
|
||||||
|
+ element.split('\n', 1)[0]
|
||||||
|
+ for # yup
|
||||||
|
+ element in collection.select_elements()
|
||||||
|
+ if # right
|
||||||
|
+ element
|
||||||
|
+ is not None
|
||||||
|
]
|
||||||
|
while True:
|
||||||
|
if False:
|
||||||
|
continue
|
||||||
|
|
||||||
|
- # and round and round we go
|
||||||
|
- # and round and round we go
|
||||||
|
+ # and round and round we go
|
||||||
|
+ # and round and round we go
|
||||||
|
|
||||||
|
# let's return
|
||||||
|
return Node(
|
||||||
|
syms.simple_stmt,
|
||||||
|
- [Node(statement, result), Leaf(token.NEWLINE, "\n")], # FIXME: \r\n?
|
||||||
|
+ [Node(statement, result), Leaf(token.NEWLINE, '\n')], # FIXME: \r\n?
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -167,7 +174,7 @@
|
||||||
|
#######################
|
||||||
|
|
||||||
|
|
||||||
|
-instruction() # comment with bad spacing
|
||||||
|
+instruction() #comment with bad spacing
|
||||||
|
|
||||||
|
# END COMMENTS
|
||||||
|
-# MORE END COMMENTS
|
||||||
|
\ No newline at end of file
|
||||||
|
+# MORE END COMMENTS
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent,
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent as component,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Please keep __all__ alphabetized within each category.
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
# Super-special typing primitives.
|
||||||
|
'Any',
|
||||||
|
'Callable',
|
||||||
|
'ClassVar',
|
||||||
|
# ABCs (from collections.abc).
|
||||||
|
'AbstractSet',
|
||||||
|
'ByteString',
|
||||||
|
'Container',
|
||||||
|
# Concrete collection types.
|
||||||
|
'Counter',
|
||||||
|
'Deque',
|
||||||
|
'Dict',
|
||||||
|
'DefaultDict',
|
||||||
|
'List',
|
||||||
|
'Set',
|
||||||
|
'FrozenSet',
|
||||||
|
'NamedTuple',
|
||||||
|
'Generator',
|
||||||
|
]
|
||||||
|
|
||||||
|
not_shareables = [
|
||||||
|
# singletons
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
NotImplemented,
|
||||||
|
...,
|
||||||
|
# builtin types and objects
|
||||||
|
type,
|
||||||
|
object,
|
||||||
|
object(),
|
||||||
|
Exception(),
|
||||||
|
42,
|
||||||
|
100.0,
|
||||||
|
"spam",
|
||||||
|
# user-defined types and objects
|
||||||
|
Cheese,
|
||||||
|
Cheese("Wensleydale"),
|
||||||
|
SubBytes(b"spam"),
|
||||||
|
]
|
||||||
|
|
||||||
|
if 'PYTHON' in os.environ:
|
||||||
|
add_compiler(compiler_from_env())
|
||||||
|
else:
|
||||||
|
# for compiler in compilers.values():
|
||||||
|
# add_compiler(compiler)
|
||||||
|
add_compiler(compilers[(7.0, 32)])
|
||||||
|
|
||||||
|
|
||||||
|
# add_compiler(compilers[(7.1, 64)])
|
||||||
|
|
||||||
|
# Comment before function.
|
||||||
|
def inline_comments_in_brackets_ruin_everything():
|
||||||
|
if typedargslist:
|
||||||
|
parameters.children = [children[0], body, children[-1]]
|
||||||
|
parameters.children = [
|
||||||
|
children[0],
|
||||||
|
body,
|
||||||
|
children[-1],
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
parameters.children = [
|
||||||
|
parameters.children[0],
|
||||||
|
body,
|
||||||
|
parameters.children[-1],
|
||||||
|
]
|
||||||
|
parameters.children = [
|
||||||
|
parameters.what_if_this_was_actually_long.children[0],
|
||||||
|
body,
|
||||||
|
parameters.children[-1],
|
||||||
|
]
|
||||||
|
if (
|
||||||
|
self._proc is not None
|
||||||
|
and # has the child process finished?
|
||||||
|
self._returncode
|
||||||
|
is None
|
||||||
|
and # the child process has finished, but the
|
||||||
|
# transport hasn't been notified yet?
|
||||||
|
self._proc.poll()
|
||||||
|
is None
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
# no newline before or after
|
||||||
|
short = [
|
||||||
|
# one
|
||||||
|
1,
|
||||||
|
# two
|
||||||
|
2,
|
||||||
|
]
|
||||||
|
|
||||||
|
# no newline after
|
||||||
|
call(
|
||||||
|
arg1,
|
||||||
|
arg2,
|
||||||
|
"""
|
||||||
|
short
|
||||||
|
""",
|
||||||
|
arg3=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
call2(
|
||||||
|
#short
|
||||||
|
arg1,
|
||||||
|
#but
|
||||||
|
arg2,
|
||||||
|
#multiline
|
||||||
|
"""
|
||||||
|
short
|
||||||
|
""",
|
||||||
|
arg3=# yup
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
lcomp = [element for element in collection if element is not None] # yup # yup # right
|
||||||
|
lcomp2 = [
|
||||||
|
# hello
|
||||||
|
element
|
||||||
|
for # yup
|
||||||
|
element in collection
|
||||||
|
if # right
|
||||||
|
element
|
||||||
|
is not None
|
||||||
|
]
|
||||||
|
lcomp3 = [
|
||||||
|
# This one is actually too long to fit in a single line.
|
||||||
|
element.split('\n', 1)[0]
|
||||||
|
for # yup
|
||||||
|
element in collection.select_elements()
|
||||||
|
if # right
|
||||||
|
element
|
||||||
|
is not None
|
||||||
|
]
|
||||||
|
while True:
|
||||||
|
if False:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# and round and round we go
|
||||||
|
# and round and round we go
|
||||||
|
|
||||||
|
# let's return
|
||||||
|
return Node(
|
||||||
|
syms.simple_stmt,
|
||||||
|
[Node(statement, result), Leaf(token.NEWLINE, '\n')], # FIXME: \r\n?
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_FILES = (
|
||||||
|
[
|
||||||
|
CONFIG_FILE,
|
||||||
|
]
|
||||||
|
+ SHARED_CONFIG_FILES
|
||||||
|
+ USER_CONFIG_FILES
|
||||||
|
) # type: Final
|
||||||
|
|
||||||
|
|
||||||
|
class Test:
|
||||||
|
def _init_host(self, parsed) -> None:
|
||||||
|
if parsed.hostname is None or not parsed.hostname.strip(): # type: ignore
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
#######################
|
||||||
|
### SECTION COMMENT ###
|
||||||
|
#######################
|
||||||
|
|
||||||
|
|
||||||
|
instruction() #comment with bad spacing
|
||||||
|
|
||||||
|
# END COMMENTS
|
||||||
|
# MORE END COMMENTS
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent as component, # DRY
|
||||||
|
)
|
||||||
|
|
||||||
|
# Please keep __all__ alphabetized within each category.
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
# Super-special typing primitives.
|
||||||
|
"Any",
|
||||||
|
"Callable",
|
||||||
|
"ClassVar",
|
||||||
|
# ABCs (from collections.abc).
|
||||||
|
"AbstractSet", # collections.abc.Set.
|
||||||
|
"ByteString",
|
||||||
|
"Container",
|
||||||
|
# Concrete collection types.
|
||||||
|
"Counter",
|
||||||
|
"Deque",
|
||||||
|
"Dict",
|
||||||
|
"DefaultDict",
|
||||||
|
"List",
|
||||||
|
"Set",
|
||||||
|
"FrozenSet",
|
||||||
|
"NamedTuple", # Not really a type.
|
||||||
|
"Generator",
|
||||||
|
]
|
||||||
|
|
||||||
|
not_shareables = [
|
||||||
|
# singletons
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
NotImplemented,
|
||||||
|
...,
|
||||||
|
# builtin types and objects
|
||||||
|
type,
|
||||||
|
object,
|
||||||
|
object(),
|
||||||
|
Exception(),
|
||||||
|
42,
|
||||||
|
100.0,
|
||||||
|
"spam",
|
||||||
|
# user-defined types and objects
|
||||||
|
Cheese,
|
||||||
|
Cheese("Wensleydale"),
|
||||||
|
SubBytes(b"spam"),
|
||||||
|
]
|
||||||
|
|
||||||
|
if "PYTHON" in os.environ:
|
||||||
|
add_compiler(compiler_from_env())
|
||||||
|
else:
|
||||||
|
# for compiler in compilers.values():
|
||||||
|
# add_compiler(compiler)
|
||||||
|
add_compiler(compilers[(7.0, 32)])
|
||||||
|
# add_compiler(compilers[(7.1, 64)])
|
||||||
|
|
||||||
|
|
||||||
|
# Comment before function.
|
||||||
|
def inline_comments_in_brackets_ruin_everything():
|
||||||
|
if typedargslist:
|
||||||
|
parameters.children = [children[0], body, children[-1]] # (1 # )1
|
||||||
|
parameters.children = [
|
||||||
|
children[0],
|
||||||
|
body,
|
||||||
|
children[-1], # type: ignore
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
parameters.children = [
|
||||||
|
parameters.children[0], # (2 what if this was actually long
|
||||||
|
body,
|
||||||
|
parameters.children[-1], # )2
|
||||||
|
]
|
||||||
|
parameters.children = [parameters.what_if_this_was_actually_long.children[0], body, parameters.children[-1]] # type: ignore
|
||||||
|
if (
|
||||||
|
self._proc is not None
|
||||||
|
# has the child process finished?
|
||||||
|
and self._returncode is None
|
||||||
|
# the child process has finished, but the
|
||||||
|
# transport hasn't been notified yet?
|
||||||
|
and self._proc.poll() is None
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
# no newline before or after
|
||||||
|
short = [
|
||||||
|
# one
|
||||||
|
1,
|
||||||
|
# two
|
||||||
|
2,
|
||||||
|
]
|
||||||
|
|
||||||
|
# no newline after
|
||||||
|
call(
|
||||||
|
arg1,
|
||||||
|
arg2,
|
||||||
|
"""
|
||||||
|
short
|
||||||
|
""",
|
||||||
|
arg3=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
call2(
|
||||||
|
# short
|
||||||
|
arg1,
|
||||||
|
# but
|
||||||
|
arg2,
|
||||||
|
# multiline
|
||||||
|
"""
|
||||||
|
short
|
||||||
|
""",
|
||||||
|
# yup
|
||||||
|
arg3=True,
|
||||||
|
)
|
||||||
|
lcomp = [
|
||||||
|
element for element in collection if element is not None # yup # yup # right
|
||||||
|
]
|
||||||
|
lcomp2 = [
|
||||||
|
# hello
|
||||||
|
element
|
||||||
|
# yup
|
||||||
|
for element in collection
|
||||||
|
# right
|
||||||
|
if element is not None
|
||||||
|
]
|
||||||
|
lcomp3 = [
|
||||||
|
# This one is actually too long to fit in a single line.
|
||||||
|
element.split("\n", 1)[0]
|
||||||
|
# yup
|
||||||
|
for element in collection.select_elements()
|
||||||
|
# right
|
||||||
|
if element is not None
|
||||||
|
]
|
||||||
|
while True:
|
||||||
|
if False:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# and round and round we go
|
||||||
|
# and round and round we go
|
||||||
|
|
||||||
|
# let's return
|
||||||
|
return Node(
|
||||||
|
syms.simple_stmt,
|
||||||
|
[Node(statement, result), Leaf(token.NEWLINE, "\n")], # FIXME: \r\n?
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_FILES = (
|
||||||
|
[
|
||||||
|
CONFIG_FILE,
|
||||||
|
]
|
||||||
|
+ SHARED_CONFIG_FILES
|
||||||
|
+ USER_CONFIG_FILES
|
||||||
|
) # type: Final
|
||||||
|
|
||||||
|
|
||||||
|
class Test:
|
||||||
|
def _init_host(self, parsed) -> None:
|
||||||
|
if parsed.hostname is None or not parsed.hostname.strip(): # type: ignore
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
#######################
|
||||||
|
### SECTION COMMENT ###
|
||||||
|
#######################
|
||||||
|
|
||||||
|
|
||||||
|
instruction() # comment with bad spacing
|
||||||
|
|
||||||
|
# END COMMENTS
|
||||||
|
# MORE END COMMENTS
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,450 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments4.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent as component, # DRY
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class C:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("post_data", "message"),
|
||||||
|
[
|
||||||
|
# metadata_version errors.
|
||||||
|
(
|
||||||
|
{},
|
||||||
|
"None is an invalid value for Metadata-Version. Error: This field is"
|
||||||
|
" required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"metadata_version": "-1"},
|
||||||
|
"'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata"
|
||||||
|
" Version see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
# name errors.
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2"},
|
||||||
|
"'' is an invalid value for Name. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2", "name": "foo-"},
|
||||||
|
"'foo-' is an invalid value for Name. Error: Must start and end with a"
|
||||||
|
" letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
# version errors.
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2", "name": "example"},
|
||||||
|
"'' is an invalid value for Version. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2", "name": "example", "version": "dog"},
|
||||||
|
"'dog' is an invalid value for Version. Error: Must start and end with"
|
||||||
|
" a letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_fails_invalid_post_data(
|
||||||
|
self, pyramid_config, db_request, post_data, message
|
||||||
|
):
|
||||||
|
pyramid_config.testing_securitypolicy(userid=1)
|
||||||
|
db_request.POST = MultiDict(post_data)
|
||||||
|
|
||||||
|
|
||||||
|
def foo(list_a, list_b):
|
||||||
|
results = (
|
||||||
|
User.query.filter(User.foo == "bar")
|
||||||
|
.filter( # Because foo.
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
)
|
||||||
|
.filter(User.xyz.is_(None))
|
||||||
|
# Another comment about the filtering on is_quux goes here.
|
||||||
|
.filter(db.not_(User.is_pending.astext.cast(db.Boolean).is_(True)))
|
||||||
|
.order_by(User.created_at.desc())
|
||||||
|
.with_for_update(key_share=True)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def foo2(list_a, list_b):
|
||||||
|
# Standalone comment reasonably placed.
|
||||||
|
return (
|
||||||
|
User.query.filter(User.foo == "bar")
|
||||||
|
.filter(
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
)
|
||||||
|
.filter(User.xyz.is_(None))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def foo3(list_a, list_b):
|
||||||
|
return (
|
||||||
|
# Standlone comment but weirdly placed.
|
||||||
|
User.query.filter(User.foo == "bar")
|
||||||
|
.filter(
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
)
|
||||||
|
.filter(User.xyz.is_(None))
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,8 +1,8 @@
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
- MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
|
+ MyLovelyCompanyTeamProjectComponent,
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
- MyLovelyCompanyTeamProjectComponent as component, # DRY
|
||||||
|
+ MyLovelyCompanyTeamProjectComponent as component,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,39 +10,50 @@
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("post_data", "message"),
|
||||||
|
[
|
||||||
|
- # metadata_version errors.
|
||||||
|
- (
|
||||||
|
+ (# metadata_version errors.
|
||||||
|
{},
|
||||||
|
"None is an invalid value for Metadata-Version. Error: This field is"
|
||||||
|
" required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
- {"metadata_version": "-1"},
|
||||||
|
+ {
|
||||||
|
+ "metadata_version": "-1",
|
||||||
|
+ },
|
||||||
|
"'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata"
|
||||||
|
" Version see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
- # name errors.
|
||||||
|
- (
|
||||||
|
- {"metadata_version": "1.2"},
|
||||||
|
+ (# name errors.
|
||||||
|
+ {
|
||||||
|
+ "metadata_version": "1.2",
|
||||||
|
+ },
|
||||||
|
"'' is an invalid value for Name. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
- {"metadata_version": "1.2", "name": "foo-"},
|
||||||
|
+ {
|
||||||
|
+ "metadata_version": "1.2",
|
||||||
|
+ "name": "foo-",
|
||||||
|
+ },
|
||||||
|
"'foo-' is an invalid value for Name. Error: Must start and end with a"
|
||||||
|
" letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
- # version errors.
|
||||||
|
- (
|
||||||
|
- {"metadata_version": "1.2", "name": "example"},
|
||||||
|
+ (# version errors.
|
||||||
|
+ {
|
||||||
|
+ "metadata_version": "1.2",
|
||||||
|
+ "name": "example",
|
||||||
|
+ },
|
||||||
|
"'' is an invalid value for Version. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
- {"metadata_version": "1.2", "name": "example", "version": "dog"},
|
||||||
|
+ {
|
||||||
|
+ "metadata_version": "1.2",
|
||||||
|
+ "name": "example",
|
||||||
|
+ "version": "dog",
|
||||||
|
+ },
|
||||||
|
"'dog' is an invalid value for Version. Error: Must start and end with"
|
||||||
|
" a letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
@@ -50,45 +61,34 @@
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_fails_invalid_post_data(
|
||||||
|
- self, pyramid_config, db_request, post_data, message
|
||||||
|
+ self,
|
||||||
|
+ pyramid_config,
|
||||||
|
+ db_request,
|
||||||
|
+ post_data,
|
||||||
|
+ message,
|
||||||
|
):
|
||||||
|
pyramid_config.testing_securitypolicy(userid=1)
|
||||||
|
db_request.POST = MultiDict(post_data)
|
||||||
|
|
||||||
|
|
||||||
|
def foo(list_a, list_b):
|
||||||
|
- results = (
|
||||||
|
- User.query.filter(User.foo == "bar")
|
||||||
|
- .filter( # Because foo.
|
||||||
|
- db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
- )
|
||||||
|
- .filter(User.xyz.is_(None))
|
||||||
|
- # Another comment about the filtering on is_quux goes here.
|
||||||
|
- .filter(db.not_(User.is_pending.astext.cast(db.Boolean).is_(True)))
|
||||||
|
- .order_by(User.created_at.desc())
|
||||||
|
- .with_for_update(key_share=True)
|
||||||
|
- .all()
|
||||||
|
- )
|
||||||
|
+ results = User.query.filter(User.foo == "bar").filter( # Because foo.
|
||||||
|
+ db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
+ ).filter(User.xyz.is_(None)).filter(
|
||||||
|
+ db.not_(User.is_pending.astext.cast(db.Boolean).is_(True))
|
||||||
|
+ ).order_by(User.created_at.desc()).with_for_update(key_share=True).all()
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def foo2(list_a, list_b):
|
||||||
|
# Standalone comment reasonably placed.
|
||||||
|
- return (
|
||||||
|
- User.query.filter(User.foo == "bar")
|
||||||
|
- .filter(
|
||||||
|
- db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
- )
|
||||||
|
- .filter(User.xyz.is_(None))
|
||||||
|
- )
|
||||||
|
+ return User.query.filter(User.foo == "bar").filter(
|
||||||
|
+ db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
+ ).filter(User.xyz.is_(None))
|
||||||
|
|
||||||
|
|
||||||
|
def foo3(list_a, list_b):
|
||||||
|
- return (
|
||||||
|
- # Standlone comment but weirdly placed.
|
||||||
|
- User.query.filter(User.foo == "bar")
|
||||||
|
- .filter(
|
||||||
|
- db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
- )
|
||||||
|
- .filter(User.xyz.is_(None))
|
||||||
|
- )
|
||||||
|
\ No newline at end of file
|
||||||
|
+ return # Standlone comment but weirdly placed.
|
||||||
|
+ User.query.filter(User.foo == "bar").filter(
|
||||||
|
+ db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
+ ).filter(User.xyz.is_(None))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent,
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent as component,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class C:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("post_data", "message"),
|
||||||
|
[
|
||||||
|
(# metadata_version errors.
|
||||||
|
{},
|
||||||
|
"None is an invalid value for Metadata-Version. Error: This field is"
|
||||||
|
" required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"metadata_version": "-1",
|
||||||
|
},
|
||||||
|
"'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata"
|
||||||
|
" Version see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(# name errors.
|
||||||
|
{
|
||||||
|
"metadata_version": "1.2",
|
||||||
|
},
|
||||||
|
"'' is an invalid value for Name. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"metadata_version": "1.2",
|
||||||
|
"name": "foo-",
|
||||||
|
},
|
||||||
|
"'foo-' is an invalid value for Name. Error: Must start and end with a"
|
||||||
|
" letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(# version errors.
|
||||||
|
{
|
||||||
|
"metadata_version": "1.2",
|
||||||
|
"name": "example",
|
||||||
|
},
|
||||||
|
"'' is an invalid value for Version. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"metadata_version": "1.2",
|
||||||
|
"name": "example",
|
||||||
|
"version": "dog",
|
||||||
|
},
|
||||||
|
"'dog' is an invalid value for Version. Error: Must start and end with"
|
||||||
|
" a letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_fails_invalid_post_data(
|
||||||
|
self,
|
||||||
|
pyramid_config,
|
||||||
|
db_request,
|
||||||
|
post_data,
|
||||||
|
message,
|
||||||
|
):
|
||||||
|
pyramid_config.testing_securitypolicy(userid=1)
|
||||||
|
db_request.POST = MultiDict(post_data)
|
||||||
|
|
||||||
|
|
||||||
|
def foo(list_a, list_b):
|
||||||
|
results = User.query.filter(User.foo == "bar").filter( # Because foo.
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
).filter(User.xyz.is_(None)).filter(
|
||||||
|
db.not_(User.is_pending.astext.cast(db.Boolean).is_(True))
|
||||||
|
).order_by(User.created_at.desc()).with_for_update(key_share=True).all()
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def foo2(list_a, list_b):
|
||||||
|
# Standalone comment reasonably placed.
|
||||||
|
return User.query.filter(User.foo == "bar").filter(
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
).filter(User.xyz.is_(None))
|
||||||
|
|
||||||
|
|
||||||
|
def foo3(list_a, list_b):
|
||||||
|
return # Standlone comment but weirdly placed.
|
||||||
|
User.query.filter(User.foo == "bar").filter(
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
).filter(User.xyz.is_(None))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent, # NOT DRY
|
||||||
|
)
|
||||||
|
from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import (
|
||||||
|
MyLovelyCompanyTeamProjectComponent as component, # DRY
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class C:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("post_data", "message"),
|
||||||
|
[
|
||||||
|
# metadata_version errors.
|
||||||
|
(
|
||||||
|
{},
|
||||||
|
"None is an invalid value for Metadata-Version. Error: This field is"
|
||||||
|
" required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"metadata_version": "-1"},
|
||||||
|
"'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata"
|
||||||
|
" Version see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
# name errors.
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2"},
|
||||||
|
"'' is an invalid value for Name. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2", "name": "foo-"},
|
||||||
|
"'foo-' is an invalid value for Name. Error: Must start and end with a"
|
||||||
|
" letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
# version errors.
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2", "name": "example"},
|
||||||
|
"'' is an invalid value for Version. Error: This field is required. see"
|
||||||
|
" https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"metadata_version": "1.2", "name": "example", "version": "dog"},
|
||||||
|
"'dog' is an invalid value for Version. Error: Must start and end with"
|
||||||
|
" a letter or numeral and contain only ascii numeric and '.', '_' and"
|
||||||
|
" '-'. see https://packaging.python.org/specifications/core-metadata",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_fails_invalid_post_data(
|
||||||
|
self, pyramid_config, db_request, post_data, message
|
||||||
|
):
|
||||||
|
pyramid_config.testing_securitypolicy(userid=1)
|
||||||
|
db_request.POST = MultiDict(post_data)
|
||||||
|
|
||||||
|
|
||||||
|
def foo(list_a, list_b):
|
||||||
|
results = (
|
||||||
|
User.query.filter(User.foo == "bar")
|
||||||
|
.filter( # Because foo.
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
)
|
||||||
|
.filter(User.xyz.is_(None))
|
||||||
|
# Another comment about the filtering on is_quux goes here.
|
||||||
|
.filter(db.not_(User.is_pending.astext.cast(db.Boolean).is_(True)))
|
||||||
|
.order_by(User.created_at.desc())
|
||||||
|
.with_for_update(key_share=True)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def foo2(list_a, list_b):
|
||||||
|
# Standalone comment reasonably placed.
|
||||||
|
return (
|
||||||
|
User.query.filter(User.foo == "bar")
|
||||||
|
.filter(
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
)
|
||||||
|
.filter(User.xyz.is_(None))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def foo3(list_a, list_b):
|
||||||
|
return (
|
||||||
|
# Standlone comment but weirdly placed.
|
||||||
|
User.query.filter(User.foo == "bar")
|
||||||
|
.filter(
|
||||||
|
db.or_(User.field_a.astext.in_(list_a), User.field_b.astext.in_(list_b))
|
||||||
|
)
|
||||||
|
.filter(User.xyz.is_(None))
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,554 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments6.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Any, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a, # type: int
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# test type comments
|
||||||
|
def f(a, b, c, d, e, f, g, h, i):
|
||||||
|
# type: (int, int, int, int, int, int, int, int, int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a, # type: int
|
||||||
|
b, # type: int
|
||||||
|
c, # type: int
|
||||||
|
d, # type: int
|
||||||
|
e, # type: int
|
||||||
|
f, # type: int
|
||||||
|
g, # type: int
|
||||||
|
h, # type: int
|
||||||
|
i, # type: int
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
arg, # type: int
|
||||||
|
*args, # type: *Any
|
||||||
|
default=False, # type: bool
|
||||||
|
**kwargs, # type: **Any
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a, # type: int
|
||||||
|
b, # type: int
|
||||||
|
c, # type: int
|
||||||
|
d, # type: int
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
|
||||||
|
element = 0 # type: int
|
||||||
|
another_element = 1 # type: float
|
||||||
|
another_element_with_long_name = 2 # type: int
|
||||||
|
another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style = (
|
||||||
|
3
|
||||||
|
) # type: int
|
||||||
|
an_element_with_a_long_value = calls() or more_calls() and more() # type: bool
|
||||||
|
|
||||||
|
tup = (
|
||||||
|
another_element,
|
||||||
|
another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style,
|
||||||
|
) # type: Tuple[int, int]
|
||||||
|
|
||||||
|
a = (
|
||||||
|
element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
+ element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
) # type: int
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
x, # not a type comment
|
||||||
|
y, # type: int
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
x, # not a type comment
|
||||||
|
): # type: (int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func(
|
||||||
|
a=some_list[0], # type: int
|
||||||
|
): # type: () -> int
|
||||||
|
c = call(
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
a[-1], # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
c = call(
|
||||||
|
"aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa" # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
result = ( # aaa
|
||||||
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
)
|
||||||
|
|
||||||
|
AAAAAAAAAAAAA = [AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA # type: ignore
|
||||||
|
|
||||||
|
call_to_some_function_asdf(
|
||||||
|
foo,
|
||||||
|
[AAAAAAAAAAAAAAAAAAAAAAA, AAAAAAAAAAAAAAAAAAAAAAA, AAAAAAAAAAAAAAAAAAAAAAA, BBBBBBBBBBBB], # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -2,8 +2,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
- a, # type: int
|
||||||
|
-):
|
||||||
|
+ a,
|
||||||
|
+): # type: int
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@@ -14,44 +14,42 @@
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
- a, # type: int
|
||||||
|
- b, # type: int
|
||||||
|
- c, # type: int
|
||||||
|
- d, # type: int
|
||||||
|
- e, # type: int
|
||||||
|
- f, # type: int
|
||||||
|
- g, # type: int
|
||||||
|
- h, # type: int
|
||||||
|
- i, # type: int
|
||||||
|
-):
|
||||||
|
+ a,
|
||||||
|
+ b,
|
||||||
|
+ c,
|
||||||
|
+ d,
|
||||||
|
+ e,
|
||||||
|
+ f,
|
||||||
|
+ g,
|
||||||
|
+ h,
|
||||||
|
+ i,
|
||||||
|
+): # type: int# type: int# type: int# type: int# type: int# type: int# type: int# type: int# type: int
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
- arg, # type: int
|
||||||
|
- *args, # type: *Any
|
||||||
|
- default=False, # type: bool
|
||||||
|
- **kwargs, # type: **Any
|
||||||
|
-):
|
||||||
|
+ arg,
|
||||||
|
+ *args,
|
||||||
|
+ default=False,
|
||||||
|
+ **kwargs,
|
||||||
|
+): # type: int# type: *Any
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
- a, # type: int
|
||||||
|
- b, # type: int
|
||||||
|
- c, # type: int
|
||||||
|
- d, # type: int
|
||||||
|
-):
|
||||||
|
+ a,
|
||||||
|
+ b,
|
||||||
|
+ c,
|
||||||
|
+ d,
|
||||||
|
+): # type: int# type: int# type: int# type: int# type: int
|
||||||
|
# type: (...) -> None
|
||||||
|
|
||||||
|
element = 0 # type: int
|
||||||
|
another_element = 1 # type: float
|
||||||
|
another_element_with_long_name = 2 # type: int
|
||||||
|
- another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style = (
|
||||||
|
- 3
|
||||||
|
- ) # type: int
|
||||||
|
+ another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style = 3 # type: int
|
||||||
|
an_element_with_a_long_value = calls() or more_calls() and more() # type: bool
|
||||||
|
|
||||||
|
tup = (
|
||||||
|
@@ -66,26 +64,26 @@
|
||||||
|
+ element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
- ) # type: int
|
||||||
|
+ )
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
- x, # not a type comment
|
||||||
|
- y, # type: int
|
||||||
|
-):
|
||||||
|
+ x,
|
||||||
|
+ y,
|
||||||
|
+): # not a type comment# type: int
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
- x, # not a type comment
|
||||||
|
-): # type: (int) -> None
|
||||||
|
+ x,
|
||||||
|
+): # not a type comment# type: (int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func(
|
||||||
|
- a=some_list[0], # type: int
|
||||||
|
-): # type: () -> int
|
||||||
|
+ a=some_list[0],
|
||||||
|
+):
|
||||||
|
c = call(
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
@@ -96,23 +94,37 @@
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
- a[-1], # type: ignore
|
||||||
|
+ a[-1],
|
||||||
|
)
|
||||||
|
|
||||||
|
c = call(
|
||||||
|
- "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa" # type: ignore
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
+ "aaaaaaaa",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-result = ( # aaa
|
||||||
|
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
-)
|
||||||
|
+result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa
|
||||||
|
|
||||||
|
-AAAAAAAAAAAAA = [AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA # type: ignore
|
||||||
|
+AAAAAAAAAAAAA = (
|
||||||
|
+ [AAAAAAAAAAAAA]
|
||||||
|
+ + SHARED_AAAAAAAAAAAAA
|
||||||
|
+ + USER_AAAAAAAAAAAAA
|
||||||
|
+ + AAAAAAAAAAAAA
|
||||||
|
+) # type: ignore
|
||||||
|
|
||||||
|
call_to_some_function_asdf(
|
||||||
|
foo,
|
||||||
|
- [AAAAAAAAAAAAAAAAAAAAAAA, AAAAAAAAAAAAAAAAAAAAAAA, AAAAAAAAAAAAAAAAAAAAAAA, BBBBBBBBBBBB], # type: ignore
|
||||||
|
+ [
|
||||||
|
+ AAAAAAAAAAAAAAAAAAAAAAA,
|
||||||
|
+ AAAAAAAAAAAAAAAAAAAAAAA,
|
||||||
|
+ AAAAAAAAAAAAAAAAAAAAAAA,
|
||||||
|
+ BBBBBBBBBBBB,
|
||||||
|
+ ],
|
||||||
|
)
|
||||||
|
|
||||||
|
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
|
||||||
|
\ No newline at end of file
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Any, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
): # type: int
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# test type comments
|
||||||
|
def f(a, b, c, d, e, f, g, h, i):
|
||||||
|
# type: (int, int, int, int, int, int, int, int, int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d,
|
||||||
|
e,
|
||||||
|
f,
|
||||||
|
g,
|
||||||
|
h,
|
||||||
|
i,
|
||||||
|
): # type: int# type: int# type: int# type: int# type: int# type: int# type: int# type: int# type: int
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
arg,
|
||||||
|
*args,
|
||||||
|
default=False,
|
||||||
|
**kwargs,
|
||||||
|
): # type: int# type: *Any
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d,
|
||||||
|
): # type: int# type: int# type: int# type: int# type: int
|
||||||
|
# type: (...) -> None
|
||||||
|
|
||||||
|
element = 0 # type: int
|
||||||
|
another_element = 1 # type: float
|
||||||
|
another_element_with_long_name = 2 # type: int
|
||||||
|
another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style = 3 # type: int
|
||||||
|
an_element_with_a_long_value = calls() or more_calls() and more() # type: bool
|
||||||
|
|
||||||
|
tup = (
|
||||||
|
another_element,
|
||||||
|
another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style,
|
||||||
|
) # type: Tuple[int, int]
|
||||||
|
|
||||||
|
a = (
|
||||||
|
element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
+ element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
): # not a type comment# type: int
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
x,
|
||||||
|
): # not a type comment# type: (int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func(
|
||||||
|
a=some_list[0],
|
||||||
|
):
|
||||||
|
c = call(
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
a[-1],
|
||||||
|
)
|
||||||
|
|
||||||
|
c = call(
|
||||||
|
"aaaaaaaa",
|
||||||
|
"aaaaaaaa",
|
||||||
|
"aaaaaaaa",
|
||||||
|
"aaaaaaaa",
|
||||||
|
"aaaaaaaa",
|
||||||
|
"aaaaaaaa",
|
||||||
|
"aaaaaaaa",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa
|
||||||
|
|
||||||
|
AAAAAAAAAAAAA = (
|
||||||
|
[AAAAAAAAAAAAA]
|
||||||
|
+ SHARED_AAAAAAAAAAAAA
|
||||||
|
+ USER_AAAAAAAAAAAAA
|
||||||
|
+ AAAAAAAAAAAAA
|
||||||
|
) # type: ignore
|
||||||
|
|
||||||
|
call_to_some_function_asdf(
|
||||||
|
foo,
|
||||||
|
[
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAA,
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAA,
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAA,
|
||||||
|
BBBBBBBBBBBB,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Any, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a, # type: int
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# test type comments
|
||||||
|
def f(a, b, c, d, e, f, g, h, i):
|
||||||
|
# type: (int, int, int, int, int, int, int, int, int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a, # type: int
|
||||||
|
b, # type: int
|
||||||
|
c, # type: int
|
||||||
|
d, # type: int
|
||||||
|
e, # type: int
|
||||||
|
f, # type: int
|
||||||
|
g, # type: int
|
||||||
|
h, # type: int
|
||||||
|
i, # type: int
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
arg, # type: int
|
||||||
|
*args, # type: *Any
|
||||||
|
default=False, # type: bool
|
||||||
|
**kwargs, # type: **Any
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a, # type: int
|
||||||
|
b, # type: int
|
||||||
|
c, # type: int
|
||||||
|
d, # type: int
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
|
||||||
|
element = 0 # type: int
|
||||||
|
another_element = 1 # type: float
|
||||||
|
another_element_with_long_name = 2 # type: int
|
||||||
|
another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style = (
|
||||||
|
3
|
||||||
|
) # type: int
|
||||||
|
an_element_with_a_long_value = calls() or more_calls() and more() # type: bool
|
||||||
|
|
||||||
|
tup = (
|
||||||
|
another_element,
|
||||||
|
another_really_really_long_element_with_a_unnecessarily_long_name_to_describe_what_it_does_enterprise_style,
|
||||||
|
) # type: Tuple[int, int]
|
||||||
|
|
||||||
|
a = (
|
||||||
|
element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
+ element
|
||||||
|
+ another_element
|
||||||
|
+ another_element_with_long_name
|
||||||
|
) # type: int
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
x, # not a type comment
|
||||||
|
y, # type: int
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
x, # not a type comment
|
||||||
|
): # type: (int) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func(
|
||||||
|
a=some_list[0], # type: int
|
||||||
|
): # type: () -> int
|
||||||
|
c = call(
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
0.0123,
|
||||||
|
0.0456,
|
||||||
|
0.0789,
|
||||||
|
a[-1], # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
c = call(
|
||||||
|
"aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa" # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
result = ( # aaa
|
||||||
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
)
|
||||||
|
|
||||||
|
AAAAAAAAAAAAA = [AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA # type: ignore
|
||||||
|
|
||||||
|
call_to_some_function_asdf(
|
||||||
|
foo,
|
||||||
|
[AAAAAAAAAAAAAAAAAAAAAAA, AAAAAAAAAAAAAAAAAAAAAAA, AAAAAAAAAAAAAAAAAAAAAAA, BBBBBBBBBBBB], # type: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,629 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments9.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Test for https://github.com/psf/black/issues/246.
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
def function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# This multiline comments section
|
||||||
|
# should be split from the statement
|
||||||
|
# above by two lines.
|
||||||
|
def function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
async def async_function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
class MyClass:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# This should be stick to the statement above
|
||||||
|
|
||||||
|
# This should be split from the above by two lines
|
||||||
|
class MyClassWithComplexLeadingComments:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDocstring:
|
||||||
|
"""A docstring."""
|
||||||
|
# Leading comment after a class with just a docstring
|
||||||
|
class MyClassAfterAnotherClassWithDocstring:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
# leading 2
|
||||||
|
# leading 2 extra
|
||||||
|
@deco2(with_args=True)
|
||||||
|
# leading 3
|
||||||
|
@deco3
|
||||||
|
# leading 4
|
||||||
|
def decorated():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
# leading 2
|
||||||
|
@deco2(with_args=True)
|
||||||
|
|
||||||
|
# leading 3 that already has an empty line
|
||||||
|
@deco3
|
||||||
|
# leading 4
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
# leading 2
|
||||||
|
@deco2(with_args=True)
|
||||||
|
# leading 3
|
||||||
|
@deco3
|
||||||
|
|
||||||
|
# leading 4 that already has an empty line
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if a:
|
||||||
|
# Leading comment before inline function
|
||||||
|
def inline():
|
||||||
|
pass
|
||||||
|
# Another leading comment
|
||||||
|
def another_inline():
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# More leading comments
|
||||||
|
def inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if a:
|
||||||
|
# Leading comment before "top-level inline" function
|
||||||
|
def top_level_quote_inline():
|
||||||
|
pass
|
||||||
|
# Another leading comment
|
||||||
|
def another_top_level_quote_inline_inline():
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# More leading comments
|
||||||
|
def top_level_quote_inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MyClass:
|
||||||
|
# First method has no empty lines between bare class def.
|
||||||
|
# More comments.
|
||||||
|
def first_method(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
# Trailing comment that belongs to this function
|
||||||
|
|
||||||
|
|
||||||
|
@decorator1
|
||||||
|
@decorator2 # fmt: skip
|
||||||
|
def bar():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
# Trailing comment that belongs to this function.
|
||||||
|
# NOTE this comment only has one empty line below, and the formatter
|
||||||
|
# should enforce two blank lines.
|
||||||
|
|
||||||
|
@decorator1
|
||||||
|
# A standalone comment
|
||||||
|
def bar():
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -35,9 +35,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
+
|
||||||
|
+
|
||||||
|
# This should be stick to the statement above
|
||||||
|
|
||||||
|
-
|
||||||
|
# This should be split from the above by two lines
|
||||||
|
class MyClassWithComplexLeadingComments:
|
||||||
|
pass
|
||||||
|
@@ -57,13 +58,13 @@
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
-# leading 2
|
||||||
|
+@# leading 2
|
||||||
|
# leading 2 extra
|
||||||
|
-@deco2(with_args=True)
|
||||||
|
-# leading 3
|
||||||
|
-@deco3
|
||||||
|
-# leading 4
|
||||||
|
+deco2(with_args=True)
|
||||||
|
+@# leading 3
|
||||||
|
+deco3
|
||||||
|
def decorated():
|
||||||
|
+ # leading 4
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@@ -72,13 +73,12 @@
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
-# leading 2
|
||||||
|
-@deco2(with_args=True)
|
||||||
|
-
|
||||||
|
-# leading 3 that already has an empty line
|
||||||
|
-@deco3
|
||||||
|
-# leading 4
|
||||||
|
+@# leading 2
|
||||||
|
+deco2(with_args=True)
|
||||||
|
+@# leading 3 that already has an empty line
|
||||||
|
+deco3
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
+ # leading 4
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@@ -87,18 +87,18 @@
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
-# leading 2
|
||||||
|
-@deco2(with_args=True)
|
||||||
|
-# leading 3
|
||||||
|
-@deco3
|
||||||
|
-
|
||||||
|
-# leading 4 that already has an empty line
|
||||||
|
+@# leading 2
|
||||||
|
+deco2(with_args=True)
|
||||||
|
+@# leading 3
|
||||||
|
+deco3
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
+ # leading 4 that already has an empty line
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if a:
|
||||||
|
+
|
||||||
|
# Leading comment before inline function
|
||||||
|
def inline():
|
||||||
|
pass
|
||||||
|
@@ -108,12 +108,14 @@
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
+
|
||||||
|
# More leading comments
|
||||||
|
def inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if a:
|
||||||
|
+
|
||||||
|
# Leading comment before "top-level inline" function
|
||||||
|
def top_level_quote_inline():
|
||||||
|
pass
|
||||||
|
@@ -123,6 +125,7 @@
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
+
|
||||||
|
# More leading comments
|
||||||
|
def top_level_quote_inline_after_else():
|
||||||
|
pass
|
||||||
|
@@ -138,9 +141,11 @@
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
- # Trailing comment that belongs to this function
|
||||||
|
|
||||||
|
|
||||||
|
+# Trailing comment that belongs to this function
|
||||||
|
+
|
||||||
|
+
|
||||||
|
@decorator1
|
||||||
|
@decorator2 # fmt: skip
|
||||||
|
def bar():
|
||||||
|
@@ -150,12 +155,13 @@
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
- # Trailing comment that belongs to this function.
|
||||||
|
- # NOTE this comment only has one empty line below, and the formatter
|
||||||
|
- # should enforce two blank lines.
|
||||||
|
|
||||||
|
|
||||||
|
+# Trailing comment that belongs to this function.
|
||||||
|
+# NOTE this comment only has one empty line below, and the formatter
|
||||||
|
+# should enforce two blank lines.
|
||||||
|
+
|
||||||
|
@decorator1
|
||||||
|
-# A standalone comment
|
||||||
|
def bar():
|
||||||
|
- pass
|
||||||
|
\ No newline at end of file
|
||||||
|
+ # A standalone comment
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Test for https://github.com/psf/black/issues/246.
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
def function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This multiline comments section
|
||||||
|
# should be split from the statement
|
||||||
|
# above by two lines.
|
||||||
|
def function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
async def async_function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
class MyClass:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This should be stick to the statement above
|
||||||
|
|
||||||
|
# This should be split from the above by two lines
|
||||||
|
class MyClassWithComplexLeadingComments:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDocstring:
|
||||||
|
"""A docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# Leading comment after a class with just a docstring
|
||||||
|
class MyClassAfterAnotherClassWithDocstring:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
@# leading 2
|
||||||
|
# leading 2 extra
|
||||||
|
deco2(with_args=True)
|
||||||
|
@# leading 3
|
||||||
|
deco3
|
||||||
|
def decorated():
|
||||||
|
# leading 4
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
@# leading 2
|
||||||
|
deco2(with_args=True)
|
||||||
|
@# leading 3 that already has an empty line
|
||||||
|
deco3
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
# leading 4
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
@# leading 2
|
||||||
|
deco2(with_args=True)
|
||||||
|
@# leading 3
|
||||||
|
deco3
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
# leading 4 that already has an empty line
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if a:
|
||||||
|
|
||||||
|
# Leading comment before inline function
|
||||||
|
def inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Another leading comment
|
||||||
|
def another_inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# More leading comments
|
||||||
|
def inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if a:
|
||||||
|
|
||||||
|
# Leading comment before "top-level inline" function
|
||||||
|
def top_level_quote_inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Another leading comment
|
||||||
|
def another_top_level_quote_inline_inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# More leading comments
|
||||||
|
def top_level_quote_inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MyClass:
|
||||||
|
# First method has no empty lines between bare class def.
|
||||||
|
# More comments.
|
||||||
|
def first_method(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Trailing comment that belongs to this function
|
||||||
|
|
||||||
|
|
||||||
|
@decorator1
|
||||||
|
@decorator2 # fmt: skip
|
||||||
|
def bar():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Trailing comment that belongs to this function.
|
||||||
|
# NOTE this comment only has one empty line below, and the formatter
|
||||||
|
# should enforce two blank lines.
|
||||||
|
|
||||||
|
@decorator1
|
||||||
|
def bar():
|
||||||
|
# A standalone comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Test for https://github.com/psf/black/issues/246.
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
def function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This multiline comments section
|
||||||
|
# should be split from the statement
|
||||||
|
# above by two lines.
|
||||||
|
def function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
async def async_function():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# This comment should be split from the statement above by two lines.
|
||||||
|
class MyClass:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
# This should be stick to the statement above
|
||||||
|
|
||||||
|
|
||||||
|
# This should be split from the above by two lines
|
||||||
|
class MyClassWithComplexLeadingComments:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassWithDocstring:
|
||||||
|
"""A docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# Leading comment after a class with just a docstring
|
||||||
|
class MyClassAfterAnotherClassWithDocstring:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
# leading 2
|
||||||
|
# leading 2 extra
|
||||||
|
@deco2(with_args=True)
|
||||||
|
# leading 3
|
||||||
|
@deco3
|
||||||
|
# leading 4
|
||||||
|
def decorated():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
# leading 2
|
||||||
|
@deco2(with_args=True)
|
||||||
|
|
||||||
|
# leading 3 that already has an empty line
|
||||||
|
@deco3
|
||||||
|
# leading 4
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
some = statement
|
||||||
|
|
||||||
|
|
||||||
|
# leading 1
|
||||||
|
@deco1
|
||||||
|
# leading 2
|
||||||
|
@deco2(with_args=True)
|
||||||
|
# leading 3
|
||||||
|
@deco3
|
||||||
|
|
||||||
|
# leading 4 that already has an empty line
|
||||||
|
def decorated_with_split_leading_comments():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if a:
|
||||||
|
# Leading comment before inline function
|
||||||
|
def inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Another leading comment
|
||||||
|
def another_inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
# More leading comments
|
||||||
|
def inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if a:
|
||||||
|
# Leading comment before "top-level inline" function
|
||||||
|
def top_level_quote_inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Another leading comment
|
||||||
|
def another_top_level_quote_inline_inline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
# More leading comments
|
||||||
|
def top_level_quote_inline_after_else():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MyClass:
|
||||||
|
# First method has no empty lines between bare class def.
|
||||||
|
# More comments.
|
||||||
|
def first_method(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
# Trailing comment that belongs to this function
|
||||||
|
|
||||||
|
|
||||||
|
@decorator1
|
||||||
|
@decorator2 # fmt: skip
|
||||||
|
def bar():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3454.
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
# Trailing comment that belongs to this function.
|
||||||
|
# NOTE this comment only has one empty line below, and the formatter
|
||||||
|
# should enforce two blank lines.
|
||||||
|
|
||||||
|
|
||||||
|
@decorator1
|
||||||
|
# A standalone comment
|
||||||
|
def bar():
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,882 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition_no_trailing_comma.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
class C:
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)), "1 file reformatted, 1 file failed to reformat."
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file left unchanged, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 1 file left unchanged, 1 file failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 2 files left unchanged, 2 files failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
for i in (a,):
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
# Rule 2
|
||||||
|
and i % 3 == 0
|
||||||
|
):
|
||||||
|
while (
|
||||||
|
# Just a comment
|
||||||
|
call()
|
||||||
|
# Another
|
||||||
|
):
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE
|
||||||
|
).push(
|
||||||
|
# Only send the first n items.
|
||||||
|
items=items[:num_items]
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
% (test.name, test.filename, lineno, lname, err)
|
||||||
|
)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
assignment = (
|
||||||
|
some.rather.elaborate.rule() and another.rule.ending_with.index[123]
|
||||||
|
)
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
} == expected, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
}
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
} == expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
} == expected, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
) == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
}, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%3d 0 LOAD_FAST 1 (x)
|
||||||
|
2 LOAD_CONST 1 (1)
|
||||||
|
4 COMPARE_OP 2 (==)
|
||||||
|
6 LOAD_FAST 0 (self)
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
""" % (
|
||||||
|
_C.__init__.__code__.co_firstlineno + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -2,7 +2,8 @@
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
- unstyle(str(report)), "1 file reformatted, 1 file failed to reformat."
|
||||||
|
+ unstyle(str(report)),
|
||||||
|
+ "1 file reformatted, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
@@ -22,133 +23,156 @@
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
- # Rule 2
|
||||||
|
- and i % 3 == 0
|
||||||
|
+ and # Rule 2
|
||||||
|
+ i % 3
|
||||||
|
+ == 0
|
||||||
|
):
|
||||||
|
- while (
|
||||||
|
- # Just a comment
|
||||||
|
- call()
|
||||||
|
+ while # Just a comment
|
||||||
|
+ call():
|
||||||
|
# Another
|
||||||
|
- ):
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
- # Only send the first n items.
|
||||||
|
- items=items[:num_items]
|
||||||
|
+ items=# Only send the first n items.
|
||||||
|
+ items[:num_items]
|
||||||
|
)
|
||||||
|
- return (
|
||||||
|
- 'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
- % (test.name, test.filename, lineno, lname, err)
|
||||||
|
- )
|
||||||
|
+ return 'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
+ % (test.name, test.filename, lineno, lname, err)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
- hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
+ hey_this_is_a_very_long_call,
|
||||||
|
+ it_has_funny_attributes,
|
||||||
|
+ really=True,
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
- hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
+ hey_this_is_a_very_long_call,
|
||||||
|
+ it_has_funny_attributes,
|
||||||
|
+ really=True,
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
- assignment = (
|
||||||
|
- some.rather.elaborate.rule() and another.rule.ending_with.index[123]
|
||||||
|
- )
|
||||||
|
+ assignment = some.rather.elaborate.rule()
|
||||||
|
+ and another.rule.ending_with.index[123]
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
- assert {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- } == expected, "Not what we expected"
|
||||||
|
+ assert (
|
||||||
|
+ {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ == expected
|
||||||
|
+ ), "Not what we expected"
|
||||||
|
|
||||||
|
- assert expected == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }, "Not what we expected"
|
||||||
|
+ assert (
|
||||||
|
+ expected
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ ), "Not what we expected"
|
||||||
|
|
||||||
|
- assert expected == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }
|
||||||
|
+ assert (
|
||||||
|
+ expected
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
- assert {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- } == expected(
|
||||||
|
- value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
+ assert (
|
||||||
|
+ {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ == expected(
|
||||||
|
+ value,
|
||||||
|
+ is_going_to_be="too long to fit in a single line",
|
||||||
|
+ srsly=True,
|
||||||
|
+ )
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
- assert {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- } == expected, (
|
||||||
|
- "Not what we expected and the message is too long to fit in one line"
|
||||||
|
- )
|
||||||
|
+ assert (
|
||||||
|
+ {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ == expected
|
||||||
|
+ ), "Not what we expected and the message is too long to fit in one line"
|
||||||
|
|
||||||
|
- assert expected(
|
||||||
|
- value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
- ) == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }, "Not what we expected"
|
||||||
|
+ assert (
|
||||||
|
+ expected(
|
||||||
|
+ value,
|
||||||
|
+ is_going_to_be="too long to fit in a single line",
|
||||||
|
+ srsly=True,
|
||||||
|
+ )
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ ), "Not what we expected"
|
||||||
|
|
||||||
|
- assert expected == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }, (
|
||||||
|
+ assert (
|
||||||
|
+ expected
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ ), (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
@@ -161,9 +185,8 @@
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
- """ % (
|
||||||
|
- _C.__init__.__code__.co_firstlineno + 1,
|
||||||
|
- )
|
||||||
|
+ """
|
||||||
|
+ % (_C.__init__.__code__.co_firstlineno + 1,)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
@@ -178,4 +201,4 @@
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
- )
|
||||||
|
\ No newline at end of file
|
||||||
|
+ )
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class C:
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file left unchanged, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 1 file left unchanged, 1 file failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 2 files left unchanged, 2 files failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
for i in (a,):
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
and # Rule 2
|
||||||
|
i % 3
|
||||||
|
== 0
|
||||||
|
):
|
||||||
|
while # Just a comment
|
||||||
|
call():
|
||||||
|
# Another
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
items=# Only send the first n items.
|
||||||
|
items[:num_items]
|
||||||
|
)
|
||||||
|
return 'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
% (test.name, test.filename, lineno, lname, err)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call,
|
||||||
|
it_has_funny_attributes,
|
||||||
|
really=True,
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call,
|
||||||
|
it_has_funny_attributes,
|
||||||
|
really=True,
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
assignment = some.rather.elaborate.rule()
|
||||||
|
and another.rule.ending_with.index[123]
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
assert (
|
||||||
|
{
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
== expected
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
assert (
|
||||||
|
{
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
== expected(
|
||||||
|
value,
|
||||||
|
is_going_to_be="too long to fit in a single line",
|
||||||
|
srsly=True,
|
||||||
|
)
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
{
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
== expected
|
||||||
|
), "Not what we expected and the message is too long to fit in one line"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected(
|
||||||
|
value,
|
||||||
|
is_going_to_be="too long to fit in a single line",
|
||||||
|
srsly=True,
|
||||||
|
)
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
), (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%3d 0 LOAD_FAST 1 (x)
|
||||||
|
2 LOAD_CONST 1 (1)
|
||||||
|
4 COMPARE_OP 2 (==)
|
||||||
|
6 LOAD_FAST 0 (self)
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
"""
|
||||||
|
% (_C.__init__.__code__.co_firstlineno + 1,)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class C:
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)), "1 file reformatted, 1 file failed to reformat."
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file left unchanged, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 1 file left unchanged, 1 file failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 2 files left unchanged, 2 files failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
for i in (a,):
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
# Rule 2
|
||||||
|
and i % 3 == 0
|
||||||
|
):
|
||||||
|
while (
|
||||||
|
# Just a comment
|
||||||
|
call()
|
||||||
|
# Another
|
||||||
|
):
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
# Only send the first n items.
|
||||||
|
items=items[:num_items]
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
% (test.name, test.filename, lineno, lname, err)
|
||||||
|
)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
assignment = (
|
||||||
|
some.rather.elaborate.rule() and another.rule.ending_with.index[123]
|
||||||
|
)
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
) == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%3d 0 LOAD_FAST 1 (x)
|
||||||
|
2 LOAD_CONST 1 (1)
|
||||||
|
4 COMPARE_OP 2 (==)
|
||||||
|
6 LOAD_FAST 0 (self)
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
""" % (
|
||||||
|
_C.__init__.__code__.co_firstlineno + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,882 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
class C:
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)), "1 file reformatted, 1 file failed to reformat."
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file left unchanged, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 1 file left unchanged, 1 file failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 2 files left unchanged, 2 files failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
for i in (a,):
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
# Rule 2
|
||||||
|
and i % 3 == 0
|
||||||
|
):
|
||||||
|
while (
|
||||||
|
# Just a comment
|
||||||
|
call()
|
||||||
|
# Another
|
||||||
|
):
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
# Only send the first n items.
|
||||||
|
items=items[:num_items]
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
% (test.name, test.filename, lineno, lname, err)
|
||||||
|
)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
assignment = (
|
||||||
|
some.rather.elaborate.rule() and another.rule.ending_with.index[123]
|
||||||
|
)
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
) == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%3d 0 LOAD_FAST 1 (x)
|
||||||
|
2 LOAD_CONST 1 (1)
|
||||||
|
4 COMPARE_OP 2 (==)
|
||||||
|
6 LOAD_FAST 0 (self)
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
""" % (
|
||||||
|
_C.__init__.__code__.co_firstlineno + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -2,7 +2,8 @@
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
- unstyle(str(report)), "1 file reformatted, 1 file failed to reformat."
|
||||||
|
+ unstyle(str(report)),
|
||||||
|
+ "1 file reformatted, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
@@ -22,133 +23,156 @@
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
- # Rule 2
|
||||||
|
- and i % 3 == 0
|
||||||
|
+ and # Rule 2
|
||||||
|
+ i % 3
|
||||||
|
+ == 0
|
||||||
|
):
|
||||||
|
- while (
|
||||||
|
- # Just a comment
|
||||||
|
- call()
|
||||||
|
+ while # Just a comment
|
||||||
|
+ call():
|
||||||
|
# Another
|
||||||
|
- ):
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
- # Only send the first n items.
|
||||||
|
- items=items[:num_items]
|
||||||
|
+ items=# Only send the first n items.
|
||||||
|
+ items[:num_items]
|
||||||
|
)
|
||||||
|
- return (
|
||||||
|
- 'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
- % (test.name, test.filename, lineno, lname, err)
|
||||||
|
- )
|
||||||
|
+ return 'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
+ % (test.name, test.filename, lineno, lname, err)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
- hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
+ hey_this_is_a_very_long_call,
|
||||||
|
+ it_has_funny_attributes,
|
||||||
|
+ really=True,
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
- hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
+ hey_this_is_a_very_long_call,
|
||||||
|
+ it_has_funny_attributes,
|
||||||
|
+ really=True,
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
- assignment = (
|
||||||
|
- some.rather.elaborate.rule() and another.rule.ending_with.index[123]
|
||||||
|
- )
|
||||||
|
+ assignment = some.rather.elaborate.rule()
|
||||||
|
+ and another.rule.ending_with.index[123]
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
- assert {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- } == expected, "Not what we expected"
|
||||||
|
+ assert (
|
||||||
|
+ {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ == expected
|
||||||
|
+ ), "Not what we expected"
|
||||||
|
|
||||||
|
- assert expected == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }, "Not what we expected"
|
||||||
|
+ assert (
|
||||||
|
+ expected
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ ), "Not what we expected"
|
||||||
|
|
||||||
|
- assert expected == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }
|
||||||
|
+ assert (
|
||||||
|
+ expected
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
- assert {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- } == expected(
|
||||||
|
- value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
+ assert (
|
||||||
|
+ {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ == expected(
|
||||||
|
+ value,
|
||||||
|
+ is_going_to_be="too long to fit in a single line",
|
||||||
|
+ srsly=True,
|
||||||
|
+ )
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
- assert {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- } == expected, (
|
||||||
|
- "Not what we expected and the message is too long to fit in one line"
|
||||||
|
- )
|
||||||
|
+ assert (
|
||||||
|
+ {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ == expected
|
||||||
|
+ ), "Not what we expected and the message is too long to fit in one line"
|
||||||
|
|
||||||
|
- assert expected(
|
||||||
|
- value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
- ) == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }, "Not what we expected"
|
||||||
|
+ assert (
|
||||||
|
+ expected(
|
||||||
|
+ value,
|
||||||
|
+ is_going_to_be="too long to fit in a single line",
|
||||||
|
+ srsly=True,
|
||||||
|
+ )
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ ), "Not what we expected"
|
||||||
|
|
||||||
|
- assert expected == {
|
||||||
|
- key1: value1,
|
||||||
|
- key2: value2,
|
||||||
|
- key3: value3,
|
||||||
|
- key4: value4,
|
||||||
|
- key5: value5,
|
||||||
|
- key6: value6,
|
||||||
|
- key7: value7,
|
||||||
|
- key8: value8,
|
||||||
|
- key9: value9,
|
||||||
|
- }, (
|
||||||
|
+ assert (
|
||||||
|
+ expected
|
||||||
|
+ == {
|
||||||
|
+ key1: value1,
|
||||||
|
+ key2: value2,
|
||||||
|
+ key3: value3,
|
||||||
|
+ key4: value4,
|
||||||
|
+ key5: value5,
|
||||||
|
+ key6: value6,
|
||||||
|
+ key7: value7,
|
||||||
|
+ key8: value8,
|
||||||
|
+ key9: value9,
|
||||||
|
+ }
|
||||||
|
+ ), (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
@@ -161,9 +185,8 @@
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
- """ % (
|
||||||
|
- _C.__init__.__code__.co_firstlineno + 1,
|
||||||
|
- )
|
||||||
|
+ """
|
||||||
|
+ % (_C.__init__.__code__.co_firstlineno + 1,)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
@@ -178,4 +201,4 @@
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
- )
|
||||||
|
\ No newline at end of file
|
||||||
|
+ )
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class C:
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file left unchanged, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 1 file left unchanged, 1 file failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 2 files left unchanged, 2 files failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
for i in (a,):
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
and # Rule 2
|
||||||
|
i % 3
|
||||||
|
== 0
|
||||||
|
):
|
||||||
|
while # Just a comment
|
||||||
|
call():
|
||||||
|
# Another
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
items=# Only send the first n items.
|
||||||
|
items[:num_items]
|
||||||
|
)
|
||||||
|
return 'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
% (test.name, test.filename, lineno, lname, err)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call,
|
||||||
|
it_has_funny_attributes,
|
||||||
|
really=True,
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call,
|
||||||
|
it_has_funny_attributes,
|
||||||
|
really=True,
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
assignment = some.rather.elaborate.rule()
|
||||||
|
and another.rule.ending_with.index[123]
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
assert (
|
||||||
|
{
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
== expected
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
assert (
|
||||||
|
{
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
== expected(
|
||||||
|
value,
|
||||||
|
is_going_to_be="too long to fit in a single line",
|
||||||
|
srsly=True,
|
||||||
|
)
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
{
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
== expected
|
||||||
|
), "Not what we expected and the message is too long to fit in one line"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected(
|
||||||
|
value,
|
||||||
|
is_going_to_be="too long to fit in a single line",
|
||||||
|
srsly=True,
|
||||||
|
)
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expected
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
), (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%3d 0 LOAD_FAST 1 (x)
|
||||||
|
2 LOAD_CONST 1 (1)
|
||||||
|
4 COMPARE_OP 2 (==)
|
||||||
|
6 LOAD_FAST 0 (self)
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
"""
|
||||||
|
% (_C.__init__.__code__.co_firstlineno + 1,)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class C:
|
||||||
|
def test(self) -> None:
|
||||||
|
with patch("black.out", print):
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)), "1 file reformatted, 1 file failed to reformat."
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"1 file reformatted, 1 file left unchanged, 1 file failed to reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 1 file left unchanged, 1 file failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
unstyle(str(report)),
|
||||||
|
"2 files reformatted, 2 files left unchanged, 2 files failed to"
|
||||||
|
" reformat.",
|
||||||
|
)
|
||||||
|
for i in (a,):
|
||||||
|
if (
|
||||||
|
# Rule 1
|
||||||
|
i % 2 == 0
|
||||||
|
# Rule 2
|
||||||
|
and i % 3 == 0
|
||||||
|
):
|
||||||
|
while (
|
||||||
|
# Just a comment
|
||||||
|
call()
|
||||||
|
# Another
|
||||||
|
):
|
||||||
|
print(i)
|
||||||
|
xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
|
||||||
|
push_manager=context.request.resource_manager,
|
||||||
|
max_items_to_push=num_items,
|
||||||
|
batch_size=Yyyy2YyyyYyyyyYyyy.FULL_SIZE,
|
||||||
|
).push(
|
||||||
|
# Only send the first n items.
|
||||||
|
items=items[:num_items]
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
|
||||||
|
% (test.name, test.filename, lineno, lname, err)
|
||||||
|
)
|
||||||
|
|
||||||
|
def omitting_trailers(self) -> None:
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex]
|
||||||
|
get_collection(
|
||||||
|
hey_this_is_a_very_long_call, it_has_funny_attributes, really=True
|
||||||
|
)[OneLevelIndex][TwoLevelIndex][ThreeLevelIndex][FourLevelIndex]
|
||||||
|
d[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][
|
||||||
|
22
|
||||||
|
]
|
||||||
|
assignment = (
|
||||||
|
some.rather.elaborate.rule() and another.rule.ending_with.index[123]
|
||||||
|
)
|
||||||
|
|
||||||
|
def easy_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
|
||||||
|
def tricky_asserts(self) -> None:
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
), "Not what we expected"
|
||||||
|
|
||||||
|
assert {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
} == expected, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert expected(
|
||||||
|
value, is_going_to_be="too long to fit in a single line", srsly=True
|
||||||
|
) == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, "Not what we expected"
|
||||||
|
|
||||||
|
assert expected == {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}, (
|
||||||
|
"Not what we expected and the message is too long to fit in one line"
|
||||||
|
" because it's too long"
|
||||||
|
)
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%3d 0 LOAD_FAST 1 (x)
|
||||||
|
2 LOAD_CONST 1 (1)
|
||||||
|
4 COMPARE_OP 2 (==)
|
||||||
|
6 LOAD_FAST 0 (self)
|
||||||
|
8 STORE_ATTR 0 (x)
|
||||||
|
10 LOAD_CONST 0 (None)
|
||||||
|
12 RETURN_VALUE
|
||||||
|
""" % (
|
||||||
|
_C.__init__.__code__.co_firstlineno + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
|
||||||
|
== {
|
||||||
|
key1: value1,
|
||||||
|
key2: value2,
|
||||||
|
key3: value3,
|
||||||
|
key4: value4,
|
||||||
|
key5: value5,
|
||||||
|
key6: value6,
|
||||||
|
key7: value7,
|
||||||
|
key8: value8,
|
||||||
|
key9: value9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_no_extra_empty_line_before_eof.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Make sure when the file ends with class's docstring,
|
||||||
|
# It doesn't add extra blank lines.
|
||||||
|
class ClassWithDocstring:
|
||||||
|
"""A docstring."""
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
# Make sure when the file ends with class's docstring,
|
||||||
|
# It doesn't add extra blank lines.
|
||||||
|
class ClassWithDocstring:
|
||||||
|
- """A docstring."""
|
||||||
|
\ No newline at end of file
|
||||||
|
+ """A docstring."""
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Make sure when the file ends with class's docstring,
|
||||||
|
# It doesn't add extra blank lines.
|
||||||
|
class ClassWithDocstring:
|
||||||
|
"""A docstring."""
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Make sure when the file ends with class's docstring,
|
||||||
|
# It doesn't add extra blank lines.
|
||||||
|
class ClassWithDocstring:
|
||||||
|
"""A docstring."""
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,419 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/empty_lines.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# leading comment
|
||||||
|
def f():
|
||||||
|
NO = ''
|
||||||
|
SPACE = ' '
|
||||||
|
DOUBLESPACE = ' '
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent # trailing comment
|
||||||
|
v = leaf.value
|
||||||
|
|
||||||
|
if t in ALWAYS_NO_SPACE:
|
||||||
|
pass
|
||||||
|
if t == token.COMMENT: # another trailing comment
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
|
||||||
|
assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}"
|
||||||
|
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
prevp = preceding_leaf(p)
|
||||||
|
if not prevp or prevp.type in OPENING_BRACKETS:
|
||||||
|
|
||||||
|
|
||||||
|
return NO
|
||||||
|
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
if prevp.parent and prevp.parent.type in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.argument,
|
||||||
|
}:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
elif prevp.type == token.DOUBLESTAR:
|
||||||
|
if prevp.parent and prevp.parent.type in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.dictsetmaker,
|
||||||
|
}:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# SECTION BECAUSE SECTIONS
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
def g():
|
||||||
|
NO = ''
|
||||||
|
SPACE = ' '
|
||||||
|
DOUBLESPACE = ' '
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent
|
||||||
|
v = leaf.value
|
||||||
|
|
||||||
|
# Comment because comments
|
||||||
|
|
||||||
|
if t in ALWAYS_NO_SPACE:
|
||||||
|
pass
|
||||||
|
if t == token.COMMENT:
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
# Another comment because more comments
|
||||||
|
assert p is not None, f'INTERNAL ERROR: hand-made leaf without parent: {leaf!r}'
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
prevp = preceding_leaf(p)
|
||||||
|
|
||||||
|
if not prevp or prevp.type in OPENING_BRACKETS:
|
||||||
|
# Start of the line or a bracketed expression.
|
||||||
|
# More than one line for the comment.
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
if prevp.parent and prevp.parent.type in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.argument,
|
||||||
|
}:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -3,9 +3,9 @@
|
||||||
|
|
||||||
|
# leading comment
|
||||||
|
def f():
|
||||||
|
- NO = ""
|
||||||
|
- SPACE = " "
|
||||||
|
- DOUBLESPACE = " "
|
||||||
|
+ NO = ''
|
||||||
|
+ SPACE = ' '
|
||||||
|
+ DOUBLESPACE = ' '
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent # trailing comment
|
||||||
|
@@ -25,23 +25,30 @@
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
- if prevp.parent and prevp.parent.type in {
|
||||||
|
- syms.typedargslist,
|
||||||
|
- syms.varargslist,
|
||||||
|
- syms.parameters,
|
||||||
|
- syms.arglist,
|
||||||
|
- syms.argument,
|
||||||
|
- }:
|
||||||
|
+ if (
|
||||||
|
+ prevp.parent
|
||||||
|
+ and prevp.parent.type
|
||||||
|
+ in {
|
||||||
|
+ syms.typedargslist,
|
||||||
|
+ syms.varargslist,
|
||||||
|
+ syms.parameters,
|
||||||
|
+ syms.arglist,
|
||||||
|
+ syms.argument,
|
||||||
|
+ }
|
||||||
|
+ ):
|
||||||
|
return NO
|
||||||
|
-
|
||||||
|
elif prevp.type == token.DOUBLESTAR:
|
||||||
|
- if prevp.parent and prevp.parent.type in {
|
||||||
|
- syms.typedargslist,
|
||||||
|
- syms.varargslist,
|
||||||
|
- syms.parameters,
|
||||||
|
- syms.arglist,
|
||||||
|
- syms.dictsetmaker,
|
||||||
|
- }:
|
||||||
|
+ if (
|
||||||
|
+ prevp.parent
|
||||||
|
+ and prevp.parent.type
|
||||||
|
+ in {
|
||||||
|
+ syms.typedargslist,
|
||||||
|
+ syms.varargslist,
|
||||||
|
+ syms.parameters,
|
||||||
|
+ syms.arglist,
|
||||||
|
+ syms.dictsetmaker,
|
||||||
|
+ }
|
||||||
|
+ ):
|
||||||
|
return NO
|
||||||
|
|
||||||
|
|
||||||
|
@@ -49,11 +56,10 @@
|
||||||
|
# SECTION BECAUSE SECTIONS
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
-
|
||||||
|
def g():
|
||||||
|
- NO = ""
|
||||||
|
- SPACE = " "
|
||||||
|
- DOUBLESPACE = " "
|
||||||
|
+ NO = ''
|
||||||
|
+ SPACE = ' '
|
||||||
|
+ DOUBLESPACE = ' '
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent
|
||||||
|
@@ -67,7 +73,7 @@
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
# Another comment because more comments
|
||||||
|
- assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}"
|
||||||
|
+ assert p is not None, f'INTERNAL ERROR: hand-made leaf without parent: {leaf!r}'
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
@@ -79,11 +85,15 @@
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
- if prevp.parent and prevp.parent.type in {
|
||||||
|
- syms.typedargslist,
|
||||||
|
- syms.varargslist,
|
||||||
|
- syms.parameters,
|
||||||
|
- syms.arglist,
|
||||||
|
- syms.argument,
|
||||||
|
- }:
|
||||||
|
- return NO
|
||||||
|
\ No newline at end of file
|
||||||
|
+ if (
|
||||||
|
+ prevp.parent
|
||||||
|
+ and prevp.parent.type
|
||||||
|
+ in {
|
||||||
|
+ syms.typedargslist,
|
||||||
|
+ syms.varargslist,
|
||||||
|
+ syms.parameters,
|
||||||
|
+ syms.arglist,
|
||||||
|
+ syms.argument,
|
||||||
|
+ }
|
||||||
|
+ ):
|
||||||
|
+ return NO
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# leading comment
|
||||||
|
def f():
|
||||||
|
NO = ''
|
||||||
|
SPACE = ' '
|
||||||
|
DOUBLESPACE = ' '
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent # trailing comment
|
||||||
|
v = leaf.value
|
||||||
|
|
||||||
|
if t in ALWAYS_NO_SPACE:
|
||||||
|
pass
|
||||||
|
if t == token.COMMENT: # another trailing comment
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}"
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
prevp = preceding_leaf(p)
|
||||||
|
if not prevp or prevp.type in OPENING_BRACKETS:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
if (
|
||||||
|
prevp.parent
|
||||||
|
and prevp.parent.type
|
||||||
|
in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.argument,
|
||||||
|
}
|
||||||
|
):
|
||||||
|
return NO
|
||||||
|
elif prevp.type == token.DOUBLESTAR:
|
||||||
|
if (
|
||||||
|
prevp.parent
|
||||||
|
and prevp.parent.type
|
||||||
|
in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.dictsetmaker,
|
||||||
|
}
|
||||||
|
):
|
||||||
|
return NO
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# SECTION BECAUSE SECTIONS
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
def g():
|
||||||
|
NO = ''
|
||||||
|
SPACE = ' '
|
||||||
|
DOUBLESPACE = ' '
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent
|
||||||
|
v = leaf.value
|
||||||
|
|
||||||
|
# Comment because comments
|
||||||
|
|
||||||
|
if t in ALWAYS_NO_SPACE:
|
||||||
|
pass
|
||||||
|
if t == token.COMMENT:
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
# Another comment because more comments
|
||||||
|
assert p is not None, f'INTERNAL ERROR: hand-made leaf without parent: {leaf!r}'
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
prevp = preceding_leaf(p)
|
||||||
|
|
||||||
|
if not prevp or prevp.type in OPENING_BRACKETS:
|
||||||
|
# Start of the line or a bracketed expression.
|
||||||
|
# More than one line for the comment.
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
if (
|
||||||
|
prevp.parent
|
||||||
|
and prevp.parent.type
|
||||||
|
in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.argument,
|
||||||
|
}
|
||||||
|
):
|
||||||
|
return NO
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# leading comment
|
||||||
|
def f():
|
||||||
|
NO = ""
|
||||||
|
SPACE = " "
|
||||||
|
DOUBLESPACE = " "
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent # trailing comment
|
||||||
|
v = leaf.value
|
||||||
|
|
||||||
|
if t in ALWAYS_NO_SPACE:
|
||||||
|
pass
|
||||||
|
if t == token.COMMENT: # another trailing comment
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}"
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
prevp = preceding_leaf(p)
|
||||||
|
if not prevp or prevp.type in OPENING_BRACKETS:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
if prevp.parent and prevp.parent.type in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.argument,
|
||||||
|
}:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
elif prevp.type == token.DOUBLESTAR:
|
||||||
|
if prevp.parent and prevp.parent.type in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.dictsetmaker,
|
||||||
|
}:
|
||||||
|
return NO
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# SECTION BECAUSE SECTIONS
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
def g():
|
||||||
|
NO = ""
|
||||||
|
SPACE = " "
|
||||||
|
DOUBLESPACE = " "
|
||||||
|
|
||||||
|
t = leaf.type
|
||||||
|
p = leaf.parent
|
||||||
|
v = leaf.value
|
||||||
|
|
||||||
|
# Comment because comments
|
||||||
|
|
||||||
|
if t in ALWAYS_NO_SPACE:
|
||||||
|
pass
|
||||||
|
if t == token.COMMENT:
|
||||||
|
return DOUBLESPACE
|
||||||
|
|
||||||
|
# Another comment because more comments
|
||||||
|
assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}"
|
||||||
|
|
||||||
|
prev = leaf.prev_sibling
|
||||||
|
if not prev:
|
||||||
|
prevp = preceding_leaf(p)
|
||||||
|
|
||||||
|
if not prevp or prevp.type in OPENING_BRACKETS:
|
||||||
|
# Start of the line or a bracketed expression.
|
||||||
|
# More than one line for the comment.
|
||||||
|
return NO
|
||||||
|
|
||||||
|
if prevp.type == token.EQUAL:
|
||||||
|
if prevp.parent and prevp.parent.type in {
|
||||||
|
syms.typedargslist,
|
||||||
|
syms.varargslist,
|
||||||
|
syms.parameters,
|
||||||
|
syms.arglist,
|
||||||
|
syms.argument,
|
||||||
|
}:
|
||||||
|
return NO
|
||||||
|
```
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,210 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff2.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
TmSt = 1
|
||||||
|
TmEx = 2
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
|
||||||
|
# Test data:
|
||||||
|
# Position, Volume, State, TmSt/TmEx/None, [call, [arg1...]]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('test', [
|
||||||
|
|
||||||
|
# Test don't manage the volume
|
||||||
|
[
|
||||||
|
('stuff', 'in')
|
||||||
|
],
|
||||||
|
])
|
||||||
|
def test_fader(test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def check_fader(test):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
# misaligned comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
"""Hey, ho."""
|
||||||
|
assert test.passed()
|
||||||
|
|
||||||
|
def test_calculate_fades():
|
||||||
|
calcs = [
|
||||||
|
# one is zero/none
|
||||||
|
(0, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
(None, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
]
|
||||||
|
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -3,38 +3,42 @@
|
||||||
|
TmSt = 1
|
||||||
|
TmEx = 2
|
||||||
|
|
||||||
|
+
|
||||||
|
# fmt: off
|
||||||
|
|
||||||
|
# Test data:
|
||||||
|
# Position, Volume, State, TmSt/TmEx/None, [call, [arg1...]]
|
||||||
|
-
|
||||||
|
-@pytest.mark.parametrize('test', [
|
||||||
|
|
||||||
|
- # Test don't manage the volume
|
||||||
|
+@pytest.mark.parametrize(
|
||||||
|
+ 'test',
|
||||||
|
[
|
||||||
|
- ('stuff', 'in')
|
||||||
|
+ # Test don't manage the volume
|
||||||
|
+ [('stuff', 'in')],
|
||||||
|
],
|
||||||
|
-])
|
||||||
|
+)
|
||||||
|
def test_fader(test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
+
|
||||||
|
def check_fader(test):
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
- pass
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
- # misaligned comment
|
||||||
|
+ # misaligned comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
+
|
||||||
|
def verify_fader(test):
|
||||||
|
"""Hey, ho."""
|
||||||
|
assert test.passed()
|
||||||
|
|
||||||
|
+
|
||||||
|
def test_calculate_fades():
|
||||||
|
calcs = [
|
||||||
|
- # one is zero/none
|
||||||
|
- (0, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
- (None, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
+ (# one is zero/none
|
||||||
|
+ 0, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
+ (None, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
]
|
||||||
|
|
||||||
|
-# fmt: on
|
||||||
|
\ No newline at end of file
|
||||||
|
+# fmt: on
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
TmSt = 1
|
||||||
|
TmEx = 2
|
||||||
|
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
|
||||||
|
# Test data:
|
||||||
|
# Position, Volume, State, TmSt/TmEx/None, [call, [arg1...]]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'test',
|
||||||
|
[
|
||||||
|
# Test don't manage the volume
|
||||||
|
[('stuff', 'in')],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_fader(test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def check_fader(test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
# misaligned comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
"""Hey, ho."""
|
||||||
|
assert test.passed()
|
||||||
|
|
||||||
|
|
||||||
|
def test_calculate_fades():
|
||||||
|
calcs = [
|
||||||
|
(# one is zero/none
|
||||||
|
0, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
(None, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
]
|
||||||
|
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
TmSt = 1
|
||||||
|
TmEx = 2
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
|
||||||
|
# Test data:
|
||||||
|
# Position, Volume, State, TmSt/TmEx/None, [call, [arg1...]]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('test', [
|
||||||
|
|
||||||
|
# Test don't manage the volume
|
||||||
|
[
|
||||||
|
('stuff', 'in')
|
||||||
|
],
|
||||||
|
])
|
||||||
|
def test_fader(test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def check_fader(test):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
# misaligned comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
def verify_fader(test):
|
||||||
|
"""Hey, ho."""
|
||||||
|
assert test.passed()
|
||||||
|
|
||||||
|
def test_calculate_fades():
|
||||||
|
calcs = [
|
||||||
|
# one is zero/none
|
||||||
|
(0, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
(None, 4, 0, 0, 10, 0, 0, 6, 10),
|
||||||
|
]
|
||||||
|
|
||||||
|
# fmt: on
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff3.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
x = [
|
||||||
|
1, 2, 3, 4
|
||||||
|
]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,14 +1,18 @@
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
- 1, 2,
|
||||||
|
- 3, 4,
|
||||||
|
+ 1,
|
||||||
|
+ 2,
|
||||||
|
+ 3,
|
||||||
|
+ 4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
- 1, 2,
|
||||||
|
- 3, 4,
|
||||||
|
+ 1,
|
||||||
|
+ 2,
|
||||||
|
+ 3,
|
||||||
|
+ 4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
x = [1, 2, 3, 4]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
x = [
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
x = [1, 2, 3, 4]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff4.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
# fmt: off
|
||||||
|
@test([
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
])
|
||||||
|
# fmt: on
|
||||||
|
def f(): pass
|
||||||
|
|
||||||
|
@test([
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
])
|
||||||
|
def f(): pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,10 +1,14 @@
|
||||||
|
# fmt: off
|
||||||
|
-@test([
|
||||||
|
- 1, 2,
|
||||||
|
- 3, 4,
|
||||||
|
-])
|
||||||
|
-# fmt: on
|
||||||
|
+@test(
|
||||||
|
+ [
|
||||||
|
+ 1,
|
||||||
|
+ 2,
|
||||||
|
+ 3,
|
||||||
|
+ 4,
|
||||||
|
+ ]
|
||||||
|
+)
|
||||||
|
def f():
|
||||||
|
+ # fmt: on
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@@ -17,4 +21,4 @@
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def f():
|
||||||
|
- pass
|
||||||
|
\ No newline at end of file
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# fmt: off
|
||||||
|
@test(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def f():
|
||||||
|
# fmt: on
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@test(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def f():
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# fmt: off
|
||||||
|
@test([
|
||||||
|
1, 2,
|
||||||
|
3, 4,
|
||||||
|
])
|
||||||
|
# fmt: on
|
||||||
|
def f():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@test(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def f():
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,378 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff5.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3129.
|
||||||
|
setup(
|
||||||
|
entry_points={
|
||||||
|
# fmt: off
|
||||||
|
"console_scripts": [
|
||||||
|
"foo-bar"
|
||||||
|
"=foo.bar.:main",
|
||||||
|
# fmt: on
|
||||||
|
] # Includes an formatted indentation.
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2015.
|
||||||
|
run(
|
||||||
|
# fmt: off
|
||||||
|
[
|
||||||
|
"ls",
|
||||||
|
"-la",
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
+ path,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3026.
|
||||||
|
def test_func():
|
||||||
|
# yapf: disable
|
||||||
|
if unformatted( args ):
|
||||||
|
return True
|
||||||
|
# yapf: enable
|
||||||
|
elif b:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2567.
|
||||||
|
if True:
|
||||||
|
# fmt: off
|
||||||
|
for _ in range( 1 ):
|
||||||
|
# fmt: on
|
||||||
|
print ( "This won't be formatted" )
|
||||||
|
print ( "This won't be formatted either" )
|
||||||
|
else:
|
||||||
|
print ( "This will be formatted" )
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3184.
|
||||||
|
class A:
|
||||||
|
async def call(param):
|
||||||
|
if param:
|
||||||
|
# fmt: off
|
||||||
|
if param[0:4] in (
|
||||||
|
"ABCD", "EFGH"
|
||||||
|
) :
|
||||||
|
# fmt: on
|
||||||
|
print ( "This won't be formatted" )
|
||||||
|
|
||||||
|
elif param[0:4] in ("ZZZZ",):
|
||||||
|
print ( "This won't be formatted either" )
|
||||||
|
|
||||||
|
print ( "This will be formatted" )
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2985.
|
||||||
|
class Named(t.Protocol):
|
||||||
|
# fmt: off
|
||||||
|
@property
|
||||||
|
def this_wont_be_formatted ( self ) -> str: ...
|
||||||
|
|
||||||
|
class Factory(t.Protocol):
|
||||||
|
def this_will_be_formatted ( self, **kwargs ) -> Named: ...
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3436.
|
||||||
|
if x:
|
||||||
|
return x
|
||||||
|
# fmt: off
|
||||||
|
elif unformatted:
|
||||||
|
# fmt: on
|
||||||
|
will_be_formatted ()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -5,8 +5,7 @@
|
||||||
|
"console_scripts": [
|
||||||
|
"foo-bar"
|
||||||
|
"=foo.bar.:main",
|
||||||
|
- # fmt: on
|
||||||
|
- ] # Includes an formatted indentation.
|
||||||
|
+ ],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -18,8 +17,8 @@
|
||||||
|
"ls",
|
||||||
|
"-la",
|
||||||
|
]
|
||||||
|
- # fmt: on
|
||||||
|
- + path,
|
||||||
|
+ + # fmt: on
|
||||||
|
+ path,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -27,9 +26,8 @@
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3026.
|
||||||
|
def test_func():
|
||||||
|
# yapf: disable
|
||||||
|
- if unformatted( args ):
|
||||||
|
+ if unformatted(args):
|
||||||
|
return True
|
||||||
|
- # yapf: enable
|
||||||
|
elif b:
|
||||||
|
return True
|
||||||
|
|
||||||
|
@@ -39,10 +37,10 @@
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2567.
|
||||||
|
if True:
|
||||||
|
# fmt: off
|
||||||
|
- for _ in range( 1 ):
|
||||||
|
- # fmt: on
|
||||||
|
- print ( "This won't be formatted" )
|
||||||
|
- print ( "This won't be formatted either" )
|
||||||
|
+ for _ in range(1):
|
||||||
|
+ # fmt: on
|
||||||
|
+ print("This won't be formatted")
|
||||||
|
+ print("This won't be formatted either")
|
||||||
|
else:
|
||||||
|
print("This will be formatted")
|
||||||
|
|
||||||
|
@@ -52,14 +50,11 @@
|
||||||
|
async def call(param):
|
||||||
|
if param:
|
||||||
|
# fmt: off
|
||||||
|
- if param[0:4] in (
|
||||||
|
- "ABCD", "EFGH"
|
||||||
|
- ) :
|
||||||
|
+ if param[0:4] in ("ABCD", "EFGH"):
|
||||||
|
# fmt: on
|
||||||
|
- print ( "This won't be formatted" )
|
||||||
|
-
|
||||||
|
+ print("This won't be formatted")
|
||||||
|
elif param[0:4] in ("ZZZZ",):
|
||||||
|
- print ( "This won't be formatted either" )
|
||||||
|
+ print("This won't be formatted either")
|
||||||
|
|
||||||
|
print("This will be formatted")
|
||||||
|
|
||||||
|
@@ -68,20 +63,21 @@
|
||||||
|
class Named(t.Protocol):
|
||||||
|
# fmt: off
|
||||||
|
@property
|
||||||
|
- def this_wont_be_formatted ( self ) -> str: ...
|
||||||
|
+ def this_wont_be_formatted(self) -> str:
|
||||||
|
+ ...
|
||||||
|
|
||||||
|
|
||||||
|
class Factory(t.Protocol):
|
||||||
|
def this_will_be_formatted(self, **kwargs) -> Named:
|
||||||
|
...
|
||||||
|
|
||||||
|
- # fmt: on
|
||||||
|
|
||||||
|
+# fmt: on
|
||||||
|
+
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3436.
|
||||||
|
if x:
|
||||||
|
return x
|
||||||
|
-# fmt: off
|
||||||
|
-elif unformatted:
|
||||||
|
+elif unformatted:
|
||||||
|
# fmt: on
|
||||||
|
- will_be_formatted()
|
||||||
|
\ No newline at end of file
|
||||||
|
+ will_be_formatted()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3129.
|
||||||
|
setup(
|
||||||
|
entry_points={
|
||||||
|
# fmt: off
|
||||||
|
"console_scripts": [
|
||||||
|
"foo-bar"
|
||||||
|
"=foo.bar.:main",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2015.
|
||||||
|
run(
|
||||||
|
# fmt: off
|
||||||
|
[
|
||||||
|
"ls",
|
||||||
|
"-la",
|
||||||
|
]
|
||||||
|
+ # fmt: on
|
||||||
|
path,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3026.
|
||||||
|
def test_func():
|
||||||
|
# yapf: disable
|
||||||
|
if unformatted(args):
|
||||||
|
return True
|
||||||
|
elif b:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2567.
|
||||||
|
if True:
|
||||||
|
# fmt: off
|
||||||
|
for _ in range(1):
|
||||||
|
# fmt: on
|
||||||
|
print("This won't be formatted")
|
||||||
|
print("This won't be formatted either")
|
||||||
|
else:
|
||||||
|
print("This will be formatted")
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3184.
|
||||||
|
class A:
|
||||||
|
async def call(param):
|
||||||
|
if param:
|
||||||
|
# fmt: off
|
||||||
|
if param[0:4] in ("ABCD", "EFGH"):
|
||||||
|
# fmt: on
|
||||||
|
print("This won't be formatted")
|
||||||
|
elif param[0:4] in ("ZZZZ",):
|
||||||
|
print("This won't be formatted either")
|
||||||
|
|
||||||
|
print("This will be formatted")
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2985.
|
||||||
|
class Named(t.Protocol):
|
||||||
|
# fmt: off
|
||||||
|
@property
|
||||||
|
def this_wont_be_formatted(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class Factory(t.Protocol):
|
||||||
|
def this_will_be_formatted(self, **kwargs) -> Named:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3436.
|
||||||
|
if x:
|
||||||
|
return x
|
||||||
|
elif unformatted:
|
||||||
|
# fmt: on
|
||||||
|
will_be_formatted()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3129.
|
||||||
|
setup(
|
||||||
|
entry_points={
|
||||||
|
# fmt: off
|
||||||
|
"console_scripts": [
|
||||||
|
"foo-bar"
|
||||||
|
"=foo.bar.:main",
|
||||||
|
# fmt: on
|
||||||
|
] # Includes an formatted indentation.
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2015.
|
||||||
|
run(
|
||||||
|
# fmt: off
|
||||||
|
[
|
||||||
|
"ls",
|
||||||
|
"-la",
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
+ path,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3026.
|
||||||
|
def test_func():
|
||||||
|
# yapf: disable
|
||||||
|
if unformatted( args ):
|
||||||
|
return True
|
||||||
|
# yapf: enable
|
||||||
|
elif b:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2567.
|
||||||
|
if True:
|
||||||
|
# fmt: off
|
||||||
|
for _ in range( 1 ):
|
||||||
|
# fmt: on
|
||||||
|
print ( "This won't be formatted" )
|
||||||
|
print ( "This won't be formatted either" )
|
||||||
|
else:
|
||||||
|
print("This will be formatted")
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3184.
|
||||||
|
class A:
|
||||||
|
async def call(param):
|
||||||
|
if param:
|
||||||
|
# fmt: off
|
||||||
|
if param[0:4] in (
|
||||||
|
"ABCD", "EFGH"
|
||||||
|
) :
|
||||||
|
# fmt: on
|
||||||
|
print ( "This won't be formatted" )
|
||||||
|
|
||||||
|
elif param[0:4] in ("ZZZZ",):
|
||||||
|
print ( "This won't be formatted either" )
|
||||||
|
|
||||||
|
print("This will be formatted")
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/2985.
|
||||||
|
class Named(t.Protocol):
|
||||||
|
# fmt: off
|
||||||
|
@property
|
||||||
|
def this_wont_be_formatted ( self ) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
|
class Factory(t.Protocol):
|
||||||
|
def this_will_be_formatted(self, **kwargs) -> Named:
|
||||||
|
...
|
||||||
|
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
# Regression test for https://github.com/psf/black/issues/3436.
|
||||||
|
if x:
|
||||||
|
return x
|
||||||
|
# fmt: off
|
||||||
|
elif unformatted:
|
||||||
|
# fmt: on
|
||||||
|
will_be_formatted()
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip2.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
l1 = ["This list should be broken up", "into multiple lines", "because it is way too long"]
|
||||||
|
l2 = ["But this list shouldn't", "even though it also has", "way too many characters in it"] # fmt: skip
|
||||||
|
l3 = ["I have", "trailing comma", "so I should be braked",]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -3,7 +3,11 @@
|
||||||
|
"into multiple lines",
|
||||||
|
"because it is way too long",
|
||||||
|
]
|
||||||
|
-l2 = ["But this list shouldn't", "even though it also has", "way too many characters in it"] # fmt: skip
|
||||||
|
+l2 = [
|
||||||
|
+ "But this list shouldn't",
|
||||||
|
+ "even though it also has",
|
||||||
|
+ "way too many characters in it",
|
||||||
|
+] # fmt: skip
|
||||||
|
l3 = [
|
||||||
|
"I have",
|
||||||
|
"trailing comma",
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
l1 = [
|
||||||
|
"This list should be broken up",
|
||||||
|
"into multiple lines",
|
||||||
|
"because it is way too long",
|
||||||
|
]
|
||||||
|
l2 = [
|
||||||
|
"But this list shouldn't",
|
||||||
|
"even though it also has",
|
||||||
|
"way too many characters in it",
|
||||||
|
] # fmt: skip
|
||||||
|
l3 = [
|
||||||
|
"I have",
|
||||||
|
"trailing comma",
|
||||||
|
"so I should be braked",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
l1 = [
|
||||||
|
"This list should be broken up",
|
||||||
|
"into multiple lines",
|
||||||
|
"because it is way too long",
|
||||||
|
]
|
||||||
|
l2 = ["But this list shouldn't", "even though it also has", "way too many characters in it"] # fmt: skip
|
||||||
|
l3 = [
|
||||||
|
"I have",
|
||||||
|
"trailing comma",
|
||||||
|
"so I should be braked",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip3.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
a = 3
|
||||||
|
# fmt: off
|
||||||
|
b, c = 1, 2
|
||||||
|
d = 6 # fmt: skip
|
||||||
|
e = 5
|
||||||
|
# fmt: on
|
||||||
|
f = ["This is a very long line that should be formatted into a clearer line ", "by rearranging."]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
a = 3
|
||||||
|
# fmt: off
|
||||||
|
-b, c = 1, 2
|
||||||
|
-d = 6 # fmt: skip
|
||||||
|
+b, c = 1, 2
|
||||||
|
+d = 6 # fmt: skip
|
||||||
|
e = 5
|
||||||
|
# fmt: on
|
||||||
|
f = [
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a = 3
|
||||||
|
# fmt: off
|
||||||
|
b, c = 1, 2
|
||||||
|
d = 6 # fmt: skip
|
||||||
|
e = 5
|
||||||
|
# fmt: on
|
||||||
|
f = [
|
||||||
|
"This is a very long line that should be formatted into a clearer line ",
|
||||||
|
"by rearranging.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a = 3
|
||||||
|
# fmt: off
|
||||||
|
b, c = 1, 2
|
||||||
|
d = 6 # fmt: skip
|
||||||
|
e = 5
|
||||||
|
# fmt: on
|
||||||
|
f = [
|
||||||
|
"This is a very long line that should be formatted into a clearer line ",
|
||||||
|
"by rearranging.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip5.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
a, b, c = 3, 4, 5
|
||||||
|
if (
|
||||||
|
a == 3
|
||||||
|
and b != 9 # fmt: skip
|
||||||
|
and c is not None
|
||||||
|
):
|
||||||
|
print("I'm good!")
|
||||||
|
else:
|
||||||
|
print("I'm bad")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,9 +1,5 @@
|
||||||
|
a, b, c = 3, 4, 5
|
||||||
|
-if (
|
||||||
|
- a == 3
|
||||||
|
- and b != 9 # fmt: skip
|
||||||
|
- and c is not None
|
||||||
|
-):
|
||||||
|
+if a == 3 and b != 9 and c is not None: # fmt: skip
|
||||||
|
print("I'm good!")
|
||||||
|
else:
|
||||||
|
- print("I'm bad")
|
||||||
|
\ No newline at end of file
|
||||||
|
+ print("I'm bad")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a, b, c = 3, 4, 5
|
||||||
|
if a == 3 and b != 9 and c is not None: # fmt: skip
|
||||||
|
print("I'm good!")
|
||||||
|
else:
|
||||||
|
print("I'm bad")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a, b, c = 3, 4, 5
|
||||||
|
if (
|
||||||
|
a == 3
|
||||||
|
and b != 9 # fmt: skip
|
||||||
|
and c is not None
|
||||||
|
):
|
||||||
|
print("I'm good!")
|
||||||
|
else:
|
||||||
|
print("I'm bad")
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
class A:
|
||||||
|
def f(self):
|
||||||
|
for line in range(10):
|
||||||
|
if True:
|
||||||
|
pass # fmt: skip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -2,4 +2,4 @@
|
||||||
|
def f(self):
|
||||||
|
for line in range(10):
|
||||||
|
if True:
|
||||||
|
- pass # fmt: skip
|
||||||
|
\ No newline at end of file
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class A:
|
||||||
|
def f(self):
|
||||||
|
for line in range(10):
|
||||||
|
if True:
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
class A:
|
||||||
|
def f(self):
|
||||||
|
for line in range(10):
|
||||||
|
if True:
|
||||||
|
pass # fmt: skip
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip7.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
a = "this is some code"
|
||||||
|
b = 5 #fmt:skip
|
||||||
|
c = 9 #fmt: skip
|
||||||
|
d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" #fmt:skip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
a = "this is some code"
|
||||||
|
-b = 5 # fmt:skip
|
||||||
|
-c = 9 # fmt: skip
|
||||||
|
-d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" # fmt:skip
|
||||||
|
\ No newline at end of file
|
||||||
|
+b = 5 #fmt:skip
|
||||||
|
+c = 9 #fmt: skip
|
||||||
|
+d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" #fmt:skip
|
||||||
|
\ No newline at end of file
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a = "this is some code"
|
||||||
|
b = 5 #fmt:skip
|
||||||
|
c = 9 #fmt: skip
|
||||||
|
d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" #fmt:skip
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a = "this is some code"
|
||||||
|
b = 5 # fmt:skip
|
||||||
|
c = 9 # fmt: skip
|
||||||
|
d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" # fmt:skip
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
a, b = 1, 2
|
||||||
|
c = 6 # fmt: skip
|
||||||
|
d = 5
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,3 +1,3 @@
|
||||||
|
a, b = 1, 2
|
||||||
|
-c = 6 # fmt: skip
|
||||||
|
+c = 6 # fmt: skip
|
||||||
|
d = 5
|
||||||
|
\ No newline at end of file
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a, b = 1, 2
|
||||||
|
c = 6 # fmt: skip
|
||||||
|
d = 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
a, b = 1, 2
|
||||||
|
c = 6 # fmt: skip
|
||||||
|
d = 5
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fstring.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
f"f-string without formatted values is just a string"
|
||||||
|
f"{{NOT a formatted value}}"
|
||||||
|
f"{{NOT 'a' \"formatted\" \"value\"}}"
|
||||||
|
f"some f-string with {a} {few():.2f} {formatted.values!r}"
|
||||||
|
f'some f-string with {a} {few(""):.2f} {formatted.values!r}'
|
||||||
|
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"}\''
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
f"f-string without formatted values is just a string"
|
||||||
|
f"{{NOT a formatted value}}"
|
||||||
|
-f'{{NOT \'a\' "formatted" "value"}}'
|
||||||
|
+f"{{NOT 'a' \"formatted\" \"value\"}}"
|
||||||
|
f"some f-string with {a} {few():.2f} {formatted.values!r}"
|
||||||
|
f'some f-string with {a} {few(""):.2f} {formatted.values!r}'
|
||||||
|
f"{f'''{'nested'} inner'''} outer"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
f"f-string without formatted values is just a string"
|
||||||
|
f"{{NOT a formatted value}}"
|
||||||
|
f"{{NOT 'a' \"formatted\" \"value\"}}"
|
||||||
|
f"some f-string with {a} {few():.2f} {formatted.values!r}"
|
||||||
|
f'some f-string with {a} {few(""):.2f} {formatted.values!r}'
|
||||||
|
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"}\''
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
f"f-string without formatted values is just a string"
|
||||||
|
f"{{NOT a formatted value}}"
|
||||||
|
f'{{NOT \'a\' "formatted" "value"}}'
|
||||||
|
f"some f-string with {a} {few():.2f} {formatted.values!r}"
|
||||||
|
f'some f-string with {a} {few(""):.2f} {formatted.values!r}'
|
||||||
|
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"}\''
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function2.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
with cache_dir():
|
||||||
|
if something:
|
||||||
|
result = (
|
||||||
|
CliRunner().invoke(black.main, [str(src1), str(src2), "--diff", "--check"])
|
||||||
|
)
|
||||||
|
limited.append(-limited.pop()) # negate top
|
||||||
|
return A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=-very.long.value.for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
def g():
|
||||||
|
"Docstring."
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
print("Inner defs should breathe a little.")
|
||||||
|
def h():
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
print("Inner defs should breathe a little.")
|
||||||
|
|
||||||
|
|
||||||
|
if os.name == "posix":
|
||||||
|
import termios
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
elif os.name == "nt":
|
||||||
|
try:
|
||||||
|
import msvcrt
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif False:
|
||||||
|
|
||||||
|
class IHopeYouAreHavingALovelyDay:
|
||||||
|
def __call__(self):
|
||||||
|
print("i_should_be_followed_by_only_one_newline")
|
||||||
|
else:
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
|
||||||
|
with hmm_but_this_should_get_two_preceding_newlines():
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -63,4 +63,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
with hmm_but_this_should_get_two_preceding_newlines():
|
||||||
|
- pass
|
||||||
|
\ No newline at end of file
|
||||||
|
+ pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
with cache_dir():
|
||||||
|
if something:
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
black.main,
|
||||||
|
[str(src1), str(src2), "--diff", "--check"],
|
||||||
|
)
|
||||||
|
limited.append(-limited.pop()) # negate top
|
||||||
|
return A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=-very.long.value.for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def g():
|
||||||
|
"Docstring."
|
||||||
|
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
|
||||||
|
print("Inner defs should breathe a little.")
|
||||||
|
|
||||||
|
|
||||||
|
def h():
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
|
||||||
|
print("Inner defs should breathe a little.")
|
||||||
|
|
||||||
|
|
||||||
|
if os.name == "posix":
|
||||||
|
import termios
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif os.name == "nt":
|
||||||
|
try:
|
||||||
|
import msvcrt
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif False:
|
||||||
|
|
||||||
|
class IHopeYouAreHavingALovelyDay:
|
||||||
|
def __call__(self):
|
||||||
|
print("i_should_be_followed_by_only_one_newline")
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
with hmm_but_this_should_get_two_preceding_newlines():
|
||||||
|
pass
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
with cache_dir():
|
||||||
|
if something:
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
black.main,
|
||||||
|
[str(src1), str(src2), "--diff", "--check"],
|
||||||
|
)
|
||||||
|
limited.append(-limited.pop()) # negate top
|
||||||
|
return A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=-very.long.value.for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def g():
|
||||||
|
"Docstring."
|
||||||
|
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
|
||||||
|
print("Inner defs should breathe a little.")
|
||||||
|
|
||||||
|
|
||||||
|
def h():
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
|
||||||
|
print("Inner defs should breathe a little.")
|
||||||
|
|
||||||
|
|
||||||
|
if os.name == "posix":
|
||||||
|
import termios
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif os.name == "nt":
|
||||||
|
try:
|
||||||
|
import msvcrt
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
|
||||||
|
def i_should_be_followed_by_only_one_newline():
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif False:
|
||||||
|
|
||||||
|
class IHopeYouAreHavingALovelyDay:
|
||||||
|
def __call__(self):
|
||||||
|
print("i_should_be_followed_by_only_one_newline")
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
with hmm_but_this_should_get_two_preceding_newlines():
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,493 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from third_party import X, Y, Z
|
||||||
|
|
||||||
|
from library import some_connection, \
|
||||||
|
some_decorator
|
||||||
|
f'trigger 3.6 mode'
|
||||||
|
def func_no_args():
|
||||||
|
a; b; c
|
||||||
|
if True: raise RuntimeError
|
||||||
|
if False: ...
|
||||||
|
for i in range(10):
|
||||||
|
print(i)
|
||||||
|
continue
|
||||||
|
exec("new-style exec", {}, {})
|
||||||
|
return None
|
||||||
|
async def coroutine(arg, exec=False):
|
||||||
|
"Single-line docstring. Multiline is harder to reformat."
|
||||||
|
async with some_connection() as conn:
|
||||||
|
await conn.do_what_i_mean('SELECT bobby, tables FROM xkcd', timeout=2)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
@asyncio.coroutine
|
||||||
|
@some_decorator(
|
||||||
|
with_args=True,
|
||||||
|
many_args=[1,2,3]
|
||||||
|
)
|
||||||
|
def function_signature_stress_test(number:int,no_annotation=None,text:str="default",* ,debug:bool=False,**kwargs) -> str:
|
||||||
|
return text[number:-1]
|
||||||
|
def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r''):
|
||||||
|
offset = attr.ib(default=attr.Factory( lambda: _r.uniform(10000, 200000)))
|
||||||
|
assert task._cancel_stack[:len(old_stack)] == old_stack
|
||||||
|
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)
|
||||||
|
|
||||||
|
def example(session):
|
||||||
|
result = session.query(models.Customer.id).filter(
|
||||||
|
models.Customer.account_id == account_id,
|
||||||
|
models.Customer.email == email_address,
|
||||||
|
).order_by(
|
||||||
|
models.Customer.id.asc()
|
||||||
|
).all()
|
||||||
|
def long_lines():
|
||||||
|
if True:
|
||||||
|
typedargslist.extend(
|
||||||
|
gen_annotated_params(ast_args.kwonlyargs, ast_args.kw_defaults, parameters, implicit_default=True)
|
||||||
|
)
|
||||||
|
typedargslist.extend(
|
||||||
|
gen_annotated_params(
|
||||||
|
ast_args.kwonlyargs, ast_args.kw_defaults, parameters, implicit_default=True,
|
||||||
|
# trailing standalone comment
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_type_comment_re = re.compile(
|
||||||
|
r"""
|
||||||
|
^
|
||||||
|
[\t ]*
|
||||||
|
\#[ ]type:[ ]*
|
||||||
|
(?P<type>
|
||||||
|
[^#\t\n]+?
|
||||||
|
)
|
||||||
|
(?<!ignore) # note: this will force the non-greedy + in <type> to match
|
||||||
|
# a trailing space which is why we need the silliness below
|
||||||
|
(?<!ignore[ ]{1})(?<!ignore[ ]{2})(?<!ignore[ ]{3})(?<!ignore[ ]{4})
|
||||||
|
(?<!ignore[ ]{5})(?<!ignore[ ]{6})(?<!ignore[ ]{7})(?<!ignore[ ]{8})
|
||||||
|
(?<!ignore[ ]{9})(?<!ignore[ ]{10})
|
||||||
|
[\t ]*
|
||||||
|
(?P<nl>
|
||||||
|
(?:\#[^\n]*)?
|
||||||
|
\n?
|
||||||
|
)
|
||||||
|
$
|
||||||
|
""", re.MULTILINE | re.VERBOSE
|
||||||
|
)
|
||||||
|
def trailing_comma():
|
||||||
|
mapping = {
|
||||||
|
A: 0.25 * (10.0 / 12),
|
||||||
|
B: 0.1 * (10.0 / 12),
|
||||||
|
C: 0.1 * (10.0 / 12),
|
||||||
|
D: 0.1 * (10.0 / 12),
|
||||||
|
}
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
return (
|
||||||
|
yield from A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=very_long_value_for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
def __await__(): return (yield)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -6,7 +6,7 @@
|
||||||
|
|
||||||
|
from library import some_connection, some_decorator
|
||||||
|
|
||||||
|
-f"trigger 3.6 mode"
|
||||||
|
+f'trigger 3.6 mode'
|
||||||
|
|
||||||
|
|
||||||
|
def func_no_args():
|
||||||
|
@@ -27,7 +27,7 @@
|
||||||
|
async def coroutine(arg, exec=False):
|
||||||
|
"Single-line docstring. Multiline is harder to reformat."
|
||||||
|
async with some_connection() as conn:
|
||||||
|
- await conn.do_what_i_mean("SELECT bobby, tables FROM xkcd", timeout=2)
|
||||||
|
+ await conn.do_what_i_mean('SELECT bobby, tables FROM xkcd', timeout=2)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@
|
||||||
|
return text[number:-1]
|
||||||
|
|
||||||
|
|
||||||
|
-def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""):
|
||||||
|
+def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r''):
|
||||||
|
offset = attr.ib(default=attr.Factory(lambda: _r.uniform(10000, 200000)))
|
||||||
|
assert task._cancel_stack[: len(old_stack)] == old_stack
|
||||||
|
|
||||||
|
@@ -58,25 +58,20 @@
|
||||||
|
f: int = -1,
|
||||||
|
g: int = 1 if False else 2,
|
||||||
|
h: str = "",
|
||||||
|
- i: str = r"",
|
||||||
|
+ i: str = r'',
|
||||||
|
):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def spaces2(result=_core.Value(None)):
|
||||||
|
- assert fut is self._read_fut, (fut, self._read_fut)
|
||||||
|
+ assert fut is self._read_fut, fut, self._read_fut
|
||||||
|
|
||||||
|
|
||||||
|
def example(session):
|
||||||
|
- result = (
|
||||||
|
- session.query(models.Customer.id)
|
||||||
|
- .filter(
|
||||||
|
- models.Customer.account_id == account_id,
|
||||||
|
- models.Customer.email == email_address,
|
||||||
|
- )
|
||||||
|
- .order_by(models.Customer.id.asc())
|
||||||
|
- .all()
|
||||||
|
- )
|
||||||
|
+ result = session.query(models.Customer.id).filter(
|
||||||
|
+ models.Customer.account_id == account_id,
|
||||||
|
+ models.Customer.email == email_address,
|
||||||
|
+ ).order_by(models.Customer.id.asc()).all()
|
||||||
|
|
||||||
|
|
||||||
|
def long_lines():
|
||||||
|
@@ -135,14 +130,13 @@
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
- return (
|
||||||
|
+ return
|
||||||
|
yield from A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=very_long_value_for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
- )
|
||||||
|
|
||||||
|
|
||||||
|
def __await__():
|
||||||
|
- return (yield)
|
||||||
|
\ No newline at end of file
|
||||||
|
+ return yield
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from third_party import X, Y, Z
|
||||||
|
|
||||||
|
from library import some_connection, some_decorator
|
||||||
|
|
||||||
|
f'trigger 3.6 mode'
|
||||||
|
|
||||||
|
|
||||||
|
def func_no_args():
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
if True:
|
||||||
|
raise RuntimeError
|
||||||
|
if False:
|
||||||
|
...
|
||||||
|
for i in range(10):
|
||||||
|
print(i)
|
||||||
|
continue
|
||||||
|
exec("new-style exec", {}, {})
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def coroutine(arg, exec=False):
|
||||||
|
"Single-line docstring. Multiline is harder to reformat."
|
||||||
|
async with some_connection() as conn:
|
||||||
|
await conn.do_what_i_mean('SELECT bobby, tables FROM xkcd', timeout=2)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
@some_decorator(with_args=True, many_args=[1, 2, 3])
|
||||||
|
def function_signature_stress_test(
|
||||||
|
number: int,
|
||||||
|
no_annotation=None,
|
||||||
|
text: str = "default",
|
||||||
|
*,
|
||||||
|
debug: bool = False,
|
||||||
|
**kwargs,
|
||||||
|
) -> str:
|
||||||
|
return text[number:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r''):
|
||||||
|
offset = attr.ib(default=attr.Factory(lambda: _r.uniform(10000, 200000)))
|
||||||
|
assert task._cancel_stack[: len(old_stack)] == old_stack
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def example(session):
|
||||||
|
result = session.query(models.Customer.id).filter(
|
||||||
|
models.Customer.account_id == account_id,
|
||||||
|
models.Customer.email == email_address,
|
||||||
|
).order_by(models.Customer.id.asc()).all()
|
||||||
|
|
||||||
|
|
||||||
|
def long_lines():
|
||||||
|
if True:
|
||||||
|
typedargslist.extend(
|
||||||
|
gen_annotated_params(
|
||||||
|
ast_args.kwonlyargs,
|
||||||
|
ast_args.kw_defaults,
|
||||||
|
parameters,
|
||||||
|
implicit_default=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
typedargslist.extend(
|
||||||
|
gen_annotated_params(
|
||||||
|
ast_args.kwonlyargs,
|
||||||
|
ast_args.kw_defaults,
|
||||||
|
parameters,
|
||||||
|
implicit_default=True,
|
||||||
|
# trailing standalone comment
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_type_comment_re = re.compile(
|
||||||
|
r"""
|
||||||
|
^
|
||||||
|
[\t ]*
|
||||||
|
\#[ ]type:[ ]*
|
||||||
|
(?P<type>
|
||||||
|
[^#\t\n]+?
|
||||||
|
)
|
||||||
|
(?<!ignore) # note: this will force the non-greedy + in <type> to match
|
||||||
|
# a trailing space which is why we need the silliness below
|
||||||
|
(?<!ignore[ ]{1})(?<!ignore[ ]{2})(?<!ignore[ ]{3})(?<!ignore[ ]{4})
|
||||||
|
(?<!ignore[ ]{5})(?<!ignore[ ]{6})(?<!ignore[ ]{7})(?<!ignore[ ]{8})
|
||||||
|
(?<!ignore[ ]{9})(?<!ignore[ ]{10})
|
||||||
|
[\t ]*
|
||||||
|
(?P<nl>
|
||||||
|
(?:\#[^\n]*)?
|
||||||
|
\n?
|
||||||
|
)
|
||||||
|
$
|
||||||
|
""",
|
||||||
|
re.MULTILINE | re.VERBOSE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def trailing_comma():
|
||||||
|
mapping = {
|
||||||
|
A: 0.25 * (10.0 / 12),
|
||||||
|
B: 0.1 * (10.0 / 12),
|
||||||
|
C: 0.1 * (10.0 / 12),
|
||||||
|
D: 0.1 * (10.0 / 12),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
return
|
||||||
|
yield from A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=very_long_value_for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def __await__():
|
||||||
|
return yield
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from third_party import X, Y, Z
|
||||||
|
|
||||||
|
from library import some_connection, some_decorator
|
||||||
|
|
||||||
|
f"trigger 3.6 mode"
|
||||||
|
|
||||||
|
|
||||||
|
def func_no_args():
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
if True:
|
||||||
|
raise RuntimeError
|
||||||
|
if False:
|
||||||
|
...
|
||||||
|
for i in range(10):
|
||||||
|
print(i)
|
||||||
|
continue
|
||||||
|
exec("new-style exec", {}, {})
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def coroutine(arg, exec=False):
|
||||||
|
"Single-line docstring. Multiline is harder to reformat."
|
||||||
|
async with some_connection() as conn:
|
||||||
|
await conn.do_what_i_mean("SELECT bobby, tables FROM xkcd", timeout=2)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
@some_decorator(with_args=True, many_args=[1, 2, 3])
|
||||||
|
def function_signature_stress_test(
|
||||||
|
number: int,
|
||||||
|
no_annotation=None,
|
||||||
|
text: str = "default",
|
||||||
|
*,
|
||||||
|
debug: bool = False,
|
||||||
|
**kwargs,
|
||||||
|
) -> str:
|
||||||
|
return text[number:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""):
|
||||||
|
offset = attr.ib(default=attr.Factory(lambda: _r.uniform(10000, 200000)))
|
||||||
|
assert task._cancel_stack[: len(old_stack)] == old_stack
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def example(session):
|
||||||
|
result = (
|
||||||
|
session.query(models.Customer.id)
|
||||||
|
.filter(
|
||||||
|
models.Customer.account_id == account_id,
|
||||||
|
models.Customer.email == email_address,
|
||||||
|
)
|
||||||
|
.order_by(models.Customer.id.asc())
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def long_lines():
|
||||||
|
if True:
|
||||||
|
typedargslist.extend(
|
||||||
|
gen_annotated_params(
|
||||||
|
ast_args.kwonlyargs,
|
||||||
|
ast_args.kw_defaults,
|
||||||
|
parameters,
|
||||||
|
implicit_default=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
typedargslist.extend(
|
||||||
|
gen_annotated_params(
|
||||||
|
ast_args.kwonlyargs,
|
||||||
|
ast_args.kw_defaults,
|
||||||
|
parameters,
|
||||||
|
implicit_default=True,
|
||||||
|
# trailing standalone comment
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_type_comment_re = re.compile(
|
||||||
|
r"""
|
||||||
|
^
|
||||||
|
[\t ]*
|
||||||
|
\#[ ]type:[ ]*
|
||||||
|
(?P<type>
|
||||||
|
[^#\t\n]+?
|
||||||
|
)
|
||||||
|
(?<!ignore) # note: this will force the non-greedy + in <type> to match
|
||||||
|
# a trailing space which is why we need the silliness below
|
||||||
|
(?<!ignore[ ]{1})(?<!ignore[ ]{2})(?<!ignore[ ]{3})(?<!ignore[ ]{4})
|
||||||
|
(?<!ignore[ ]{5})(?<!ignore[ ]{6})(?<!ignore[ ]{7})(?<!ignore[ ]{8})
|
||||||
|
(?<!ignore[ ]{9})(?<!ignore[ ]{10})
|
||||||
|
[\t ]*
|
||||||
|
(?P<nl>
|
||||||
|
(?:\#[^\n]*)?
|
||||||
|
\n?
|
||||||
|
)
|
||||||
|
$
|
||||||
|
""",
|
||||||
|
re.MULTILINE | re.VERBOSE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def trailing_comma():
|
||||||
|
mapping = {
|
||||||
|
A: 0.25 * (10.0 / 12),
|
||||||
|
B: 0.1 * (10.0 / 12),
|
||||||
|
C: 0.1 * (10.0 / 12),
|
||||||
|
D: 0.1 * (10.0 / 12),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
**kwargs,
|
||||||
|
) -> A:
|
||||||
|
return (
|
||||||
|
yield from A(
|
||||||
|
very_long_argument_name1=very_long_value_for_the_argument,
|
||||||
|
very_long_argument_name2=very_long_value_for_the_argument,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def __await__():
|
||||||
|
return (yield)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,419 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_formatter/src/lib.rs
|
||||||
|
expression: snapshot
|
||||||
|
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function_trailing_comma.py
|
||||||
|
---
|
||||||
|
## Input
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f(a,):
|
||||||
|
d = {'key': 'value',}
|
||||||
|
tup = (1,)
|
||||||
|
|
||||||
|
def f2(a,b,):
|
||||||
|
d = {'key': 'value', 'key2': 'value2',}
|
||||||
|
tup = (1,2,)
|
||||||
|
|
||||||
|
def f(a:int=1,):
|
||||||
|
call(arg={'explode': 'this',})
|
||||||
|
call2(arg=[1,2,3],)
|
||||||
|
x = {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
}["a"]
|
||||||
|
if a == {"a": 1,"b": 2,"c": 3,"d": 4,"e": 5,"f": 6,"g": 7,"h": 8,}["a"]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
|
||||||
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
]:
|
||||||
|
json = {"k": {"k2": {"k3": [1,]}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The type annotation shouldn't get a trailing comma since that would change its type.
|
||||||
|
# Relevant bug report: https://github.com/psf/black/issues/2381.
|
||||||
|
def some_function_with_a_really_long_name() -> (
|
||||||
|
returning_a_deeply_nested_import_of_a_type_i_suppose
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def some_method_with_a_really_long_name(very_long_parameter_so_yeah: str, another_long_parameter: int) -> (
|
||||||
|
another_case_of_returning_a_deeply_nested_import_of_a_type_i_suppose_cause_why_not
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func() -> (
|
||||||
|
also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(this_shouldn_t_get_a_trailing_comma_too)
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func() -> ((also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
))
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure inner one-element tuple won't explode
|
||||||
|
some_module.some_function(
|
||||||
|
argument1, (one_element_tuple,), argument4, argument5, argument6
|
||||||
|
)
|
||||||
|
|
||||||
|
# Inner trailing comma causes outer to explode
|
||||||
|
some_module.some_function(
|
||||||
|
argument1, (one, two,), argument4, argument5, argument6
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Differences
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- Black
|
||||||
|
+++ Ruff
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
a,
|
||||||
|
):
|
||||||
|
d = {
|
||||||
|
- "key": "value",
|
||||||
|
+ 'key': 'value',
|
||||||
|
}
|
||||||
|
tup = (1,)
|
||||||
|
|
||||||
|
@@ -12,8 +12,8 @@
|
||||||
|
b,
|
||||||
|
):
|
||||||
|
d = {
|
||||||
|
- "key": "value",
|
||||||
|
- "key2": "value2",
|
||||||
|
+ 'key': 'value',
|
||||||
|
+ 'key2': 'value2',
|
||||||
|
}
|
||||||
|
tup = (
|
||||||
|
1,
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
):
|
||||||
|
call(
|
||||||
|
arg={
|
||||||
|
- "explode": "this",
|
||||||
|
+ 'explode': 'this',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
call2(
|
||||||
|
@@ -52,53 +52,52 @@
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
|
||||||
|
- Set["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"]
|
||||||
|
-):
|
||||||
|
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
|
||||||
|
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
+]:
|
||||||
|
json = {
|
||||||
|
"k": {
|
||||||
|
"k2": {
|
||||||
|
"k3": [
|
||||||
|
1,
|
||||||
|
- ]
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ ],
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# The type annotation shouldn't get a trailing comma since that would change its type.
|
||||||
|
# Relevant bug report: https://github.com/psf/black/issues/2381.
|
||||||
|
-def some_function_with_a_really_long_name() -> (
|
||||||
|
- returning_a_deeply_nested_import_of_a_type_i_suppose
|
||||||
|
-):
|
||||||
|
+def some_function_with_a_really_long_name() -> returning_a_deeply_nested_import_of_a_type_i_suppose:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def some_method_with_a_really_long_name(
|
||||||
|
- very_long_parameter_so_yeah: str, another_long_parameter: int
|
||||||
|
+ very_long_parameter_so_yeah: str,
|
||||||
|
+ another_long_parameter: int,
|
||||||
|
) -> another_case_of_returning_a_deeply_nested_import_of_a_type_i_suppose_cause_why_not:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
-def func() -> (
|
||||||
|
- also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
- this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
- )
|
||||||
|
+def func() -> also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
+ this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
-def func() -> (
|
||||||
|
- also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
- this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
- )
|
||||||
|
+def func() -> also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
+ this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure inner one-element tuple won't explode
|
||||||
|
some_module.some_function(
|
||||||
|
- argument1, (one_element_tuple,), argument4, argument5, argument6
|
||||||
|
+ argument1,
|
||||||
|
+ (one_element_tuple,),
|
||||||
|
+ argument4,
|
||||||
|
+ argument5,
|
||||||
|
+ argument6,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Inner trailing comma causes outer to explode
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruff Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
):
|
||||||
|
d = {
|
||||||
|
'key': 'value',
|
||||||
|
}
|
||||||
|
tup = (1,)
|
||||||
|
|
||||||
|
|
||||||
|
def f2(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
):
|
||||||
|
d = {
|
||||||
|
'key': 'value',
|
||||||
|
'key2': 'value2',
|
||||||
|
}
|
||||||
|
tup = (
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a: int = 1,
|
||||||
|
):
|
||||||
|
call(
|
||||||
|
arg={
|
||||||
|
'explode': 'this',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
call2(
|
||||||
|
arg=[1, 2, 3],
|
||||||
|
)
|
||||||
|
x = {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
}["a"]
|
||||||
|
if (
|
||||||
|
a
|
||||||
|
== {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
"c": 3,
|
||||||
|
"d": 4,
|
||||||
|
"e": 5,
|
||||||
|
"f": 6,
|
||||||
|
"g": 7,
|
||||||
|
"h": 8,
|
||||||
|
}["a"]
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
|
||||||
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
]:
|
||||||
|
json = {
|
||||||
|
"k": {
|
||||||
|
"k2": {
|
||||||
|
"k3": [
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# The type annotation shouldn't get a trailing comma since that would change its type.
|
||||||
|
# Relevant bug report: https://github.com/psf/black/issues/2381.
|
||||||
|
def some_function_with_a_really_long_name() -> returning_a_deeply_nested_import_of_a_type_i_suppose:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def some_method_with_a_really_long_name(
|
||||||
|
very_long_parameter_so_yeah: str,
|
||||||
|
another_long_parameter: int,
|
||||||
|
) -> another_case_of_returning_a_deeply_nested_import_of_a_type_i_suppose_cause_why_not:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func() -> also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func() -> also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure inner one-element tuple won't explode
|
||||||
|
some_module.some_function(
|
||||||
|
argument1,
|
||||||
|
(one_element_tuple,),
|
||||||
|
argument4,
|
||||||
|
argument5,
|
||||||
|
argument6,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Inner trailing comma causes outer to explode
|
||||||
|
some_module.some_function(
|
||||||
|
argument1,
|
||||||
|
(
|
||||||
|
one,
|
||||||
|
two,
|
||||||
|
),
|
||||||
|
argument4,
|
||||||
|
argument5,
|
||||||
|
argument6,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Black Output
|
||||||
|
|
||||||
|
```py
|
||||||
|
def f(
|
||||||
|
a,
|
||||||
|
):
|
||||||
|
d = {
|
||||||
|
"key": "value",
|
||||||
|
}
|
||||||
|
tup = (1,)
|
||||||
|
|
||||||
|
|
||||||
|
def f2(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
):
|
||||||
|
d = {
|
||||||
|
"key": "value",
|
||||||
|
"key2": "value2",
|
||||||
|
}
|
||||||
|
tup = (
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def f(
|
||||||
|
a: int = 1,
|
||||||
|
):
|
||||||
|
call(
|
||||||
|
arg={
|
||||||
|
"explode": "this",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
call2(
|
||||||
|
arg=[1, 2, 3],
|
||||||
|
)
|
||||||
|
x = {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
}["a"]
|
||||||
|
if (
|
||||||
|
a
|
||||||
|
== {
|
||||||
|
"a": 1,
|
||||||
|
"b": 2,
|
||||||
|
"c": 3,
|
||||||
|
"d": 4,
|
||||||
|
"e": 5,
|
||||||
|
"f": 6,
|
||||||
|
"g": 7,
|
||||||
|
"h": 8,
|
||||||
|
}["a"]
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
|
||||||
|
Set["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"]
|
||||||
|
):
|
||||||
|
json = {
|
||||||
|
"k": {
|
||||||
|
"k2": {
|
||||||
|
"k3": [
|
||||||
|
1,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# The type annotation shouldn't get a trailing comma since that would change its type.
|
||||||
|
# Relevant bug report: https://github.com/psf/black/issues/2381.
|
||||||
|
def some_function_with_a_really_long_name() -> (
|
||||||
|
returning_a_deeply_nested_import_of_a_type_i_suppose
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def some_method_with_a_really_long_name(
|
||||||
|
very_long_parameter_so_yeah: str, another_long_parameter: int
|
||||||
|
) -> another_case_of_returning_a_deeply_nested_import_of_a_type_i_suppose_cause_why_not:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func() -> (
|
||||||
|
also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
)
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func() -> (
|
||||||
|
also_super_long_type_annotation_that_may_cause_an_AST_related_crash_in_black(
|
||||||
|
this_shouldn_t_get_a_trailing_comma_too
|
||||||
|
)
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure inner one-element tuple won't explode
|
||||||
|
some_module.some_function(
|
||||||
|
argument1, (one_element_tuple,), argument4, argument5, argument6
|
||||||
|
)
|
||||||
|
|
||||||
|
# Inner trailing comma causes outer to explode
|
||||||
|
some_module.some_function(
|
||||||
|
argument1,
|
||||||
|
(
|
||||||
|
one,
|
||||||
|
two,
|
||||||
|
),
|
||||||
|
argument4,
|
||||||
|
argument5,
|
||||||
|
argument6,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue