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:
Micha Reiser 2023-02-22 15:25:06 +01:00 committed by GitHub
parent 262e768fd3
commit ed33b75bad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
119 changed files with 12989 additions and 981 deletions

View file

@ -20,8 +20,6 @@ mod format;
mod newlines;
mod parentheses;
pub mod shared_traits;
#[cfg(test)]
mod test;
pub mod trivia;
pub fn fmt(contents: &str) -> Result<Formatted<ASTFormatContext>> {
@ -57,70 +55,98 @@ pub fn fmt(contents: &str) -> Result<Formatted<ASTFormatContext>> {
#[cfg(test)]
mod tests {
use std::fs;
use std::path::Path;
use anyhow::Result;
use test_case::test_case;
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)?;
insta::assert_display_snapshot!(snapshot, formatted.print()?.as_code());
Ok(())
}
#[test_case(Path::new("simple_cases/collections.py"); "collections")]
#[test_case(Path::new("simple_cases/bracketmatch.py"); "bracketmatch")]
fn passing_modulo_string_normalization(path: &Path) -> Result<()> {
fn adjust_quotes(contents: &str) -> String {
// Replace all single quotes with double quotes.
contents.replace('\'', "\"")
let expected_path = input_path.with_extension("py.expect");
let expected_output = fs::read_to_string(&expected_path)
.unwrap_or_else(|_| panic!("Expected Black output file '{expected_path:?}' to exist"));
let printed = formatted.print()?;
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(())
}
@ -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)
}
}
}

View file

@ -1,28 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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)

View file

@ -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

View file

@ -1,102 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
#!/usr/bin/env python3
# fmt: on
# Some license here.
#
# Has many lines. Many, many lines.
# Many, many, many lines.
"""Module docstring.
Possibly also many, many lines.
"""
import os.path
import sys
import a
from b.c import X # some noqa comment
try:
import fast
except ImportError:
import slow as fast
# Some comment before a function.
y = 1
(
# some strings
y # type: ignore
)
def function(default=None):
"""Docstring comes first.
Possibly many lines.
"""
# FIXME: Some comment about why this function is crap but still in production.
import inner_imports
if inner_imports.are_evil():
# Explains why we have this if.
# In great detail indeed.
x = X()
return x.method1() # type: ignore
# This return is also commented for some reason.
return default
# Explains why we use global state.
GLOBAL_STATE = {"a": a(1), "b": a(2), "c": a(3)}
# Another comment!
# This time two lines.
class Foo:
"""Docstring for class Foo. Example from Sphinx docs."""
#: Doc comment for class attribute Foo.bar.
#: It can have multiple lines.
bar = 1
flox = 1.5 #: Doc comment for Foo.flox. One line only.
baz = 2
"""Docstring for class attribute Foo.baz."""
def __init__(self):
#: Doc comment for instance attribute qux.
self.qux = 3
self.spam = 4
"""Docstring for instance attribute spam."""
#' <h1>This is pweave!</h1>
@fast(really=True)
async def wat():
# This comment, for some reason \
# contains a trailing backslash.
async with X.open_async() as x: # Some more comments
result = await x.method1()
# Comment after ending a block.
if result:
print("A OK", file=sys.stdout)
# Comment between things.
print()
# Some closing comments.
# Maybe Vim or Emacs directives for formatting.
# Who knows.

View file

@ -1,179 +0,0 @@
---
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 (
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

View file

@ -1,54 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# The percent-percent comments are Spyder IDE cells.
# %%
def func():
x = """
a really long string
"""
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
]
# Capture each of the exceptions in the MultiError along with each of their causes and contexts
if isinstance(exc_value, MultiError):
embedded = []
for exc in exc_value.exceptions:
if exc not in _seen:
embedded.append(
# This should be left alone (before)
traceback.TracebackException.from_exception(
exc,
limit=limit,
lookup_lines=lookup_lines,
capture_locals=capture_locals,
# copy the set of _seen exceptions so that duplicates
# shared between sub-exceptions are not omitted
_seen=set(_seen),
)
# This should be left alone (after)
)
# everything is fine if the expression isn't nested
traceback.TracebackException.from_exception(
exc,
limit=limit,
lookup_lines=lookup_lines,
capture_locals=capture_locals,
# copy the set of _seen exceptions so that duplicates
# shared between sub-exceptions are not omitted
_seen=set(_seen),
)
# %%

View file

@ -1,100 +0,0 @@
---
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 (
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))
)

View file

@ -1,79 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
while True:
if something.changed:
do.stuff() # trailing comment
# Comment belongs to the `if` block.
# This one belongs to the `while` block.
# Should this one, too? I guess so.
# This one is properly standalone now.
for i in range(100):
# first we do this
if i % 33 == 0:
break
# then we do this
print(i)
# and finally we loop around
with open(some_temp_file) as f:
data = f.read()
try:
with open(some_other_file) as w:
w.write(data)
except OSError:
print("problems")
import sys
# leading function comment
def wat():
...
# trailing function comment
# SECTION COMMENT
# leading 1
@deco1
# leading 2
@deco2(with_args=True)
# leading 3
@deco3
def decorated1():
...
# leading 1
@deco1
# leading 2
@deco2(with_args=True)
# leading function comment
def decorated1():
...
# Note: this is fixed in
# Preview.empty_lines_before_class_or_def_with_leading_comments.
# In the current style, the user will have to split those lines by hand.
some_instruction
# This comment should be split from `some_instruction` by two lines but isn't.
def g():
...
if __name__ == "__main__":
main()

View file

@ -1,124 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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]

View file

@ -1,12 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# The percent-percent comments are Spyder IDE cells.
# Both `#%%`` and `# %%` are accepted, so `black` standardises
# to the latter.
# %%
# %%

View file

@ -1,167 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# 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

View file

@ -1,29 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
from .config import (
ConfigTypeAttributes,
Int,
Path, # String,
# DEFAULT_TYPE_ATTRIBUTES,
)
result = 1 # A simple comment
result = (1,) # Another one
result = 1 #  type: ignore
result = 1 # This comment is talking about type: ignore
square = Square(4) #  type: Optional[Square]
def function(a: int = 42):
"""This docstring is already formatted
a
b
"""
# There's a NBSP + 3 spaces before
# And 4 spaces on the next line
pass

View file

@ -1,187 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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,
}
)

View file

@ -1,187 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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,
}
)

View file

@ -1,225 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
class MyClass:
"""Multiline
class docstring
"""
def method(self):
"""Multiline
method docstring
"""
pass
def foo():
"""This is a docstring with
some lines of text here
"""
return
def bar():
"""This is another docstring
with more lines of text
"""
return
def baz():
'''"This" is a string with some
embedded "quotes"'''
return
def troz():
"""Indentation with tabs
is just as OK
"""
return
def zort():
"""Another
multiline
docstring
"""
pass
def poit():
"""
Lorem ipsum dolor sit amet.
Consectetur adipiscing elit:
- sed do eiusmod tempor incididunt ut labore
- dolore magna aliqua
- enim ad minim veniam
- quis nostrud exercitation ullamco laboris nisi
- aliquip ex ea commodo consequat
"""
pass
def under_indent():
"""
These lines are indented in a way that does not
make sense.
"""
pass
def over_indent():
"""
This has a shallow indent
- But some lines are deeper
- And the closing quote is too deep
"""
pass
def single_line():
"""But with a newline after it!"""
pass
def this():
r"""
'hey ho'
"""
def that():
""" "hey yah" """
def and_that():
"""
"hey yah" """
def and_this():
'''
"hey yah"'''
def multiline_whitespace():
""" """
def oneline_whitespace():
""" """
def empty():
""""""
def single_quotes():
"testing"
def believe_it_or_not_this_is_in_the_py_stdlib():
'''
"hey yah"'''
def ignored_docstring():
"""a => \
b"""
def single_line_docstring_with_whitespace():
"""This should be stripped"""
def docstring_with_inline_tabs_and_space_indentation():
"""hey
tab separated value
tab at start of line and then a tab separated value
multiple tabs at the beginning and inline
mixed tabs and spaces at beginning. next line has mixed tabs and spaces only.
line ends with some tabs
"""
def docstring_with_inline_tabs_and_tab_indentation():
"""hey
tab separated value
tab at start of line and then a tab separated value
multiple tabs at the beginning and inline
mixed tabs and spaces at beginning. next line has mixed tabs and spaces only.
line ends with some tabs
"""
pass
def backslash_space():
"""\ """
def multiline_backslash_1():
"""
hey\there\
\ """
def multiline_backslash_2():
"""
hey there \ """
# Regression test for #3425
def multiline_backslash_really_long_dont_crash():
"""
hey there hello guten tag hi hoow are you ola zdravstvuyte ciao como estas ca va \ """
def multiline_backslash_3():
"""
already escaped \\"""
def my_god_its_full_of_stars_1():
"I'm sorry Dave\u2001"
# the space below is actually a \u2001, removed in output
def my_god_its_full_of_stars_2():
"I'm sorry Dave"
def docstring_almost_at_line_limit():
"""long docstring................................................................."""
def docstring_almost_at_line_limit2():
"""long docstring.................................................................
..................................................................................
"""
def docstring_at_line_limit():
"""long docstring................................................................"""
def multiline_docstring_at_line_limit():
"""first line-----------------------------------------------------------------------
second line----------------------------------------------------------------------"""
def stable_quote_normalization_with_immediate_inner_single_quote(self):
"""'<text here>
<text here, since without another non-empty line black is stable>
"""

View file

@ -1,10 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# Make sure when the file ends with class's docstring,
# It doesn't add extra blank lines.
class ClassWithDocstring:
"""A docstring."""

View file

@ -1,54 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
def docstring_almost_at_line_limit():
"""long docstring................................................................."""
def docstring_almost_at_line_limit_with_prefix():
f"""long docstring................................................................"""
def mulitline_docstring_almost_at_line_limit():
"""long docstring.................................................................
..................................................................................
"""
def mulitline_docstring_almost_at_line_limit_with_prefix():
f"""long docstring................................................................
..................................................................................
"""
def docstring_at_line_limit():
"""long docstring................................................................"""
def docstring_at_line_limit_with_prefix():
f"""long docstring..............................................................."""
def multiline_docstring_at_line_limit():
"""first line-----------------------------------------------------------------------
second line----------------------------------------------------------------------"""
def multiline_docstring_at_line_limit_with_prefix():
f"""first line----------------------------------------------------------------------
second line----------------------------------------------------------------------"""
def single_quote_docstring_over_line_limit():
"We do not want to put the closing quote on a new line as that is invalid (see GH-3141)."
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)."

View file

@ -1,95 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
"""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

View file

@ -1,377 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
...
"some_string"
b"\\xa3"
Name
None
True
False
1
1.0
1j
True or False
True or False or None
True and False
True and False and None
(Name1 and Name2) or Name3
Name1 and Name2 or Name3
Name1 or (Name2 and Name3)
Name1 or Name2 and Name3
(Name1 and Name2) or (Name3 and Name4)
Name1 and Name2 or Name3 and Name4
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)
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
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
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]
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}}
{**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
()
(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,
]
[*a]
[*range(10)]
[
*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 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: 0 for i in (1, 2, 3)}
{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
}
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(*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
....__class__
list[str]
dict[str, int]
tuple[str, ...]
tuple[str, int, float, dict[str, int]]
tuple[
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
slice[0]
slice[0:1]
slice[0:1:2]
slice[:]
slice[:-1]
slice[1:]
slice[::-1]
slice[d :: d + 1]
slice[:c, c - 1]
numpy[:, 0:1]
numpy[:, :-1]
numpy[0, :]
numpy[:, i]
numpy[0, :2]
numpy[:N, 0]
numpy[:2, :4]
numpy[2:4, 1:5]
numpy[4:, 2:]
numpy[:, (0, 1, 2, 5)]
numpy[0, [0]]
numpy[:, [i]]
numpy[1 : c + 1, c]
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"}
[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))
(*starred,)
{
"id": "1",
"type": "type",
"started_at": now(),
"ended_at": now() + timedelta(days=10),
"priority": 1,
"import_session_id": 1,
**kwargs,
}
a = (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()
)
Ø = 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
async def f():
await some.complicated[0].call(with_args=(True or (1 is not 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"):
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)
)
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
<< aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
bbbb >> bbbb * bbbb
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
last_call()
# standalone comment at ENDMARKER

View file

@ -1,230 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
#!/usr/bin/env python3
import asyncio
import sys
from third_party import X, Y, Z
from library import some_connection, some_decorator
# fmt: off
from third_party import (X,
Y, Z)
# fmt: on
f"trigger 3.6 mode"
# Comment 1
# Comment 2
# fmt: off
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]
# fmt: on
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(1, 2)))
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)):
...
something = {
# fmt: off
key: 'value',
}
def subscriptlist():
atom[
# fmt: off
'some big and',
'complex subscript',
# fmt: on
goes + here,
andhere,
]
def import_as_names():
# fmt: off
from hello import a, b
'unformatted'
# fmt: on
def testlist_star_expr():
# fmt: off
a , b = *hello
'unformatted'
# fmt: on
def yield_expr():
# fmt: off
yield hello
'unformatted'
# fmt: on
"formatted"
# fmt: off
( yield hello )
'unformatted'
# fmt: on
def example(session):
# fmt: off
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()
# fmt: on
def off_and_on_without_data():
"""All comments here are technically on the same prefix.
The comments between will be formatted. This is a known limitation.
"""
# fmt: off
# hey, that won't work
# fmt: on
pass
def on_and_off_broken():
"""Another known limitation."""
# fmt: on
# fmt: off
this=should.not_be.formatted()
and_=indeed . it is not formatted
because . the . handling . inside . generate_ignored_nodes()
now . considers . multiple . fmt . directives . within . one . prefix
# fmt: on
# fmt: off
# ...but comments still get reformatted even though they should not be
# fmt: on
def long_lines():
if True:
typedargslist.extend(
gen_annotated_params(
ast_args.kwonlyargs,
ast_args.kw_defaults,
parameters,
implicit_default=True,
)
)
# fmt: off
a = (
unnecessary_bracket()
)
# fmt: on
_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?
)
$
""",
# fmt: off
re.MULTILINE|re.VERBOSE
# fmt: on
)
def single_literal_yapf_disable():
"""Black does not support this."""
BAZ = {(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)} # yapf: disable
cfg.rule(
"Default",
"address",
xxxx_xxxx=["xxx-xxxxxx-xxxxxxxxxx"],
xxxxxx="xx_xxxxx",
xxxxxxx="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
xxxxxxxxx_xxxx=True,
xxxxxxxx_xxxxxxxxxx=False,
xxxxxx_xxxxxx=2,
xxxxxx_xxxxx_xxxxxxxx=70,
xxxxxx_xxxxxx_xxxxx=True,
# fmt: off
xxxxxxx_xxxxxxxxxxxx={
"xxxxxxxx": {
"xxxxxx": False,
"xxxxxxx": False,
"xxxx_xxxxxx": "xxxxx",
},
"xxxxxxxx-xxxxx": {
"xxxxxx": False,
"xxxxxxx": True,
"xxxx_xxxxxx": "xxxxxx",
},
},
# fmt: on
xxxxxxxxxx_xxxxxxxxxxx_xxxxxxx_xxxxxxxxx=5,
)
# fmt: off
yield 'hello'
# No formatting to the end of the file
l=[1,2,3]
d={'a':1,
'b':2}

View file

@ -1,46 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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

View file

@ -1,21 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# fmt: off
x = [
1, 2,
3, 4,
]
# fmt: on
# fmt: off
x = [
1, 2,
3, 4,
]
# fmt: on
x = [1, 2, 3, 4]

View file

@ -1,26 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# fmt: off
@test([
1, 2,
3, 4,
])
# fmt: on
def f():
pass
@test(
[
1,
2,
3,
4,
]
)
def f():
pass

View file

@ -1,93 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# 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()

View file

@ -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

View file

@ -1,17 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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",
]

View file

@ -1,16 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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.",
]

View file

@ -1,13 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
a = 2
# fmt: skip
l = [
1,
2,
3,
]

View file

@ -1,15 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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")

View file

@ -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

View file

@ -1,10 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
a = "this is some code"
b = 5 # fmt:skip
c = 9 # fmt: skip
d = "thisisasuperlongstringthisisasuperlongstringthisisasuperlongstringthisisasuperlongstring" # fmt:skip

View file

@ -1,68 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# Make sure a leading comment is not removed.
def some_func( unformatted, args ): # fmt: skip
print("I am some_func")
return 0
# Make sure this comment is not removed.
# Make sure a leading comment is not removed.
async def some_async_func( unformatted, args): # fmt: skip
print("I am some_async_func")
await asyncio.sleep(1)
# Make sure a leading comment is not removed.
class SomeClass( Unformatted, SuperClasses ): # fmt: skip
def some_method( self, unformatted, args ): # fmt: skip
print("I am some_method")
return 0
async def some_async_method( self, unformatted, args ): # fmt: skip
print("I am some_async_method")
await asyncio.sleep(1)
# Make sure a leading comment is not removed.
if unformatted_call( args ): # fmt: skip
print("First branch")
# Make sure this is not removed.
elif another_unformatted_call( args ): # fmt: skip
print("Second branch")
else : # fmt: skip
print("Last branch")
while some_condition( unformatted, args ): # fmt: skip
print("Do something")
for i in some_iter( unformatted, args ): # fmt: skip
print("Do something")
async def test_async_for():
async for i in some_async_iter( unformatted, args ): # fmt: skip
print("Do something")
try : # fmt: skip
some_call()
except UnformattedError as ex: # fmt: skip
handle_exception()
finally : # fmt: skip
finally_call()
with give_me_context( unformatted, args ): # fmt: skip
print("Do something")
async def test_async_with():
async with give_me_async_context( unformatted, args ): # fmt: skip
print("Do something")

View file

@ -1,15 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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"}\''

View file

@ -1,154 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
#!/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)

View file

@ -1,120 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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,
)

View file

@ -1,27 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# 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
# magic trailing comma.
(
first_value,
(
m1,
m2,
),
third_value,
) = xxxxxx_yyyyyy_zzzzzz_wwwwww_uuuuuuu_vvvvvvvvvvv(
arg1,
arg2,
)
# Make when when the left side of assignment plus the opening paren "... = (" is
# exactly line length limit + 1, it won't be split like that.
xxxxxxxxx_yyy_zzzzzzzz[
xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1)
] = 1

View file

@ -1,99 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
import asyncio
# Control example
async def main():
await asyncio.sleep(1)
# Remove brackets for short coroutine/task
async def main():
await asyncio.sleep(1)
async def main():
await asyncio.sleep(1)
async def main():
await asyncio.sleep(1)
# Check comments
async def main():
await asyncio.sleep(1) # Hello
async def main():
await asyncio.sleep(1) # Hello
async def main():
await asyncio.sleep(1) # Hello
# Long lines
async def main():
await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
)
# Same as above but with magic trailing comma in function
async def main():
await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
)
# Cr@zY Br@ck3Tz
async def main():
await black(1)
# Keep brackets around non power operations and nested awaits
async def main():
await (set_of_tasks | other_set)
async def main():
await (await asyncio.sleep(1))
# It's awaits all the way down...
async def main():
await (await x)
async def main():
await (yield x)
async def main():
await (await asyncio.sleep(1))
async def main():
await (await (await (await (await asyncio.sleep(1)))))
async def main():
await (yield)

View file

@ -1,48 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# These brackets are redundant, therefore remove.
try:
a.something
except AttributeError as err:
raise err
# This is tuple of exceptions.
# Although this could be replaced with just the exception,
# we do not remove brackets to preserve AST.
try:
a.something
except (AttributeError,) as err:
raise err
# This is a tuple of exceptions. Do not remove brackets.
try:
a.something
except (AttributeError, ValueError) as err:
raise err
# Test long variants.
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error
) as err:
raise err
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
raise err
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
raise err

View file

@ -1,33 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# Only remove tuple brackets after `for`
for k, v in d.items():
print(k, v)
# Don't touch tuple brackets after `in`
for module in (core, _unicodefun):
if hasattr(module, "_verify_python3_env"):
module._verify_python3_env = lambda: None
# Brackets remain for long for loop lines
for (
why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long,
i_dont_know_but_we_should_still_check_the_behaviour_if_they_do,
) in d.items():
print(k, v)
for (
k,
v,
) in (
dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items()
):
print(k, v)
# Test deeply nested brackets
for k, v in d.items():
print(k, v)

View file

@ -1,91 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
x = 1
x = 1.2
data = (
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
).encode()
async def show_status():
while True:
try:
if report_host:
data = (
f"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
).encode()
except Exception as e:
pass
def example():
return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def example1():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
def example1point5():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
def example2():
return (
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
def example3():
return (
1111111111111111111111111111111111111111111111111111111111111111111111111111111
)
def example4():
return True
def example5():
return ()
def example6():
return {a: a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]}
def example7():
return {
a: a
for a in [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20000000000000000000,
]
}
def example8():
return None

View file

@ -1,126 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# Control
def double(a: int) -> int:
return 2 * a
# Remove the brackets
def double(a: int) -> int:
return 2 * a
# Some newline variations
def double(a: int) -> int:
return 2 * a
def double(a: int) -> int:
return 2 * a
def double(a: int) -> int:
return 2 * a
# Don't lose the comments
def double(a: int) -> int: # Hello
return 2 * a
def double(a: int) -> int: # Hello
return 2 * a
# Really long annotations
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo(
a: int,
b: int,
c: int,
) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo(
a: int,
b: int,
c: int,
) -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
# Split args but no need to split return
def foo(
a: int,
b: int,
c: int,
) -> int:
return 2
# Deeply nested brackets
# with *interesting* spacing
def double(a: int) -> int:
return 2 * a
def double(a: int) -> int:
return 2 * a
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
# Return type with commas
def foo() -> tuple[int, int, int]:
return 2
def foo() -> (
tuple[
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
]
):
return 2
# Magic trailing comma example
def foo() -> (
tuple[
int,
int,
int,
]
):
return 2

View file

@ -1,31 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# We should not remove the trailing comma in a single-element subscript.
a: tuple[int,]
b = tuple[int,]
# But commas in multiple element subscripts should be removed.
c: tuple[int, int]
d = tuple[int, int]
# Remove commas for non-subscripts.
small_list = [1]
list_of_types = [tuple[int,]]
small_set = {1}
set_of_types = {tuple[int,]}
# Except single element tuples
small_tuple = (1,)
# Trailing commas in multiple chained non-nested parens.
zero(one).two(three).four(five)
func1(arg1).func2(arg2).func3(arg3).func4(arg4).func5(arg5)
(a, b, c, d) = func1(arg1) and func2(arg2)
func(argument1, (one, two), argument4, argument5, argument6)

View file

@ -1,26 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
#!/usr/bin/env python3
name = "Łukasz"
(f"hello {name}", f"hello {name}")
(b"", b"")
("", "")
(r"", R"")
(rf"", rf"", Rf"", Rf"", rf"", rf"", Rf"", Rf"")
(rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"")
def docstring_singleline():
R"""2020 was one hell of a year. The good news is that we were able to"""
def docstring_multiline():
R"""
clear out all of the issues opened in that time :p
"""

View file

@ -1,64 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
importA
(
()
<< 0
** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert sort_by_dependency(
{
"1": {"2", "3"},
"2": {"2a", "2b"},
"3": {"3a", "3b"},
"2a": set(),
"2b": set(),
"3a": set(),
"3b": set(),
}
) == ["2a", "2b", "2", "3a", "3b", "3", "1"]
importA
0
0 ^ 0 #
class A:
def foo(self):
for _ in range(10):
aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbb.cccccccccc(
xxxxxxxxxxxx
) # pylint: disable=no-member
def test(self, othr):
return 1 == 2 and (
name,
description,
self.default,
self.selected,
self.auto_generated,
self.parameters,
self.meta_data,
self.schedule,
) == (
name,
description,
othr.default,
othr.selected,
othr.auto_generated,
othr.parameters,
othr.meta_data,
othr.schedule,
)
assert a_function(
very_long_arguments_that_surpass_the_limit,
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"}

View file

@ -1,40 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
if e1234123412341234.winerror not in (
_winapi.ERROR_SEM_TIMEOUT,
_winapi.ERROR_PIPE_BUSY,
) or _check_timeout(t):
pass
if x:
if y:
new_id = (
max(
Vegetable.objects.order_by("-id")[0].id,
Mineral.objects.order_by("-id")[0].id,
)
+ 1
)
class X:
def get_help_text(self):
return ngettext(
"Your password must contain at least %(min_length)d character.",
"Your password must contain at least %(min_length)d characters.",
self.min_length,
) % {"min_length": self.min_length}
class A:
def b(self):
if self.connection.mysql_is_mariadb and (
10,
4,
3,
) < self.connection.mysql_version < (10, 5, 2):
pass

View file

@ -1,12 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
if e123456.get_tk_patchlevel() >= (8, 6, 0, "final") or (
8,
5,
8,
) <= get_tk_patchlevel() < (8, 6):
pass

View file

@ -1,14 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}

View file

@ -1,56 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
zero(
one,
).two(
three,
).four(
five,
)
func1(arg1).func2(
arg2,
).func3(arg3).func4(
arg4,
).func5(arg5)
# Inner one-element tuple shouldn't explode
func1(arg1).func2(arg1, (one_tuple,)).func3(arg3)
(
a,
b,
c,
d,
) = func1(
arg1
) and func2(arg2)
# Example from https://github.com/psf/black/issues/3229
def refresh_token(self, device_family, refresh_token, api_key):
return self.orchestration.refresh_token(
data={
"refreshToken": refresh_token,
},
api_key=api_key,
)["extensions"]["sdk"]["token"]
# Edge case where a bug in a working-in-progress version of
# https://github.com/psf/black/pull/3370 causes an infinite recursion.
assert (
long_module.long_class.long_func().another_func()
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)
# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)

View file

@ -1,7 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---

View file

@ -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)
```

View file

@ -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
```

View file

@ -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
```

View file

@ -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
```

View file

@ -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,
},
)
```

View file

@ -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
```

View file

@ -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
```

View file

@ -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))
)
```

View file

@ -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]
```

View file

@ -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
```

View file

@ -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,
}
)
```

View file

@ -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,
}
)
```

View file

@ -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."""
```

View file

@ -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
```

View file

@ -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
```

View file

@ -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]
```

View file

@ -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
```

View file

@ -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()
```

View file

@ -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",
]
```

View file

@ -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.",
]
```

View file

@ -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")
```

View file

@ -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
```

View file

@ -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
```

View file

@ -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
```

View file

@ -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"}\''
```

View file

@ -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
```

View file

@ -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)
```

View file

@ -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,
)
```

View file

@ -0,0 +1,407 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py
---
## Input
```py
import asyncio
# Control example
async def main():
await asyncio.sleep(1)
# Remove brackets for short coroutine/task
async def main():
await (asyncio.sleep(1))
async def main():
await (
asyncio.sleep(1)
)
async def main():
await (asyncio.sleep(1)
)
# Check comments
async def main():
await ( # Hello
asyncio.sleep(1)
)
async def main():
await (
asyncio.sleep(1) # Hello
)
async def main():
await (
asyncio.sleep(1)
) # Hello
# Long lines
async def main():
await asyncio.gather(asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1))
# Same as above but with magic trailing comma in function
async def main():
await asyncio.gather(asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1), asyncio.sleep(1),)
# Cr@zY Br@ck3Tz
async def main():
await (
(((((((((((((
((( (((
((( (((
((( (((
((( (((
((black(1)))
))) )))
))) )))
))) )))
))) )))
)))))))))))))
)
# Keep brackets around non power operations and nested awaits
async def main():
await (set_of_tasks | other_set)
async def main():
await (await asyncio.sleep(1))
# It's awaits all the way down...
async def main():
await (await x)
async def main():
await (yield x)
async def main():
await (await (asyncio.sleep(1)))
async def main():
await (await (await (await (await (asyncio.sleep(1))))))
async def main():
await (yield)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -8,59 +8,63 @@
# Remove brackets for short coroutine/task
async def main():
- await asyncio.sleep(1)
+ await (asyncio.sleep(1))
async def main():
- await asyncio.sleep(1)
+ await (asyncio.sleep(1))
async def main():
- await asyncio.sleep(1)
+ await (asyncio.sleep(1))
# Check comments
async def main():
- await asyncio.sleep(1) # Hello
+ await (asyncio.sleep(1))
async def main():
- await asyncio.sleep(1) # Hello
+ await (asyncio.sleep(1)) # Hello
-async def main():
- await asyncio.sleep(1) # Hello
+async def main(): # Hello
+ await (asyncio.sleep(1))
# Long lines
async def main():
- await asyncio.gather(
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
+ (
+ await asyncio.gather(
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ )
)
# Same as above but with magic trailing comma in function
async def main():
- await asyncio.gather(
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
- asyncio.sleep(1),
+ (
+ await asyncio.gather(
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ asyncio.sleep(1),
+ )
)
# Cr@zY Br@ck3Tz
async def main():
- await black(1)
+ await (black(1))
# Keep brackets around non power operations and nested awaits
@@ -82,12 +86,12 @@
async def main():
- await (await asyncio.sleep(1))
+ await (await (asyncio.sleep(1)))
async def main():
- await (await (await (await (await asyncio.sleep(1)))))
+ await (await (await (await (await (asyncio.sleep(1))))))
async def main():
- await (yield)
\ No newline at end of file
+ await (yield)
```
## Ruff Output
```py
import asyncio
# Control example
async def main():
await asyncio.sleep(1)
# Remove brackets for short coroutine/task
async def main():
await (asyncio.sleep(1))
async def main():
await (asyncio.sleep(1))
async def main():
await (asyncio.sleep(1))
# Check comments
async def main():
await (asyncio.sleep(1))
async def main():
await (asyncio.sleep(1)) # Hello
async def main(): # Hello
await (asyncio.sleep(1))
# Long lines
async def main():
(
await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
)
)
# Same as above but with magic trailing comma in function
async def main():
(
await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
)
)
# Cr@zY Br@ck3Tz
async def main():
await (black(1))
# Keep brackets around non power operations and nested awaits
async def main():
await (set_of_tasks | other_set)
async def main():
await (await asyncio.sleep(1))
# It's awaits all the way down...
async def main():
await (await x)
async def main():
await (yield x)
async def main():
await (await (asyncio.sleep(1)))
async def main():
await (await (await (await (await (asyncio.sleep(1))))))
async def main():
await (yield)
```
## Black Output
```py
import asyncio
# Control example
async def main():
await asyncio.sleep(1)
# Remove brackets for short coroutine/task
async def main():
await asyncio.sleep(1)
async def main():
await asyncio.sleep(1)
async def main():
await asyncio.sleep(1)
# Check comments
async def main():
await asyncio.sleep(1) # Hello
async def main():
await asyncio.sleep(1) # Hello
async def main():
await asyncio.sleep(1) # Hello
# Long lines
async def main():
await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
)
# Same as above but with magic trailing comma in function
async def main():
await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
asyncio.sleep(1),
)
# Cr@zY Br@ck3Tz
async def main():
await black(1)
# Keep brackets around non power operations and nested awaits
async def main():
await (set_of_tasks | other_set)
async def main():
await (await asyncio.sleep(1))
# It's awaits all the way down...
async def main():
await (await x)
async def main():
await (yield x)
async def main():
await (await asyncio.sleep(1))
async def main():
await (await (await (await (await asyncio.sleep(1)))))
async def main():
await (yield)
```

View file

@ -0,0 +1,175 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_except_parens.py
---
## Input
```py
# These brackets are redundant, therefore remove.
try:
a.something
except (AttributeError) as err:
raise err
# This is tuple of exceptions.
# Although this could be replaced with just the exception,
# we do not remove brackets to preserve AST.
try:
a.something
except (AttributeError,) as err:
raise err
# This is a tuple of exceptions. Do not remove brackets.
try:
a.something
except (AttributeError, ValueError) as err:
raise err
# Test long variants.
try:
a.something
except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error) as err:
raise err
try:
a.something
except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,) as err:
raise err
try:
a.something
except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error) as err:
raise err
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,7 +1,7 @@
# These brackets are redundant, therefore remove.
try:
a.something
-except AttributeError as err:
+except (AttributeError) as err:
raise err
# This is tuple of exceptions.
@@ -21,9 +21,7 @@
# Test long variants.
try:
a.something
-except (
- some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error
-) as err:
+except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error) as err:
raise err
try:
@@ -39,4 +37,4 @@
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
- raise err
\ No newline at end of file
+ raise err
```
## Ruff Output
```py
# These brackets are redundant, therefore remove.
try:
a.something
except (AttributeError) as err:
raise err
# This is tuple of exceptions.
# Although this could be replaced with just the exception,
# we do not remove brackets to preserve AST.
try:
a.something
except (AttributeError,) as err:
raise err
# This is a tuple of exceptions. Do not remove brackets.
try:
a.something
except (AttributeError, ValueError) as err:
raise err
# Test long variants.
try:
a.something
except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error) as err:
raise err
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
raise err
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
raise err
```
## Black Output
```py
# These brackets are redundant, therefore remove.
try:
a.something
except AttributeError as err:
raise err
# This is tuple of exceptions.
# Although this could be replaced with just the exception,
# we do not remove brackets to preserve AST.
try:
a.something
except (AttributeError,) as err:
raise err
# This is a tuple of exceptions. Do not remove brackets.
try:
a.something
except (AttributeError, ValueError) as err:
raise err
# Test long variants.
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error
) as err:
raise err
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
raise err
try:
a.something
except (
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error,
) as err:
raise err
```

View file

@ -0,0 +1,126 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_for_brackets.py
---
## Input
```py
# Only remove tuple brackets after `for`
for (k, v) in d.items():
print(k, v)
# Don't touch tuple brackets after `in`
for module in (core, _unicodefun):
if hasattr(module, "_verify_python3_env"):
module._verify_python3_env = lambda: None
# Brackets remain for long for loop lines
for (why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long, i_dont_know_but_we_should_still_check_the_behaviour_if_they_do) in d.items():
print(k, v)
for (k, v) in dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items():
print(k, v)
# Test deeply nested brackets
for (((((k, v))))) in d.items():
print(k, v)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -3,7 +3,7 @@
print(k, v)
# Don't touch tuple brackets after `in`
-for module in (core, _unicodefun):
+for module in core, _unicodefun:
if hasattr(module, "_verify_python3_env"):
module._verify_python3_env = lambda: None
@@ -17,11 +17,9 @@
for (
k,
v,
-) in (
- dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items()
-):
+) in dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items():
print(k, v)
# Test deeply nested brackets
for k, v in d.items():
- print(k, v)
\ No newline at end of file
+ print(k, v)
```
## Ruff Output
```py
# Only remove tuple brackets after `for`
for k, v in d.items():
print(k, v)
# Don't touch tuple brackets after `in`
for module in core, _unicodefun:
if hasattr(module, "_verify_python3_env"):
module._verify_python3_env = lambda: None
# Brackets remain for long for loop lines
for (
why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long,
i_dont_know_but_we_should_still_check_the_behaviour_if_they_do,
) in d.items():
print(k, v)
for (
k,
v,
) in dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items():
print(k, v)
# Test deeply nested brackets
for k, v in d.items():
print(k, v)
```
## Black Output
```py
# Only remove tuple brackets after `for`
for k, v in d.items():
print(k, v)
# Don't touch tuple brackets after `in`
for module in (core, _unicodefun):
if hasattr(module, "_verify_python3_env"):
module._verify_python3_env = lambda: None
# Brackets remain for long for loop lines
for (
why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long,
i_dont_know_but_we_should_still_check_the_behaviour_if_they_do,
) in d.items():
print(k, v)
for (
k,
v,
) in (
dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items()
):
print(k, v)
# Test deeply nested brackets
for k, v in d.items():
print(k, v)
```

View file

@ -0,0 +1,302 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_newline_after_code_block_open.py
---
## Input
```py
import random
def foo1():
print("The newline above me should be deleted!")
def foo2():
print("All the newlines above me should be deleted!")
def foo3():
print("No newline above me!")
print("There is a newline above me, and that's OK!")
def foo4():
# There is a comment here
print("The newline above me should not be deleted!")
class Foo:
def bar(self):
print("The newline above me should be deleted!")
for i in range(5):
print(f"{i}) The line above me should be removed!")
for i in range(5):
print(f"{i}) The lines above me should be removed!")
for i in range(5):
for j in range(7):
print(f"{i}) The lines above me should be removed!")
if random.randint(0, 3) == 0:
print("The new line above me is about to be removed!")
if random.randint(0, 3) == 0:
print("The new lines above me is about to be removed!")
if random.randint(0, 3) == 0:
if random.uniform(0, 1) > 0.5:
print("Two lines above me are about to be removed!")
while True:
print("The newline above me should be deleted!")
while True:
print("The newlines above me should be deleted!")
while True:
while False:
print("The newlines above me should be deleted!")
with open("/path/to/file.txt", mode="w") as file:
file.write("The new line above me is about to be removed!")
with open("/path/to/file.txt", mode="w") as file:
file.write("The new lines above me is about to be removed!")
with open("/path/to/file.txt", mode="r") as read_file:
with open("/path/to/output_file.txt", mode="w") as write_file:
write_file.writelines(read_file.readlines())
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -75,4 +75,4 @@
with open("/path/to/file.txt", mode="r") as read_file:
with open("/path/to/output_file.txt", mode="w") as write_file:
- write_file.writelines(read_file.readlines())
\ No newline at end of file
+ write_file.writelines(read_file.readlines())
```
## Ruff Output
```py
import random
def foo1():
print("The newline above me should be deleted!")
def foo2():
print("All the newlines above me should be deleted!")
def foo3():
print("No newline above me!")
print("There is a newline above me, and that's OK!")
def foo4():
# There is a comment here
print("The newline above me should not be deleted!")
class Foo:
def bar(self):
print("The newline above me should be deleted!")
for i in range(5):
print(f"{i}) The line above me should be removed!")
for i in range(5):
print(f"{i}) The lines above me should be removed!")
for i in range(5):
for j in range(7):
print(f"{i}) The lines above me should be removed!")
if random.randint(0, 3) == 0:
print("The new line above me is about to be removed!")
if random.randint(0, 3) == 0:
print("The new lines above me is about to be removed!")
if random.randint(0, 3) == 0:
if random.uniform(0, 1) > 0.5:
print("Two lines above me are about to be removed!")
while True:
print("The newline above me should be deleted!")
while True:
print("The newlines above me should be deleted!")
while True:
while False:
print("The newlines above me should be deleted!")
with open("/path/to/file.txt", mode="w") as file:
file.write("The new line above me is about to be removed!")
with open("/path/to/file.txt", mode="w") as file:
file.write("The new lines above me is about to be removed!")
with open("/path/to/file.txt", mode="r") as read_file:
with open("/path/to/output_file.txt", mode="w") as write_file:
write_file.writelines(read_file.readlines())
```
## Black Output
```py
import random
def foo1():
print("The newline above me should be deleted!")
def foo2():
print("All the newlines above me should be deleted!")
def foo3():
print("No newline above me!")
print("There is a newline above me, and that's OK!")
def foo4():
# There is a comment here
print("The newline above me should not be deleted!")
class Foo:
def bar(self):
print("The newline above me should be deleted!")
for i in range(5):
print(f"{i}) The line above me should be removed!")
for i in range(5):
print(f"{i}) The lines above me should be removed!")
for i in range(5):
for j in range(7):
print(f"{i}) The lines above me should be removed!")
if random.randint(0, 3) == 0:
print("The new line above me is about to be removed!")
if random.randint(0, 3) == 0:
print("The new lines above me is about to be removed!")
if random.randint(0, 3) == 0:
if random.uniform(0, 1) > 0.5:
print("Two lines above me are about to be removed!")
while True:
print("The newline above me should be deleted!")
while True:
print("The newlines above me should be deleted!")
while True:
while False:
print("The newlines above me should be deleted!")
with open("/path/to/file.txt", mode="w") as file:
file.write("The new line above me is about to be removed!")
with open("/path/to/file.txt", mode="w") as file:
file.write("The new lines above me is about to be removed!")
with open("/path/to/file.txt", mode="r") as read_file:
with open("/path/to/output_file.txt", mode="w") as write_file:
write_file.writelines(read_file.readlines())
```

View file

@ -0,0 +1,294 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_parens.py
---
## Input
```py
x = (1)
x = (1.2)
data = (
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
).encode()
async def show_status():
while True:
try:
if report_host:
data = (
f"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
).encode()
except Exception as e:
pass
def example():
return (("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"))
def example1():
return ((1111111111111111111111111111111111111111111111111111111111111111111111111111111111111))
def example1point5():
return ((((((1111111111111111111111111111111111111111111111111111111111111111111111111111111111111))))))
def example2():
return (("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"))
def example3():
return ((1111111111111111111111111111111111111111111111111111111111111111111111111111111))
def example4():
return ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((True))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
def example5():
return ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
def example6():
return ((((((((({a:a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]})))))))))
def example7():
return ((((((((({a:a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20000000000000000000]})))))))))
def example8():
return (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((None)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,18 +1,14 @@
x = 1
x = 1.2
-data = (
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-).encode()
+data = ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").encode()
async def show_status():
while True:
try:
if report_host:
- data = (
- f"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- ).encode()
+ data = (f"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").encode()
except Exception as e:
pass
@@ -30,15 +26,11 @@
def example2():
- return (
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- )
+ return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def example3():
- return (
- 1111111111111111111111111111111111111111111111111111111111111111111111111111111
- )
+ return 1111111111111111111111111111111111111111111111111111111111111111111111111111111
def example4():
@@ -82,4 +74,4 @@
def example8():
- return None
\ No newline at end of file
+ return None
```
## Ruff Output
```py
x = 1
x = 1.2
data = ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").encode()
async def show_status():
while True:
try:
if report_host:
data = (f"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").encode()
except Exception as e:
pass
def example():
return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def example1():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
def example1point5():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
def example2():
return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def example3():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111
def example4():
return True
def example5():
return ()
def example6():
return {a: a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]}
def example7():
return {
a: a
for a in [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20000000000000000000,
]
}
def example8():
return None
```
## Black Output
```py
x = 1
x = 1.2
data = (
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
).encode()
async def show_status():
while True:
try:
if report_host:
data = (
f"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
).encode()
except Exception as e:
pass
def example():
return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def example1():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
def example1point5():
return 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
def example2():
return (
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
def example3():
return (
1111111111111111111111111111111111111111111111111111111111111111111111111111111
)
def example4():
return True
def example5():
return ()
def example6():
return {a: a for a in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]}
def example7():
return {
a: a
for a in [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20000000000000000000,
]
}
def example8():
return None
```

View file

@ -0,0 +1,497 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py
---
## Input
```py
# Control
def double(a: int) -> int:
return 2*a
# Remove the brackets
def double(a: int) -> (int):
return 2*a
# Some newline variations
def double(a: int) -> (
int):
return 2*a
def double(a: int) -> (int
):
return 2*a
def double(a: int) -> (
int
):
return 2*a
# Don't lose the comments
def double(a: int) -> ( # Hello
int
):
return 2*a
def double(a: int) -> (
int # Hello
):
return 2*a
# Really long annotations
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo(a: int, b: int, c: int,) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo(a: int, b: int, c: int,) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
# Split args but no need to split return
def foo(a: int, b: int, c: int,) -> int:
return 2
# Deeply nested brackets
# with *interesting* spacing
def double(a: int) -> (((((int))))):
return 2*a
def double(a: int) -> (
( (
((int)
)
)
)
):
return 2*a
def foo() -> (
( (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
)
)):
return 2
# Return type with commas
def foo() -> (
tuple[int, int, int]
):
return 2
def foo() -> tuple[loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong]:
return 2
# Magic trailing comma example
def foo() -> tuple[int, int, int,]:
return 2
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,52 +1,53 @@
# Control
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
# Remove the brackets
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
# Some newline variations
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
# Don't lose the comments
-def double(a: int) -> int: # Hello
- return 2 * a
+def double(a: int) -> int:
+ return 2
+ * a
-def double(a: int) -> int: # Hello
- return 2 * a
+def double(a: int) -> int:
+ return 2
+ * a
# Really long annotations
-def foo() -> (
- intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
-):
+def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
-def foo() -> (
- intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
-):
+def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
-def foo() -> (
- intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
- | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
-):
+def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
+| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
@@ -62,10 +63,8 @@
a: int,
b: int,
c: int,
-) -> (
- intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
- | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
-):
+) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
+| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
@@ -81,16 +80,16 @@
# Deeply nested brackets
# with *interesting* spacing
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
def double(a: int) -> int:
- return 2 * a
+ return 2
+ * a
-def foo() -> (
- intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
-):
+def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
@@ -99,22 +98,18 @@
return 2
-def foo() -> (
- tuple[
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
- loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
- ]
-):
+def foo() -> tuple[
+ loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
+ loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
+ loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
+]:
return 2
# Magic trailing comma example
-def foo() -> (
- tuple[
- int,
- int,
- int,
- ]
-):
- return 2
\ No newline at end of file
+def foo() -> tuple[
+ int,
+ int,
+ int,
+]:
+ return 2
```
## Ruff Output
```py
# Control
def double(a: int) -> int:
return 2
* a
# Remove the brackets
def double(a: int) -> int:
return 2
* a
# Some newline variations
def double(a: int) -> int:
return 2
* a
def double(a: int) -> int:
return 2
* a
def double(a: int) -> int:
return 2
* a
# Don't lose the comments
def double(a: int) -> int:
return 2
* a
def double(a: int) -> int:
return 2
* a
# Really long annotations
def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo(
a: int,
b: int,
c: int,
) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo(
a: int,
b: int,
c: int,
) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
# Split args but no need to split return
def foo(
a: int,
b: int,
c: int,
) -> int:
return 2
# Deeply nested brackets
# with *interesting* spacing
def double(a: int) -> int:
return 2
* a
def double(a: int) -> int:
return 2
* a
def foo() -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
# Return type with commas
def foo() -> tuple[int, int, int]:
return 2
def foo() -> tuple[
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
]:
return 2
# Magic trailing comma example
def foo() -> tuple[
int,
int,
int,
]:
return 2
```
## Black Output
```py
# Control
def double(a: int) -> int:
return 2 * a
# Remove the brackets
def double(a: int) -> int:
return 2 * a
# Some newline variations
def double(a: int) -> int:
return 2 * a
def double(a: int) -> int:
return 2 * a
def double(a: int) -> int:
return 2 * a
# Don't lose the comments
def double(a: int) -> int: # Hello
return 2 * a
def double(a: int) -> int: # Hello
return 2 * a
# Really long annotations
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
def foo(
a: int,
b: int,
c: int,
) -> intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds:
return 2
def foo(
a: int,
b: int,
c: int,
) -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
# Split args but no need to split return
def foo(
a: int,
b: int,
c: int,
) -> int:
return 2
# Deeply nested brackets
# with *interesting* spacing
def double(a: int) -> int:
return 2 * a
def double(a: int) -> int:
return 2 * a
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
# Return type with commas
def foo() -> tuple[int, int, int]:
return 2
def foo() -> (
tuple[
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong,
]
):
return 2
# Magic trailing comma example
def foo() -> (
tuple[
int,
int,
int,
]
):
return 2
```

View file

@ -0,0 +1,239 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.py
---
## Input
```py
# We should not remove the trailing comma in a single-element subscript.
a: tuple[int,]
b = tuple[int,]
# But commas in multiple element subscripts should be removed.
c: tuple[int, int,]
d = tuple[int, int,]
# Remove commas for non-subscripts.
small_list = [1,]
list_of_types = [tuple[int,],]
small_set = {1,}
set_of_types = {tuple[int,],}
# Except single element tuples
small_tuple = (1,)
# Trailing commas in multiple chained non-nested parens.
zero(
one,
).two(
three,
).four(
five,
)
func1(arg1).func2(arg2,).func3(arg3).func4(arg4,).func5(arg5)
(
a,
b,
c,
d,
) = func1(
arg1
) and func2(arg2)
func(
argument1,
(
one,
two,
),
argument4,
argument5,
argument6,
)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -3,23 +3,61 @@
b = tuple[int,]
# But commas in multiple element subscripts should be removed.
-c: tuple[int, int]
-d = tuple[int, int]
+c: tuple[
+ int,
+ int,
+]
+d = tuple[
+ int,
+ int,
+]
# Remove commas for non-subscripts.
-small_list = [1]
-list_of_types = [tuple[int,]]
-small_set = {1}
-set_of_types = {tuple[int,]}
+small_list = [
+ 1,
+]
+list_of_types = [
+ tuple[int,],
+]
+small_set = {
+ 1,
+}
+set_of_types = {
+ tuple[int,],
+}
# Except single element tuples
small_tuple = (1,)
# Trailing commas in multiple chained non-nested parens.
-zero(one).two(three).four(five)
+zero(
+ one,
+).two(
+ three,
+).four(
+ five,
+)
-func1(arg1).func2(arg2).func3(arg3).func4(arg4).func5(arg5)
+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)
\ No newline at end of file
+func(
+ argument1,
+ (
+ one,
+ two,
+ ),
+ argument4,
+ argument5,
+ argument6,
+)
\ No newline at end of file
```
## Ruff Output
```py
# We should not remove the trailing comma in a single-element subscript.
a: tuple[int,]
b = tuple[int,]
# But commas in multiple element subscripts should be removed.
c: tuple[
int,
int,
]
d = tuple[
int,
int,
]
# Remove commas for non-subscripts.
small_list = [
1,
]
list_of_types = [
tuple[int,],
]
small_set = {
1,
}
set_of_types = {
tuple[int,],
}
# Except single element tuples
small_tuple = (1,)
# Trailing commas in multiple chained non-nested parens.
zero(
one,
).two(
three,
).four(
five,
)
func1(arg1).func2(
arg2,
).func3(arg3).func4(
arg4,
).func5(arg5)
(
a,
b,
c,
d,
) = func1(arg1) and func2(arg2)
func(
argument1,
(
one,
two,
),
argument4,
argument5,
argument6,
)
```
## Black Output
```py
# We should not remove the trailing comma in a single-element subscript.
a: tuple[int,]
b = tuple[int,]
# But commas in multiple element subscripts should be removed.
c: tuple[int, int]
d = tuple[int, int]
# Remove commas for non-subscripts.
small_list = [1]
list_of_types = [tuple[int,]]
small_set = {1}
set_of_types = {tuple[int,]}
# Except single element tuples
small_tuple = (1,)
# Trailing commas in multiple chained non-nested parens.
zero(one).two(three).four(five)
func1(arg1).func2(arg2).func3(arg3).func4(arg4).func5(arg5)
(a, b, c, d) = func1(arg1) and func2(arg2)
func(argument1, (one, two), argument4, argument5, argument6)
```

View file

@ -0,0 +1,117 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/string_prefixes.py
---
## Input
```py
#!/usr/bin/env python3
name = "Łukasz"
(f"hello {name}", F"hello {name}")
(b"", B"")
(u"", U"")
(r"", R"")
(rf"", fr"", Rf"", fR"", rF"", Fr"", RF"", FR"")
(rb"", br"", Rb"", bR"", rB"", Br"", RB"", BR"")
def docstring_singleline():
R"""2020 was one hell of a year. The good news is that we were able to"""
def docstring_multiline():
R"""
clear out all of the issues opened in that time :p
"""
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,13 +1,13 @@
#!/usr/bin/env python3
name = "Łukasz"
-(f"hello {name}", f"hello {name}")
-(b"", b"")
-("", "")
+(f"hello {name}", F"hello {name}")
+(b"", B"")
+(u"", U"")
(r"", R"")
-(rf"", rf"", Rf"", Rf"", rf"", rf"", Rf"", Rf"")
-(rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"")
+(rf"", fr"", Rf"", fR"", rF"", Fr"", RF"", FR"")
+(rb"", br"", Rb"", bR"", rB"", Br"", RB"", BR"")
def docstring_singleline():
@@ -17,4 +17,4 @@
def docstring_multiline():
R"""
clear out all of the issues opened in that time :p
- """
\ No newline at end of file
+ """
```
## Ruff Output
```py
#!/usr/bin/env python3
name = "Łukasz"
(f"hello {name}", F"hello {name}")
(b"", B"")
(u"", U"")
(r"", R"")
(rf"", fr"", Rf"", fR"", rF"", Fr"", RF"", FR"")
(rb"", br"", Rb"", bR"", rB"", Br"", RB"", BR"")
def docstring_singleline():
R"""2020 was one hell of a year. The good news is that we were able to"""
def docstring_multiline():
R"""
clear out all of the issues opened in that time :p
"""
```
## Black Output
```py
#!/usr/bin/env python3
name = "Łukasz"
(f"hello {name}", f"hello {name}")
(b"", b"")
("", "")
(r"", R"")
(rf"", rf"", Rf"", Rf"", rf"", rf"", Rf"", Rf"")
(rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"")
def docstring_singleline():
R"""2020 was one hell of a year. The good news is that we were able to"""
def docstring_multiline():
R"""
clear out all of the issues opened in that time :p
"""
```

View file

@ -0,0 +1,267 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/torture.py
---
## Input
```py
importA;() << 0 ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525 #
assert sort_by_dependency(
{
"1": {"2", "3"}, "2": {"2a", "2b"}, "3": {"3a", "3b"},
"2a": set(), "2b": set(), "3a": set(), "3b": set()
}
) == ["2a", "2b", "2", "3a", "3b", "3", "1"]
importA
0;0^0#
class A:
def foo(self):
for _ in range(10):
aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbb.cccccccccc( # pylint: disable=no-member
xxxxxxxxxxxx
)
def test(self, othr):
return (1 == 2 and
(name, description, self.default, self.selected, self.auto_generated, self.parameters, self.meta_data, self.schedule) ==
(name, description, othr.default, othr.selected, othr.auto_generated, othr.parameters, othr.meta_data, othr.schedule))
assert (
a_function(very_long_arguments_that_surpass_the_limit, 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"}
)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,21 +1,23 @@
importA
(
()
- << 0
- ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525
+ << 0**101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
-assert sort_by_dependency(
- {
- "1": {"2", "3"},
- "2": {"2a", "2b"},
- "3": {"3a", "3b"},
- "2a": set(),
- "2b": set(),
- "3a": set(),
- "3b": set(),
- }
-) == ["2a", "2b", "2", "3a", "3b", "3", "1"]
+assert (
+ sort_by_dependency(
+ {
+ "1": {"2", "3"},
+ "2": {"2a", "2b"},
+ "3": {"3a", "3b"},
+ "2a": set(),
+ "2b": set(),
+ "3a": set(),
+ "3b": set(),
+ }
+ )
+ == ["2a", "2b", "2", "3a", "3b", "3", "1"]
+)
importA
0
@@ -25,13 +27,12 @@
class A:
def foo(self):
for _ in range(10):
- aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbb.cccccccccc(
- xxxxxxxxxxxx
- ) # pylint: disable=no-member
+ aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbb.cccccccccc(xxxxxxxxxxxx) # pylint: disable=no-member
def test(self, othr):
- return 1 == 2 and (
+ return 1 == 2
+ and (
name,
description,
self.default,
@@ -40,7 +41,8 @@
self.parameters,
self.meta_data,
self.schedule,
- ) == (
+ )
+ == (
name,
description,
othr.default,
@@ -52,7 +54,13 @@
)
-assert a_function(
- very_long_arguments_that_surpass_the_limit,
- 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"}
\ No newline at end of file
+assert (
+ a_function(
+ very_long_arguments_that_surpass_the_limit,
+ 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",
+ }
+)
\ No newline at end of file
```
## Ruff Output
```py
importA
(
()
<< 0**101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert (
sort_by_dependency(
{
"1": {"2", "3"},
"2": {"2a", "2b"},
"3": {"3a", "3b"},
"2a": set(),
"2b": set(),
"3a": set(),
"3b": set(),
}
)
== ["2a", "2b", "2", "3a", "3b", "3", "1"]
)
importA
0
0 ^ 0 #
class A:
def foo(self):
for _ in range(10):
aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbb.cccccccccc(xxxxxxxxxxxx) # pylint: disable=no-member
def test(self, othr):
return 1 == 2
and (
name,
description,
self.default,
self.selected,
self.auto_generated,
self.parameters,
self.meta_data,
self.schedule,
)
== (
name,
description,
othr.default,
othr.selected,
othr.auto_generated,
othr.parameters,
othr.meta_data,
othr.schedule,
)
assert (
a_function(
very_long_arguments_that_surpass_the_limit,
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",
}
)
```
## Black Output
```py
importA
(
()
<< 0
** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert sort_by_dependency(
{
"1": {"2", "3"},
"2": {"2a", "2b"},
"3": {"3a", "3b"},
"2a": set(),
"2b": set(),
"3a": set(),
"3b": set(),
}
) == ["2a", "2b", "2", "3a", "3b", "3", "1"]
importA
0
0 ^ 0 #
class A:
def foo(self):
for _ in range(10):
aaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbb.cccccccccc(
xxxxxxxxxxxx
) # pylint: disable=no-member
def test(self, othr):
return 1 == 2 and (
name,
description,
self.default,
self.selected,
self.auto_generated,
self.parameters,
self.meta_data,
self.schedule,
) == (
name,
description,
othr.default,
othr.selected,
othr.auto_generated,
othr.parameters,
othr.meta_data,
othr.schedule,
)
assert a_function(
very_long_arguments_that_surpass_the_limit,
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"}
```

View file

@ -0,0 +1,179 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens1.py
---
## Input
```py
if e1234123412341234.winerror not in (_winapi.ERROR_SEM_TIMEOUT,
_winapi.ERROR_PIPE_BUSY) or _check_timeout(t):
pass
if x:
if y:
new_id = max(Vegetable.objects.order_by('-id')[0].id,
Mineral.objects.order_by('-id')[0].id) + 1
class X:
def get_help_text(self):
return ngettext(
"Your password must contain at least %(min_length)d character.",
"Your password must contain at least %(min_length)d characters.",
self.min_length,
) % {'min_length': self.min_length}
class A:
def b(self):
if self.connection.mysql_is_mariadb and (
10,
4,
3,
) < self.connection.mysql_version < (10, 5, 2):
pass
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,15 +1,14 @@
-if e1234123412341234.winerror not in (
- _winapi.ERROR_SEM_TIMEOUT,
- _winapi.ERROR_PIPE_BUSY,
-) or _check_timeout(t):
+if e1234123412341234.winerror
+not in (_winapi.ERROR_SEM_TIMEOUT, _winapi.ERROR_PIPE_BUSY)
+or _check_timeout(t):
pass
if x:
if y:
new_id = (
max(
- Vegetable.objects.order_by("-id")[0].id,
- Mineral.objects.order_by("-id")[0].id,
+ Vegetable.objects.order_by('-id')[0].id,
+ Mineral.objects.order_by('-id')[0].id,
)
+ 1
)
@@ -21,14 +20,20 @@
"Your password must contain at least %(min_length)d character.",
"Your password must contain at least %(min_length)d characters.",
self.min_length,
- ) % {"min_length": self.min_length}
+ )
+ % {'min_length': self.min_length}
class A:
def b(self):
- if self.connection.mysql_is_mariadb and (
- 10,
- 4,
- 3,
- ) < self.connection.mysql_version < (10, 5, 2):
- pass
\ No newline at end of file
+ if (
+ self.connection.mysql_is_mariadb
+ and (
+ 10,
+ 4,
+ 3,
+ )
+ < self.connection.mysql_version
+ < (10, 5, 2)
+ ):
+ pass
```
## Ruff Output
```py
if e1234123412341234.winerror
not in (_winapi.ERROR_SEM_TIMEOUT, _winapi.ERROR_PIPE_BUSY)
or _check_timeout(t):
pass
if x:
if y:
new_id = (
max(
Vegetable.objects.order_by('-id')[0].id,
Mineral.objects.order_by('-id')[0].id,
)
+ 1
)
class X:
def get_help_text(self):
return ngettext(
"Your password must contain at least %(min_length)d character.",
"Your password must contain at least %(min_length)d characters.",
self.min_length,
)
% {'min_length': self.min_length}
class A:
def b(self):
if (
self.connection.mysql_is_mariadb
and (
10,
4,
3,
)
< self.connection.mysql_version
< (10, 5, 2)
):
pass
```
## Black Output
```py
if e1234123412341234.winerror not in (
_winapi.ERROR_SEM_TIMEOUT,
_winapi.ERROR_PIPE_BUSY,
) or _check_timeout(t):
pass
if x:
if y:
new_id = (
max(
Vegetable.objects.order_by("-id")[0].id,
Mineral.objects.order_by("-id")[0].id,
)
+ 1
)
class X:
def get_help_text(self):
return ngettext(
"Your password must contain at least %(min_length)d character.",
"Your password must contain at least %(min_length)d characters.",
self.min_length,
) % {"min_length": self.min_length}
class A:
def b(self):
if self.connection.mysql_is_mariadb and (
10,
4,
3,
) < self.connection.mysql_version < (10, 5, 2):
pass
```

View file

@ -0,0 +1,58 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens2.py
---
## Input
```py
if (e123456.get_tk_patchlevel() >= (8, 6, 0, 'final') or
(8, 5, 8) <= get_tk_patchlevel() < (8, 6)):
pass
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,6 +1,5 @@
-if e123456.get_tk_patchlevel() >= (8, 6, 0, "final") or (
- 8,
- 5,
- 8,
-) <= get_tk_patchlevel() < (8, 6):
- pass
\ No newline at end of file
+if (
+ e123456.get_tk_patchlevel() >= (8, 6, 0, 'final')
+ or (8, 5, 8) <= get_tk_patchlevel() < (8, 6)
+):
+ pass
```
## Ruff Output
```py
if (
e123456.get_tk_patchlevel() >= (8, 6, 0, 'final')
or (8, 5, 8) <= get_tk_patchlevel() < (8, 6)
):
pass
```
## Black Output
```py
if e123456.get_tk_patchlevel() >= (8, 6, 0, "final") or (
8,
5,
8,
) <= get_tk_patchlevel() < (8, 6):
pass
```

View file

@ -0,0 +1,64 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens3.py
---
## Input
```py
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -5,4 +5,5 @@
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
- ) % {"reported_username": reported_username, "report_reason": report_reason}
\ No newline at end of file
+ )
+ % {"reported_username": reported_username, "report_reason": report_reason}
```
## Ruff Output
```py
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
)
% {"reported_username": reported_username, "report_reason": report_reason}
```
## Black Output
```py
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}
```

View file

@ -0,0 +1,181 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_commas_in_leading_parts.py
---
## Input
```py
zero(one,).two(three,).four(five,)
func1(arg1).func2(arg2,).func3(arg3).func4(arg4,).func5(arg5)
# Inner one-element tuple shouldn't explode
func1(arg1).func2(arg1, (one_tuple,)).func3(arg3)
(a, b, c, d,) = func1(arg1) and func2(arg2)
# Example from https://github.com/psf/black/issues/3229
def refresh_token(self, device_family, refresh_token, api_key):
return self.orchestration.refresh_token(
data={
"refreshToken": refresh_token,
},
api_key=api_key,
)["extensions"]["sdk"]["token"]
# Edge case where a bug in a working-in-progress version of
# https://github.com/psf/black/pull/3370 causes an infinite recursion.
assert (
long_module.long_class.long_func().another_func()
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)
# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -20,9 +20,7 @@
b,
c,
d,
-) = func1(
- arg1
-) and func2(arg2)
+) = func1(arg1) and func2(arg2)
# Example from https://github.com/psf/black/issues/3229
@@ -43,8 +41,6 @@
)
# Regression test for https://github.com/psf/black/issues/3414.
-assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
- xxxxxxxxx
-).xxxxxxxxxxxxxxxxxx(), (
+assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(xxxxxxxxx).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
\ No newline at end of file
```
## Ruff Output
```py
zero(
one,
).two(
three,
).four(
five,
)
func1(arg1).func2(
arg2,
).func3(arg3).func4(
arg4,
).func5(arg5)
# Inner one-element tuple shouldn't explode
func1(arg1).func2(arg1, (one_tuple,)).func3(arg3)
(
a,
b,
c,
d,
) = func1(arg1) and func2(arg2)
# Example from https://github.com/psf/black/issues/3229
def refresh_token(self, device_family, refresh_token, api_key):
return self.orchestration.refresh_token(
data={
"refreshToken": refresh_token,
},
api_key=api_key,
)["extensions"]["sdk"]["token"]
# Edge case where a bug in a working-in-progress version of
# https://github.com/psf/black/pull/3370 causes an infinite recursion.
assert (
long_module.long_class.long_func().another_func()
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)
# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(xxxxxxxxx).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
```
## Black Output
```py
zero(
one,
).two(
three,
).four(
five,
)
func1(arg1).func2(
arg2,
).func3(arg3).func4(
arg4,
).func5(arg5)
# Inner one-element tuple shouldn't explode
func1(arg1).func2(arg1, (one_tuple,)).func3(arg3)
(
a,
b,
c,
d,
) = func1(
arg1
) and func2(arg2)
# Example from https://github.com/psf/black/issues/3229
def refresh_token(self, device_family, refresh_token, api_key):
return self.orchestration.refresh_token(
data={
"refreshToken": refresh_token,
},
api_key=api_key,
)["extensions"]["sdk"]["token"]
# Edge case where a bug in a working-in-progress version of
# https://github.com/psf/black/pull/3370 causes an infinite recursion.
assert (
long_module.long_class.long_func().another_func()
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)
# Regression test for https://github.com/psf/black/issues/3414.
assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
xxxxxxxxx
).xxxxxxxxxxxxxxxxxx(), (
"xxx {xxxxxxxxx} xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
```

View file

@ -1,7 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
print("hello, world")

View file

@ -1,10 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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

View file

@ -1,36 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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

View file

@ -1,171 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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

View file

@ -1,105 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
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,
},
)

View file

@ -1,71 +0,0 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: adjust_quotes(formatted.print()?.as_code())
---
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

View file

@ -1,70 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
"""The asyncio package, tracking PEP 3156."""
# flake8: noqa
from logging import WARNING
from logging import (
ERROR,
)
import sys
# This relies on each of the submodules having an __all__ variable.
from .base_events import *
from .coroutines import *
from .events import * # comment here
from .futures import *
from .locks import * # comment here
from .protocols import *
from ..runners import * # comment here
from ..queues import *
from ..streams import *
from some_library import (
Just,
Enough,
Libraries,
To,
Fit,
In,
This,
Nice,
Split,
Which,
We,
No,
Longer,
Use,
)
from name_of_a_company.extremely_long_project_name.component.ttypes import (
CuteLittleServiceHandlerFactoryyy,
)
from name_of_a_company.extremely_long_project_name.extremely_long_component_name.ttypes import *
from .a.b.c.subprocess import *
from . import tasks
from . import A, B, C
from . import (
SomeVeryLongNameAndAllOfItsAdditionalLetters1,
SomeVeryLongNameAndAllOfItsAdditionalLetters2,
)
__all__ = (
base_events.__all__
+ coroutines.__all__
+ events.__all__
+ futures.__all__
+ locks.__all__
+ protocols.__all__
+ runners.__all__
+ queues.__all__
+ streams.__all__
+ tasks.__all__
)

View file

@ -1,28 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
# We should not treat the trailing comma
# in a single-element subscript.
a: tuple[int,]
b = tuple[int,]
# The magic comma still applies to multi-element subscripts.
c: tuple[
int,
int,
]
d = tuple[
int,
int,
]
# Magic commas still work as expected for non-subscripts.
small_list = [
1,
]
list_of_types = [
tuple[int,],
]

View file

@ -1,69 +0,0 @@
---
source: src/source_code/mod.rs
assertion_line: 0
expression: formatted
---
def function(**kwargs):
t = a**2 + b**3
return t**2
def function_replace_spaces(**kwargs):
t = a**2 + b**3 + c**4
def function_dont_replace_spaces():
{**a, **b, **c}
a = 5**~4
b = 5 ** f()
c = -(5**2)
d = 5 ** f["hi"]
e = lazy(lambda **kwargs: 5)
f = f() ** 5
g = a.b**c.d
h = 5 ** funcs.f()
i = funcs.f() ** 5
j = super().name ** 5
k = [(2**idx, value) for idx, value in pairs]
l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001)
m = [([2**63], [1, 2**63])]
n = count <= 10**5
o = settings(max_examples=10**6)
p = {(k, k**2): v**2 for k, v in pairs}
q = [10**i for i in range(6)]
r = x**y
a = 5.0**~4.0
b = 5.0 ** f()
c = -(5.0**2.0)
d = 5.0 ** f["hi"]
e = lazy(lambda **kwargs: 5)
f = f() ** 5.0
g = a.b**c.d
h = 5.0 ** funcs.f()
i = funcs.f() ** 5.0
j = super().name ** 5.0
k = [(2.0**idx, value) for idx, value in pairs]
l = mod.weights_[0] == pytest.approx(0.95**100, abs=0.001)
m = [([2.0**63.0], [1.0, 2**63.0])]
n = count <= 10**5.0
o = settings(max_examples=10**6.0)
p = {(k, k**2): v**2.0 for k, v in pairs}
q = [10.5**i for i in range(6)]
# WE SHOULD DEFINITELY NOT EAT THESE COMMENTS (https://github.com/psf/black/issues/2873)
if hasattr(view, "sum_of_weights"):
return np.divide( # type: ignore[no-any-return]
view.variance, # type: ignore[union-attr]
view.sum_of_weights, # type: ignore[union-attr]
out=np.full(view.sum_of_weights.shape, np.nan), # type: ignore[union-attr]
where=view.sum_of_weights**2 > view.sum_of_weights_squared, # type: ignore[union-attr]
)
return np.divide(
where=view.sum_of_weights_of_weight_long**2 > view.sum_of_weights_squared, # type: ignore
)

Some files were not shown because too many files have changed in this diff Show more