Compare commits

..

1 Commits

Author SHA1 Message Date
Charlie Marsh
6e6188c599 Respect later bindings in only_binding 2024-02-12 20:59:38 -05:00
91 changed files with 955 additions and 3842 deletions

View File

@@ -387,11 +387,6 @@ We have several ways of benchmarking and profiling Ruff:
- Microbenchmarks which run the linter or the formatter on individual files. These run on pull requests.
- Profiling the linter on either the microbenchmarks or entire projects
> \[!NOTE\]
> When running benchmarks, ensure that your CPU is otherwise idle (e.g., close any background
> applications, like web browsers). You may also want to switch your CPU to a "performance"
> mode, if it exists, especially when benchmarking short-lived processes.
### CPython Benchmark
First, clone [CPython](https://github.com/python/cpython). It's a large and diverse Python codebase,

View File

@@ -48,7 +48,6 @@ serde = { workspace = true }
serde_json = { workspace = true }
shellexpand = { workspace = true }
strum = { workspace = true, features = [] }
tempfile = { workspace = true }
thiserror = { workspace = true }
toml = { workspace = true }
tracing = { workspace = true, features = ["log"] }

View File

@@ -1,7 +1,7 @@
use std::fmt::Debug;
use std::fs::{self, File};
use std::hash::Hasher;
use std::io::{self, BufReader, Write};
use std::io::{self, BufReader, BufWriter, Write};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Mutex;
@@ -15,7 +15,6 @@ use rayon::iter::ParallelIterator;
use rayon::iter::{IntoParallelIterator, ParallelBridge};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;
use ruff_cache::{CacheKey, CacheKeyHasher};
use ruff_diagnostics::{DiagnosticKind, Fix};
@@ -166,29 +165,15 @@ impl Cache {
return Ok(());
}
// Write the cache to a temporary file first and then rename it for an "atomic" write.
// Protects against data loss if the process is killed during the write and races between different ruff
// processes, resulting in a corrupted cache file. https://github.com/astral-sh/ruff/issues/8147#issuecomment-1943345964
let mut temp_file =
NamedTempFile::new_in(self.path.parent().expect("Write path must have a parent"))
.context("Failed to create temporary file")?;
// Serialize to in-memory buffer because hyperfine benchmark showed that it's faster than
// using a `BufWriter` and our cache files are small enough that streaming isn't necessary.
let serialized =
bincode::serialize(&self.package).context("Failed to serialize cache data")?;
temp_file
.write_all(&serialized)
.context("Failed to write serialized cache to temporary file.")?;
temp_file.persist(&self.path).with_context(|| {
let file = File::create(&self.path)
.with_context(|| format!("Failed to create cache file '{}'", self.path.display()))?;
let writer = BufWriter::new(file);
bincode::serialize_into(writer, &self.package).with_context(|| {
format!(
"Failed to rename temporary cache file to {}",
"Failed to serialise cache to file '{}'",
self.path.display()
)
})?;
Ok(())
})
}
/// Applies the pending changes without storing the cache to disk.

View File

@@ -1,8 +1,7 @@
use std::cell::Cell;
use std::num::NonZeroU8;
use crate::format_element::PrintMode;
use crate::{GroupId, TextSize};
use std::cell::Cell;
use std::num::NonZeroU8;
/// A Tag marking the start and end of some content to which some special formatting should be applied.
///
@@ -100,10 +99,6 @@ pub enum Tag {
}
impl Tag {
pub const fn align(count: NonZeroU8) -> Tag {
Tag::StartAlign(Align(count))
}
/// Returns `true` if `self` is any start tag.
pub const fn is_start(&self) -> bool {
matches!(

View File

@@ -1,75 +0,0 @@
import codecs
import io
from pathlib import Path
# Errors
with open("FURB129.py") as f:
for _line in f.readlines():
pass
a = [line.lower() for line in f.readlines()]
b = {line.upper() for line in f.readlines()}
c = {line.lower(): line.upper() for line in f.readlines()}
with Path("FURB129.py").open() as f:
for _line in f.readlines():
pass
for _line in open("FURB129.py").readlines():
pass
for _line in Path("FURB129.py").open().readlines():
pass
def func():
f = Path("FURB129.py").open()
for _line in f.readlines():
pass
f.close()
def func(f: io.BytesIO):
for _line in f.readlines():
pass
def func():
with (open("FURB129.py") as f, foo as bar):
for _line in f.readlines():
pass
for _line in bar.readlines():
pass
# False positives
def func(f):
for _line in f.readlines():
pass
def func(f: codecs.StreamReader):
for _line in f.readlines():
pass
def func():
class A:
def readlines(self) -> list[str]:
return ["a", "b", "c"]
return A()
for _line in func().readlines():
pass
# OK
for _line in ["a", "b", "c"]:
pass
with open("FURB129.py") as f:
for _line in f:
pass
for _line in f.readlines(10):
pass
for _not_line in f.readline():
pass

View File

@@ -162,26 +162,3 @@ async def f(x: bool):
T = asyncio.create_task(asyncio.sleep(1))
else:
T = None
# Error
def f():
loop = asyncio.new_event_loop()
loop.create_task(main()) # Error
# Error
def f():
loop = asyncio.get_event_loop()
loop.create_task(main()) # Error
# OK
def f():
global task
loop = asyncio.new_event_loop()
task = loop.create_task(main()) # Error
# OK
def f():
global task
loop = asyncio.get_event_loop()
task = loop.create_task(main()) # Error

View File

@@ -2,14 +2,11 @@ use ruff_python_ast::Comprehension;
use crate::checkers::ast::Checker;
use crate::codes::Rule;
use crate::rules::{flake8_simplify, refurb};
use crate::rules::flake8_simplify;
/// Run lint rules over a [`Comprehension`] syntax nodes.
pub(crate) fn comprehension(comprehension: &Comprehension, checker: &mut Checker) {
if checker.enabled(Rule::InDictKeys) {
flake8_simplify::rules::key_in_dict_comprehension(checker, comprehension);
}
if checker.enabled(Rule::ReadlinesInFor) {
refurb::rules::readlines_in_comprehension(checker, comprehension);
}
}

View File

@@ -1317,9 +1317,6 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
if checker.enabled(Rule::UnnecessaryDictIndexLookup) {
pylint::rules::unnecessary_dict_index_lookup(checker, for_stmt);
}
if checker.enabled(Rule::ReadlinesInFor) {
refurb::rules::readlines_in_for(checker, for_stmt);
}
if !is_async {
if checker.enabled(Rule::ReimplementedBuiltin) {
flake8_simplify::rules::convert_for_loop_to_any_all(checker, stmt);

View File

@@ -40,7 +40,7 @@ use ruff_diagnostics::{Diagnostic, IsolationLevel};
use ruff_notebook::{CellOffsets, NotebookIndex};
use ruff_python_ast::all::{extract_all_names, DunderAllFlags};
use ruff_python_ast::helpers::{
collect_import_from_member, extract_handled_exceptions, is_docstring_stmt, to_module_path,
collect_import_from_member, extract_handled_exceptions, to_module_path,
};
use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::str::trailing_quote;
@@ -71,38 +71,6 @@ mod analyze;
mod annotation;
mod deferred;
/// State representing whether a docstring is expected or not for the next statement.
#[derive(Default, Debug, Copy, Clone, PartialEq)]
enum DocstringState {
/// The next statement is expected to be a docstring, but not necessarily so.
///
/// For example, in the following code:
///
/// ```python
/// class Foo:
/// pass
///
///
/// def bar(x, y):
/// """Docstring."""
/// return x + y
/// ```
///
/// For `Foo`, the state is expected when the checker is visiting the class
/// body but isn't going to be present. While, for `bar` function, the docstring
/// is expected and present.
#[default]
Expected,
Other,
}
impl DocstringState {
/// Returns `true` if the next statement is expected to be a docstring.
const fn is_expected(self) -> bool {
matches!(self, DocstringState::Expected)
}
}
pub(crate) struct Checker<'a> {
/// The [`Path`] to the file under analysis.
path: &'a Path,
@@ -146,8 +114,6 @@ pub(crate) struct Checker<'a> {
pub(crate) flake8_bugbear_seen: Vec<TextRange>,
/// The end offset of the last visited statement.
last_stmt_end: TextSize,
/// A state describing if a docstring is expected or not.
docstring_state: DocstringState,
}
impl<'a> Checker<'a> {
@@ -187,7 +153,6 @@ impl<'a> Checker<'a> {
cell_offsets,
notebook_index,
last_stmt_end: TextSize::default(),
docstring_state: DocstringState::default(),
}
}
}
@@ -385,16 +350,6 @@ where
// the node.
let flags_snapshot = self.semantic.flags;
// Update the semantic model if it is in a docstring. This should be done after the
// flags snapshot to ensure that it gets reset once the statement is analyzed.
if self.docstring_state.is_expected() {
if is_docstring_stmt(stmt) {
self.semantic.flags |= SemanticModelFlags::DOCSTRING;
}
// Reset the state irrespective of whether the statement is a docstring or not.
self.docstring_state = DocstringState::Other;
}
// Step 1: Binding
match stmt {
Stmt::AugAssign(ast::StmtAugAssign {
@@ -696,8 +651,6 @@ where
self.semantic.set_globals(globals);
}
// Set the docstring state before visiting the class body.
self.docstring_state = DocstringState::Expected;
self.visit_body(body);
}
Stmt::TypeAlias(ast::StmtTypeAlias {
@@ -2008,8 +1961,6 @@ impl<'a> Checker<'a> {
};
self.visit_parameters(parameters);
// Set the docstring state before visiting the function body.
self.docstring_state = DocstringState::Expected;
self.visit_body(body);
}
}

View File

@@ -1025,7 +1025,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
#[allow(deprecated)]
(Refurb, "113") => (RuleGroup::Nursery, rules::refurb::rules::RepeatedAppend),
(Refurb, "118") => (RuleGroup::Preview, rules::refurb::rules::ReimplementedOperator),
(Refurb, "129") => (RuleGroup::Preview, rules::refurb::rules::ReadlinesInFor),
#[allow(deprecated)]
(Refurb, "131") => (RuleGroup::Nursery, rules::refurb::rules::DeleteFullSlice),
#[allow(deprecated)]

View File

@@ -419,20 +419,23 @@ mod tests {
Ok(())
}
#[test_case(Path::new("line_ending_crlf.py"))]
#[test_case(Path::new("line_ending_lf.py"))]
fn source_code_style(path: &Path) -> Result<()> {
let snapshot = format!("{}", path.to_string_lossy());
let diagnostics = test_path(
Path::new("isort").join(path).as_path(),
&LinterSettings {
src: vec![test_resource_path("fixtures/isort")],
..LinterSettings::for_rule(Rule::UnsortedImports)
},
)?;
crate::assert_messages!(snapshot, diagnostics);
Ok(())
}
// Test currently disabled as line endings are automatically converted to
// platform-appropriate ones in CI/CD #[test_case(Path::new("
// line_ending_crlf.py"))] #[test_case(Path::new("line_ending_lf.py"))]
// fn source_code_style(path: &Path) -> Result<()> {
// let snapshot = format!("{}", path.to_string_lossy());
// let diagnostics = test_path(
// Path::new("isort")
// .join(path)
// .as_path(),
// &LinterSettings {
// src: vec![test_resource_path("fixtures/isort")],
// ..LinterSettings::for_rule(Rule::UnsortedImports)
// },
// )?;
// crate::assert_messages!(snapshot, diagnostics);
// Ok(())
// }
#[test_case(Path::new("separate_local_folder_imports.py"))]
fn known_local_folder(path: &Path) -> Result<()> {

View File

@@ -1,23 +0,0 @@
---
source: crates/ruff_linter/src/rules/isort/mod.rs
---
line_ending_crlf.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
1 | / from long_module_name import member_one, member_two, member_three, member_four, member_five
2 | |
| |_^ I001
|
= help: Organize imports
Safe fix
1 |-from long_module_name import member_one, member_two, member_three, member_four, member_five
1 |+from long_module_name import (
2 |+ member_five,
3 |+ member_four,
4 |+ member_one,
5 |+ member_three,
6 |+ member_two,
7 |+)
2 8 |

View File

@@ -1,23 +0,0 @@
---
source: crates/ruff_linter/src/rules/isort/mod.rs
---
line_ending_lf.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
1 | / from long_module_name import member_one, member_two, member_three, member_four, member_five
2 | |
| |_^ I001
|
= help: Organize imports
Safe fix
1 |-from long_module_name import member_one, member_two, member_three, member_four, member_five
1 |+from long_module_name import (
2 |+ member_five,
3 |+ member_four,
4 |+ member_one,
5 |+ member_three,
6 |+ member_two,
7 |+)
2 8 |

View File

@@ -17,7 +17,6 @@ mod tests {
#[test_case(Rule::ReadWholeFile, Path::new("FURB101.py"))]
#[test_case(Rule::RepeatedAppend, Path::new("FURB113.py"))]
#[test_case(Rule::ReimplementedOperator, Path::new("FURB118.py"))]
#[test_case(Rule::ReadlinesInFor, Path::new("FURB129.py"))]
#[test_case(Rule::DeleteFullSlice, Path::new("FURB131.py"))]
#[test_case(Rule::CheckAndRemoveFromSet, Path::new("FURB132.py"))]
#[test_case(Rule::IfExprMinMax, Path::new("FURB136.py"))]

View File

@@ -9,7 +9,6 @@ pub(crate) use math_constant::*;
pub(crate) use metaclass_abcmeta::*;
pub(crate) use print_empty_string::*;
pub(crate) use read_whole_file::*;
pub(crate) use readlines_in_for::*;
pub(crate) use redundant_log_base::*;
pub(crate) use regex_flag_alias::*;
pub(crate) use reimplemented_operator::*;
@@ -31,7 +30,6 @@ mod math_constant;
mod metaclass_abcmeta;
mod print_empty_string;
mod read_whole_file;
mod readlines_in_for;
mod redundant_log_base;
mod regex_flag_alias;
mod reimplemented_operator;

View File

@@ -1,92 +0,0 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{Comprehension, Expr, StmtFor};
use ruff_python_semantic::analyze::typing;
use ruff_python_semantic::analyze::typing::is_io_base_expr;
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for uses of `readlines()` when iterating over a file line-by-line.
///
/// ## Why is this bad?
/// Rather than iterating over all lines in a file by calling `readlines()`,
/// it's more convenient and performant to iterate over the file object
/// directly.
///
/// ## Example
/// ```python
/// with open("file.txt") as fp:
/// for line in fp.readlines():
/// ...
/// ```
///
/// Use instead:
/// ```python
/// with open("file.txt") as fp:
/// for line in fp:
/// ...
/// ```
///
/// ## References
/// - [Python documentation: `io.IOBase.readlines`](https://docs.python.org/3/library/io.html#io.IOBase.readlines)
#[violation]
pub(crate) struct ReadlinesInFor;
impl AlwaysFixableViolation for ReadlinesInFor {
#[derive_message_formats]
fn message(&self) -> String {
format!("Instead of calling `readlines()`, iterate over file object directly")
}
fn fix_title(&self) -> String {
"Remove `readlines()`".into()
}
}
/// FURB129
pub(crate) fn readlines_in_for(checker: &mut Checker, for_stmt: &StmtFor) {
readlines_in_iter(checker, for_stmt.iter.as_ref());
}
/// FURB129
pub(crate) fn readlines_in_comprehension(checker: &mut Checker, comprehension: &Comprehension) {
readlines_in_iter(checker, &comprehension.iter);
}
fn readlines_in_iter(checker: &mut Checker, iter_expr: &Expr) {
let Expr::Call(expr_call) = iter_expr else {
return;
};
let Expr::Attribute(expr_attr) = expr_call.func.as_ref() else {
return;
};
if expr_attr.attr.as_str() != "readlines" || !expr_call.arguments.is_empty() {
return;
}
// Determine whether `fp` in `fp.readlines()` was bound to a file object.
if let Expr::Name(name) = expr_attr.value.as_ref() {
if !checker
.semantic()
.resolve_name(name)
.map(|id| checker.semantic().binding(id))
.is_some_and(|binding| typing::is_io_base(binding, checker.semantic()))
{
return;
}
} else {
if !is_io_base_expr(expr_attr.value.as_ref(), checker.semantic()) {
return;
}
}
let mut diagnostic = Diagnostic::new(ReadlinesInFor, expr_call.range());
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_deletion(
expr_call.range().add_start(expr_attr.value.range().len()),
)));
checker.diagnostics.push(diagnostic);
}

View File

@@ -1,207 +0,0 @@
---
source: crates/ruff_linter/src/rules/refurb/mod.rs
---
FURB129.py:7:18: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
5 | # Errors
6 | with open("FURB129.py") as f:
7 | for _line in f.readlines():
| ^^^^^^^^^^^^^ FURB129
8 | pass
9 | a = [line.lower() for line in f.readlines()]
|
= help: Remove `readlines()`
Unsafe fix
4 4 |
5 5 | # Errors
6 6 | with open("FURB129.py") as f:
7 |- for _line in f.readlines():
7 |+ for _line in f:
8 8 | pass
9 9 | a = [line.lower() for line in f.readlines()]
10 10 | b = {line.upper() for line in f.readlines()}
FURB129.py:9:35: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
7 | for _line in f.readlines():
8 | pass
9 | a = [line.lower() for line in f.readlines()]
| ^^^^^^^^^^^^^ FURB129
10 | b = {line.upper() for line in f.readlines()}
11 | c = {line.lower(): line.upper() for line in f.readlines()}
|
= help: Remove `readlines()`
Unsafe fix
6 6 | with open("FURB129.py") as f:
7 7 | for _line in f.readlines():
8 8 | pass
9 |- a = [line.lower() for line in f.readlines()]
9 |+ a = [line.lower() for line in f]
10 10 | b = {line.upper() for line in f.readlines()}
11 11 | c = {line.lower(): line.upper() for line in f.readlines()}
12 12 |
FURB129.py:10:35: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
8 | pass
9 | a = [line.lower() for line in f.readlines()]
10 | b = {line.upper() for line in f.readlines()}
| ^^^^^^^^^^^^^ FURB129
11 | c = {line.lower(): line.upper() for line in f.readlines()}
|
= help: Remove `readlines()`
Unsafe fix
7 7 | for _line in f.readlines():
8 8 | pass
9 9 | a = [line.lower() for line in f.readlines()]
10 |- b = {line.upper() for line in f.readlines()}
10 |+ b = {line.upper() for line in f}
11 11 | c = {line.lower(): line.upper() for line in f.readlines()}
12 12 |
13 13 | with Path("FURB129.py").open() as f:
FURB129.py:11:49: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
9 | a = [line.lower() for line in f.readlines()]
10 | b = {line.upper() for line in f.readlines()}
11 | c = {line.lower(): line.upper() for line in f.readlines()}
| ^^^^^^^^^^^^^ FURB129
12 |
13 | with Path("FURB129.py").open() as f:
|
= help: Remove `readlines()`
Unsafe fix
8 8 | pass
9 9 | a = [line.lower() for line in f.readlines()]
10 10 | b = {line.upper() for line in f.readlines()}
11 |- c = {line.lower(): line.upper() for line in f.readlines()}
11 |+ c = {line.lower(): line.upper() for line in f}
12 12 |
13 13 | with Path("FURB129.py").open() as f:
14 14 | for _line in f.readlines():
FURB129.py:14:18: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
13 | with Path("FURB129.py").open() as f:
14 | for _line in f.readlines():
| ^^^^^^^^^^^^^ FURB129
15 | pass
|
= help: Remove `readlines()`
Unsafe fix
11 11 | c = {line.lower(): line.upper() for line in f.readlines()}
12 12 |
13 13 | with Path("FURB129.py").open() as f:
14 |- for _line in f.readlines():
14 |+ for _line in f:
15 15 | pass
16 16 |
17 17 | for _line in open("FURB129.py").readlines():
FURB129.py:17:14: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
15 | pass
16 |
17 | for _line in open("FURB129.py").readlines():
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB129
18 | pass
|
= help: Remove `readlines()`
Unsafe fix
14 14 | for _line in f.readlines():
15 15 | pass
16 16 |
17 |-for _line in open("FURB129.py").readlines():
17 |+for _line in open("FURB129.py"):
18 18 | pass
19 19 |
20 20 | for _line in Path("FURB129.py").open().readlines():
FURB129.py:20:14: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
18 | pass
19 |
20 | for _line in Path("FURB129.py").open().readlines():
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB129
21 | pass
|
= help: Remove `readlines()`
Unsafe fix
17 17 | for _line in open("FURB129.py").readlines():
18 18 | pass
19 19 |
20 |-for _line in Path("FURB129.py").open().readlines():
20 |+for _line in Path("FURB129.py").open():
21 21 | pass
22 22 |
23 23 |
FURB129.py:26:18: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
24 | def func():
25 | f = Path("FURB129.py").open()
26 | for _line in f.readlines():
| ^^^^^^^^^^^^^ FURB129
27 | pass
28 | f.close()
|
= help: Remove `readlines()`
Unsafe fix
23 23 |
24 24 | def func():
25 25 | f = Path("FURB129.py").open()
26 |- for _line in f.readlines():
26 |+ for _line in f:
27 27 | pass
28 28 | f.close()
29 29 |
FURB129.py:32:18: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
31 | def func(f: io.BytesIO):
32 | for _line in f.readlines():
| ^^^^^^^^^^^^^ FURB129
33 | pass
|
= help: Remove `readlines()`
Unsafe fix
29 29 |
30 30 |
31 31 | def func(f: io.BytesIO):
32 |- for _line in f.readlines():
32 |+ for _line in f:
33 33 | pass
34 34 |
35 35 |
FURB129.py:38:22: FURB129 [*] Instead of calling `readlines()`, iterate over file object directly
|
36 | def func():
37 | with (open("FURB129.py") as f, foo as bar):
38 | for _line in f.readlines():
| ^^^^^^^^^^^^^ FURB129
39 | pass
40 | for _line in bar.readlines():
|
= help: Remove `readlines()`
Unsafe fix
35 35 |
36 36 | def func():
37 37 | with (open("FURB129.py") as f, foo as bar):
38 |- for _line in f.readlines():
38 |+ for _line in f:
39 39 | pass
40 40 | for _line in bar.readlines():
41 41 | pass

View File

@@ -52,15 +52,14 @@ use ruff_text_size::Ranged;
/// - [The Python Standard Library](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)
#[violation]
pub struct AsyncioDanglingTask {
expr: String,
method: Method,
}
impl Violation for AsyncioDanglingTask {
#[derive_message_formats]
fn message(&self) -> String {
let AsyncioDanglingTask { expr, method } = self;
format!("Store a reference to the return value of `{expr}.{method}`")
let AsyncioDanglingTask { method } = self;
format!("Store a reference to the return value of `asyncio.{method}`")
}
}
@@ -81,35 +80,23 @@ pub(crate) fn asyncio_dangling_task(expr: &Expr, semantic: &SemanticModel) -> Op
})
{
return Some(Diagnostic::new(
AsyncioDanglingTask {
expr: "asyncio".to_string(),
method,
},
AsyncioDanglingTask { method },
expr.range(),
));
}
// Ex) `loop = ...; loop.create_task(...)`
// Ex) `loop = asyncio.get_running_loop(); loop.create_task(...)`
if let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func.as_ref() {
if attr == "create_task" {
if let Expr::Name(name) = value.as_ref() {
if typing::resolve_assignment(value, semantic).is_some_and(|call_path| {
matches!(
call_path.as_slice(),
[
"asyncio",
"get_event_loop" | "get_running_loop" | "new_event_loop"
]
)
}) {
return Some(Diagnostic::new(
AsyncioDanglingTask {
expr: name.id.to_string(),
method: Method::CreateTask,
},
expr.range(),
));
}
if typing::resolve_assignment(value, semantic).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["asyncio", "get_running_loop"])
}) {
return Some(Diagnostic::new(
AsyncioDanglingTask {
method: Method::CreateTask,
},
expr.range(),
));
}
}
}

View File

@@ -25,7 +25,7 @@ RUF006.py:68:12: RUF006 Store a reference to the return value of `asyncio.create
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
RUF006.py:74:26: RUF006 Store a reference to the return value of `loop.create_task`
RUF006.py:74:26: RUF006 Store a reference to the return value of `asyncio.create_task`
|
72 | def f():
73 | loop = asyncio.get_running_loop()
@@ -33,7 +33,7 @@ RUF006.py:74:26: RUF006 Store a reference to the return value of `loop.create_ta
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
RUF006.py:97:5: RUF006 Store a reference to the return value of `loop.create_task`
RUF006.py:97:5: RUF006 Store a reference to the return value of `asyncio.create_task`
|
95 | def f():
96 | loop = asyncio.get_running_loop()
@@ -41,24 +41,4 @@ RUF006.py:97:5: RUF006 Store a reference to the return value of `loop.create_tas
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
|
RUF006.py:170:5: RUF006 Store a reference to the return value of `loop.create_task`
|
168 | def f():
169 | loop = asyncio.new_event_loop()
170 | loop.create_task(main()) # Error
| ^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
171 |
172 | # Error
|
RUF006.py:175:5: RUF006 Store a reference to the return value of `loop.create_task`
|
173 | def f():
174 | loop = asyncio.get_event_loop()
175 | loop.create_task(main()) # Error
| ^^^^^^^^^^^^^^^^^^^^^^^^ RUF006
176 |
177 | # OK
|

View File

@@ -13,11 +13,10 @@ use ruff_text_size::{Ranged, TextRange};
use crate::comments::{leading_comments, trailing_comments, Comments, SourceComment};
use crate::expression::parentheses::{
in_parentheses_only_group, in_parentheses_only_if_group_breaks, in_parentheses_only_indent_end,
in_parentheses_only_indent_start, in_parentheses_only_soft_line_break,
in_parentheses_only_soft_line_break_or_space, is_expression_parenthesized,
write_in_parentheses_only_group_end_tag, write_in_parentheses_only_group_start_tag,
Parentheses,
in_parentheses_only_group, in_parentheses_only_if_group_breaks,
in_parentheses_only_soft_line_break, in_parentheses_only_soft_line_break_or_space,
is_expression_parenthesized, write_in_parentheses_only_group_end_tag,
write_in_parentheses_only_group_start_tag, Parentheses,
};
use crate::expression::OperatorPrecedence;
use crate::prelude::*;
@@ -288,7 +287,7 @@ impl Format<PyFormatContext<'_>> for BinaryLike<'_> {
let flat_binary = self.flatten(&comments, f.context().source());
if self.is_bool_op() {
return in_parentheses_only_group(&flat_binary).fmt(f);
return in_parentheses_only_group(&&*flat_binary).fmt(f);
}
let source = f.context().source();
@@ -482,7 +481,7 @@ impl Format<PyFormatContext<'_>> for BinaryLike<'_> {
// Finish the group that wraps all implicit concatenated strings
write_in_parentheses_only_group_end_tag(f);
} else {
in_parentheses_only_group(&flat_binary).fmt(f)?;
in_parentheses_only_group(&&*flat_binary).fmt(f)?;
}
Ok(())
@@ -528,12 +527,6 @@ impl<'a> Deref for FlatBinaryExpression<'a> {
}
}
impl Format<PyFormatContext<'_>> for FlatBinaryExpression<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
Format::fmt(&**self, f)
}
}
/// Binary chain represented as a flat vector where operands are stored at even indices and operators
/// add odd indices.
///
@@ -649,7 +642,7 @@ impl<'a> FlatBinaryExpressionSlice<'a> {
}
/// Formats a binary chain slice by inserting soft line breaks before the lowest-precedence operators.
/// In other words: It splits the line before the lowest precedence operators (and it either splits
/// In other words: It splits the line before by the lowest precedence operators (and it either splits
/// all of them or none). For example, the lowest precedence operator for `a + b * c + d` is the `+` operator.
/// The expression either gets formatted as `a + b * c + d` if it fits on the line or as
/// ```python
@@ -685,64 +678,59 @@ impl Format<PyFormatContext<'_>> for FlatBinaryExpressionSlice<'_> {
let mut last_operator: Option<OperatorIndex> = None;
let lowest_precedence = self.lowest_precedence();
let lowest_precedence_operators = self
.operators()
.filter(|(_, operator)| operator.precedence() == lowest_precedence);
for (index, operator_part) in lowest_precedence_operators {
let left = self.between_operators(last_operator, index);
let right = self.after_operator(index);
for (index, operator_part) in self.operators() {
if operator_part.precedence() == lowest_precedence {
let left = self.between_operators(last_operator, index);
let right = self.after_operator(index);
let is_pow = operator_part.symbol.is_pow()
&& is_simple_power_expression(
left.last_operand().expression(),
right.first_operand().expression(),
f.context().comments().ranges(),
f.context().source(),
);
let is_pow = operator_part.symbol.is_pow()
&& is_simple_power_expression(
left.last_operand().expression(),
right.first_operand().expression(),
f.context().comments().ranges(),
f.context().source(),
);
if let Some(leading) = left.first_operand().leading_binary_comments() {
leading_comments(leading).fmt(f)?;
}
match &left.0 {
[OperandOrOperator::Operand(operand)] => operand.fmt(f)?,
_ => in_parentheses_only_group(&left).fmt(f)?,
}
if last_operator.is_none() {
in_parentheses_only_indent_start().fmt(f)?;
}
if let Some(trailing) = left.last_operand().trailing_binary_comments() {
trailing_comments(trailing).fmt(f)?;
}
if is_pow {
in_parentheses_only_soft_line_break().fmt(f)?;
} else {
in_parentheses_only_soft_line_break_or_space().fmt(f)?;
}
operator_part.fmt(f)?;
// Format the operator on its own line if the right side has any leading comments.
if operator_part.has_trailing_comments()
|| right.first_operand().has_unparenthesized_leading_comments(
f.context().comments(),
f.context().source(),
)
{
hard_line_break().fmt(f)?;
} else if is_pow {
if is_fix_power_op_line_length_enabled(f.context()) {
in_parentheses_only_if_group_breaks(&space()).fmt(f)?;
if let Some(leading) = left.first_operand().leading_binary_comments() {
leading_comments(leading).fmt(f)?;
}
} else {
space().fmt(f)?;
}
last_operator = Some(index);
match &left.0 {
[OperandOrOperator::Operand(operand)] => operand.fmt(f)?,
_ => in_parentheses_only_group(&left).fmt(f)?,
}
if let Some(trailing) = left.last_operand().trailing_binary_comments() {
trailing_comments(trailing).fmt(f)?;
}
if is_pow {
in_parentheses_only_soft_line_break().fmt(f)?;
} else {
in_parentheses_only_soft_line_break_or_space().fmt(f)?;
}
operator_part.fmt(f)?;
// Format the operator on its own line if the right side has any leading comments.
if operator_part.has_trailing_comments()
|| right.first_operand().has_unparenthesized_leading_comments(
f.context().comments(),
f.context().source(),
)
{
hard_line_break().fmt(f)?;
} else if is_pow {
if is_fix_power_op_line_length_enabled(f.context()) {
in_parentheses_only_if_group_breaks(&space()).fmt(f)?;
}
} else {
space().fmt(f)?;
}
last_operator = Some(index);
}
}
// Format the last right side
@@ -757,11 +745,9 @@ impl Format<PyFormatContext<'_>> for FlatBinaryExpressionSlice<'_> {
}
match &right.0 {
[OperandOrOperator::Operand(operand)] => operand.fmt(f)?,
_ => in_parentheses_only_group(&right).fmt(f)?,
[OperandOrOperator::Operand(operand)] => operand.fmt(f),
_ => in_parentheses_only_group(&right).fmt(f),
}
in_parentheses_only_indent_end().fmt(f)
}
}

View File

@@ -379,42 +379,6 @@ where
})
}
pub(super) fn in_parentheses_only_indent_start<'a>() -> impl Format<PyFormatContext<'a>> {
format_with(|f: &mut PyFormatter| {
match f.context().node_level() {
NodeLevel::TopLevel(_) | NodeLevel::CompoundStatement | NodeLevel::Expression(None) => {
// no-op, not parenthesized
}
NodeLevel::Expression(Some(parentheses_id)) => f.write_element(FormatElement::Tag(
Tag::StartIndentIfGroupBreaks(parentheses_id),
)),
NodeLevel::ParenthesizedExpression => {
f.write_element(FormatElement::Tag(Tag::StartIndent))
}
}
Ok(())
})
}
pub(super) fn in_parentheses_only_indent_end<'a>() -> impl Format<PyFormatContext<'a>> {
format_with(|f: &mut PyFormatter| {
match f.context().node_level() {
NodeLevel::TopLevel(_) | NodeLevel::CompoundStatement | NodeLevel::Expression(None) => {
// no-op, not parenthesized
}
NodeLevel::Expression(Some(_)) => {
f.write_element(FormatElement::Tag(Tag::EndIndentIfGroupBreaks))
}
NodeLevel::ParenthesizedExpression => {
f.write_element(FormatElement::Tag(Tag::EndIndent))
}
}
Ok(())
})
}
/// Format comments inside empty parentheses, brackets or curly braces.
///
/// Empty `()`, `[]` and `{}` are special because there can be dangling comments, and they can be in

View File

@@ -2,7 +2,8 @@ use ruff_python_ast::BytesLiteral;
use ruff_text_size::Ranged;
use crate::prelude::*;
use crate::string::{StringNormalizer, StringPart};
use crate::preview::is_hex_codes_in_unicode_sequences_enabled;
use crate::string::{Quoting, StringPart};
#[derive(Default)]
pub struct FormatBytesLiteral;
@@ -11,9 +12,14 @@ impl FormatNodeRule<BytesLiteral> for FormatBytesLiteral {
fn fmt_fields(&self, item: &BytesLiteral, f: &mut PyFormatter) -> FormatResult<()> {
let locator = f.context().locator();
StringNormalizer::from_context(f.context())
.with_preferred_quote_style(f.options().quote_style())
.normalize(&StringPart::from_source(item.range(), &locator), &locator)
StringPart::from_source(item.range(), &locator)
.normalize(
Quoting::CanChange,
&locator,
f.options().quote_style(),
f.context().docstring(),
is_hex_codes_in_unicode_sequences_enabled(f.context()),
)
.fmt(f)
}
}

View File

@@ -2,7 +2,8 @@ use ruff_python_ast::FString;
use ruff_text_size::Ranged;
use crate::prelude::*;
use crate::string::{Quoting, StringNormalizer, StringPart};
use crate::preview::is_hex_codes_in_unicode_sequences_enabled;
use crate::string::{Quoting, StringPart};
/// Formats an f-string which is part of a larger f-string expression.
///
@@ -25,12 +26,13 @@ impl Format<PyFormatContext<'_>> for FormatFString<'_> {
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
let locator = f.context().locator();
let result = StringNormalizer::from_context(f.context())
.with_quoting(self.quoting)
.with_preferred_quote_style(f.options().quote_style())
let result = StringPart::from_source(self.value.range(), &locator)
.normalize(
&StringPart::from_source(self.value.range(), &locator),
self.quoting,
&locator,
f.options().quote_style(),
f.context().docstring(),
is_hex_codes_in_unicode_sequences_enabled(f.context()),
)
.fmt(f);

View File

@@ -2,7 +2,8 @@ use ruff_python_ast::StringLiteral;
use ruff_text_size::Ranged;
use crate::prelude::*;
use crate::string::{docstring, Quoting, StringNormalizer, StringPart};
use crate::preview::is_hex_codes_in_unicode_sequences_enabled;
use crate::string::{docstring, Quoting, StringPart};
use crate::QuoteStyle;
pub(crate) struct FormatStringLiteral<'a> {
@@ -58,13 +59,13 @@ impl Format<PyFormatContext<'_>> for FormatStringLiteral<'_> {
quote_style
};
let normalized = StringNormalizer::from_context(f.context())
.with_quoting(self.layout.quoting())
.with_preferred_quote_style(quote_style)
.normalize(
&StringPart::from_source(self.value.range(), &locator),
&locator,
);
let normalized = StringPart::from_source(self.value.range(), &locator).normalize(
self.layout.quoting(),
&locator,
quote_style,
f.context().docstring(),
is_hex_codes_in_unicode_sequences_enabled(f.context()),
);
if self.layout.is_docstring() {
docstring::format(&normalized, f)

View File

@@ -18,7 +18,6 @@ use crate::expression::parentheses::in_parentheses_only_soft_line_break_or_space
use crate::other::f_string::FormatFString;
use crate::other::string_literal::{FormatStringLiteral, StringLiteralKind};
use crate::prelude::*;
use crate::preview::is_hex_codes_in_unicode_sequences_enabled;
use crate::QuoteStyle;
pub(crate) mod docstring;
@@ -292,54 +291,23 @@ impl StringPart {
}
}
/// Returns the prefix of the string part.
pub(crate) const fn prefix(&self) -> StringPrefix {
self.prefix
}
/// Returns the surrounding quotes of the string part.
pub(crate) const fn quotes(&self) -> StringQuotes {
self.quotes
}
/// Returns the range of the string's content in the source (minus prefix and quotes).
pub(crate) const fn content_range(&self) -> TextRange {
self.content_range
}
}
pub(crate) struct StringNormalizer {
quoting: Quoting,
preferred_quote_style: QuoteStyle,
parent_docstring_quote_char: Option<QuoteChar>,
normalize_hex: bool,
}
impl StringNormalizer {
pub(crate) fn from_context(context: &PyFormatContext<'_>) -> Self {
Self {
quoting: Quoting::default(),
preferred_quote_style: QuoteStyle::default(),
parent_docstring_quote_char: context.docstring(),
normalize_hex: is_hex_codes_in_unicode_sequences_enabled(context),
}
}
pub(crate) fn with_preferred_quote_style(mut self, quote_style: QuoteStyle) -> Self {
self.preferred_quote_style = quote_style;
self
}
pub(crate) fn with_quoting(mut self, quoting: Quoting) -> Self {
self.quoting = quoting;
self
}
/// Computes the strings preferred quotes.
pub(crate) fn choose_quotes(&self, string: &StringPart, locator: &Locator) -> StringQuotes {
/// Computes the strings preferred quotes and normalizes its content.
///
/// The parent docstring quote style should be set when formatting a code
/// snippet within the docstring. The quote style should correspond to the
/// style of quotes used by said docstring. Normalization will ensure the
/// quoting styles don't conflict.
pub(crate) fn normalize<'a>(
self,
quoting: Quoting,
locator: &'a Locator,
configured_style: QuoteStyle,
parent_docstring_quote_char: Option<QuoteChar>,
normalize_hex: bool,
) -> NormalizedString<'a> {
// Per PEP 8, always prefer double quotes for triple-quoted strings.
// Except when using quote-style-preserve.
let preferred_style = if string.quotes().triple {
let preferred_style = if self.quotes.triple {
// ... unless we're formatting a code snippet inside a docstring,
// then we specifically want to invert our quote style to avoid
// writing out invalid Python.
@@ -385,49 +353,39 @@ impl StringNormalizer {
// Overall this is a bit of a corner case and just inverting the
// style from what the parent ultimately decided upon works, even
// if it doesn't have perfect alignment with PEP8.
if let Some(quote) = self.parent_docstring_quote_char {
if let Some(quote) = parent_docstring_quote_char {
QuoteStyle::from(quote.invert())
} else if self.preferred_quote_style.is_preserve() {
} else if configured_style.is_preserve() {
QuoteStyle::Preserve
} else {
QuoteStyle::Double
}
} else {
self.preferred_quote_style
configured_style
};
match self.quoting {
Quoting::Preserve => string.quotes(),
let raw_content = &locator.slice(self.content_range);
let quotes = match quoting {
Quoting::Preserve => self.quotes,
Quoting::CanChange => {
if let Some(preferred_quote) = QuoteChar::from_style(preferred_style) {
let raw_content = locator.slice(string.content_range());
if string.prefix().is_raw_string() {
choose_quotes_for_raw_string(raw_content, string.quotes(), preferred_quote)
if self.prefix.is_raw_string() {
choose_quotes_raw(raw_content, self.quotes, preferred_quote)
} else {
choose_quotes_impl(raw_content, string.quotes(), preferred_quote)
choose_quotes(raw_content, self.quotes, preferred_quote)
}
} else {
string.quotes()
self.quotes
}
}
}
}
};
/// Computes the strings preferred quotes and normalizes its content.
pub(crate) fn normalize<'a>(
&self,
string: &StringPart,
locator: &'a Locator,
) -> NormalizedString<'a> {
let raw_content = locator.slice(string.content_range());
let quotes = self.choose_quotes(string, locator);
let normalized = normalize_string(raw_content, quotes, string.prefix(), self.normalize_hex);
let normalized = normalize_string(raw_content, quotes, self.prefix, normalize_hex);
NormalizedString {
prefix: string.prefix(),
content_range: string.content_range(),
prefix: self.prefix,
content_range: self.content_range,
text: normalized,
quotes,
}
@@ -554,7 +512,7 @@ impl Format<PyFormatContext<'_>> for StringPrefix {
/// The preferred quote style is chosen unless the string contains unescaped quotes of the
/// preferred style. For example, `r"foo"` is chosen over `r'foo'` if the preferred quote
/// style is double quotes.
fn choose_quotes_for_raw_string(
fn choose_quotes_raw(
input: &str,
quotes: StringQuotes,
preferred_quote: QuoteChar,
@@ -613,11 +571,7 @@ fn choose_quotes_for_raw_string(
/// For triple quoted strings, the preferred quote style is always used, unless the string contains
/// a triplet of the quote character (e.g., if double quotes are preferred, double quotes will be
/// used unless the string contains `"""`).
fn choose_quotes_impl(
input: &str,
quotes: StringQuotes,
preferred_quote: QuoteChar,
) -> StringQuotes {
fn choose_quotes(input: &str, quotes: StringQuotes, preferred_quote: QuoteChar) -> StringQuotes {
let quote = if quotes.triple {
// True if the string contains a triple quote sequence of the configured quote style.
let mut uses_triple_quotes = false;
@@ -826,7 +780,7 @@ impl TryFrom<char> for QuoteChar {
/// with the provided [`StringQuotes`] style.
///
/// Returns the normalized string and whether it contains new lines.
pub(crate) fn normalize_string(
fn normalize_string(
input: &str,
quotes: StringQuotes,
prefix: StringPrefix,

View File

@@ -1,314 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/collections.py
---
## Input
```python
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
@@ -54,7 +54,7 @@
}
assert False, (
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa wraps %s"
- % bar
+ % bar
)
# looping over a 1-tuple should also not get wrapped
@@ -75,7 +75,7 @@
if True:
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
Config.IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING
- | {pylons.controllers.WSGIController}
+ | {pylons.controllers.WSGIController}
)
if True:
```
## Ruff Output
```python
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
```python
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

@@ -192,7 +192,7 @@ instruction()#comment with bad spacing
children[0],
body,
children[-1], # type: ignore
@@ -72,14 +76,18 @@
@@ -72,7 +76,11 @@
body,
parameters.children[-1], # )2
]
@@ -204,19 +204,7 @@ instruction()#comment with bad spacing
+ ] # 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
+ # 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
# has the child process finished?
@@ -115,7 +123,9 @@
arg3=True,
)
@@ -240,23 +228,14 @@ instruction()#comment with bad spacing
)
@@ -151,14 +164,17 @@
[
CONFIG_FILE,
]
- + SHARED_CONFIG_FILES
- + USER_CONFIG_FILES
+ + SHARED_CONFIG_FILES
+ + USER_CONFIG_FILES
) # type: Final
@@ -158,7 +171,10 @@
class Test:
def _init_host(self, parsed) -> None:
- if parsed.hostname is None or not parsed.hostname.strip(): # type: ignore
+ if (
+ parsed.hostname is None # type: ignore
+ or not parsed.hostname.strip()
+ or not parsed.hostname.strip()
+ ):
pass
@@ -351,11 +330,11 @@ def inline_comments_in_brackets_ruin_everything():
] # 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
# 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
@@ -432,8 +411,8 @@ CONFIG_FILES = (
[
CONFIG_FILE,
]
+ SHARED_CONFIG_FILES
+ USER_CONFIG_FILES
+ SHARED_CONFIG_FILES
+ USER_CONFIG_FILES
) # type: Final
@@ -441,7 +420,7 @@ class Test:
def _init_host(self, parsed) -> None:
if (
parsed.hostname is None # type: ignore
or not parsed.hostname.strip()
or not parsed.hostname.strip()
):
pass

View File

@@ -141,23 +141,6 @@ aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*ite
an_element_with_a_long_value = calls() or more_calls() and more() # type: bool
tup = (
@@ -61,11 +59,11 @@
a = (
element
- + another_element
- + another_element_with_long_name
- + element
- + another_element
- + another_element_with_long_name
+ + another_element
+ + another_element_with_long_name
+ + element
+ + another_element
+ + another_element_with_long_name
) # type: int
@@ -100,7 +98,13 @@
)
@@ -260,11 +243,11 @@ def f(
a = (
element
+ another_element
+ another_element_with_long_name
+ element
+ another_element
+ another_element_with_long_name
+ another_element
+ another_element_with_long_name
+ element
+ another_element
+ another_element_with_long_name
) # type: int

View File

@@ -146,40 +146,6 @@ if (
# b comment
None
)
@@ -92,20 +91,20 @@
# comment1
a
# comment2
- or (
- # comment3
- (
- # comment4
- b
- )
- # comment5
- and
- # comment6
- c
or (
- # comment7
- d
+ # comment3
+ (
+ # comment4
+ b
+ )
+ # comment5
+ and
+ # comment6
+ c
+ or (
+ # comment7
+ d
+ )
)
- )
):
print("Foo")
```
## Ruff Output
@@ -278,21 +244,21 @@ if (
# comment1
a
# comment2
or (
# comment3
(
# comment4
b
)
# comment5
and
# comment6
c
or (
# comment7
d
)
or (
# comment3
(
# comment4
b
)
# comment5
and
# comment6
c
or (
# comment7
d
)
)
):
print("Foo")
```

View File

@@ -193,26 +193,6 @@ class C:
```diff
--- Black
+++ Ruff
@@ -22,8 +22,8 @@
if (
# Rule 1
i % 2 == 0
- # Rule 2
- and i % 3 == 0
+ # Rule 2
+ and i % 3 == 0
):
while (
# Just a comment
@@ -41,7 +41,7 @@
)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
- % (test.name, test.filename, lineno, lname, err)
+ % (test.name, test.filename, lineno, lname, err)
)
def omitting_trailers(self) -> None:
@@ -110,19 +110,20 @@
value, is_going_to_be="too long to fit in a single line", srsly=True
), "Not what we expected"
@@ -242,12 +222,12 @@ class C:
+ key8: value8,
+ key9: value9,
+ }
+ == expected
+ == 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
@@ -161,21 +162,19 @@
@@ -161,9 +162,7 @@
8 STORE_ATTR 0 (x)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
@@ -258,29 +238,6 @@ class C:
assert (
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
- == {
- key1: value1,
- key2: value2,
- key3: value3,
- key4: value4,
- key5: value5,
- key6: value6,
- key7: value7,
- key8: value8,
- key9: value9,
- }
+ == {
+ key1: value1,
+ key2: value2,
+ key3: value3,
+ key4: value4,
+ key5: value5,
+ key6: value6,
+ key7: value7,
+ key8: value8,
+ key9: value9,
+ }
)
```
## Ruff Output
@@ -310,8 +267,8 @@ class C:
if (
# Rule 1
i % 2 == 0
# Rule 2
and i % 3 == 0
# Rule 2
and i % 3 == 0
):
while (
# Just a comment
@@ -329,7 +286,7 @@ class C:
)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
% (test.name, test.filename, lineno, lname, err)
% (test.name, test.filename, lineno, lname, err)
)
def omitting_trailers(self) -> None:
@@ -410,7 +367,7 @@ class C:
key8: value8,
key9: value9,
}
== expected
== expected
), "Not what we expected and the message is too long to fit in one line"
assert expected(
@@ -454,17 +411,17 @@ class C:
assert (
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
)
```

View File

@@ -193,26 +193,6 @@ class C:
```diff
--- Black
+++ Ruff
@@ -22,8 +22,8 @@
if (
# Rule 1
i % 2 == 0
- # Rule 2
- and i % 3 == 0
+ # Rule 2
+ and i % 3 == 0
):
while (
# Just a comment
@@ -41,7 +41,7 @@
)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
- % (test.name, test.filename, lineno, lname, err)
+ % (test.name, test.filename, lineno, lname, err)
)
def omitting_trailers(self) -> None:
@@ -110,19 +110,20 @@
value, is_going_to_be="too long to fit in a single line", srsly=True
), "Not what we expected"
@@ -242,12 +222,12 @@ class C:
+ key8: value8,
+ key9: value9,
+ }
+ == expected
+ == 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
@@ -161,21 +162,19 @@
@@ -161,9 +162,7 @@
8 STORE_ATTR 0 (x)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
@@ -258,29 +238,6 @@ class C:
assert (
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
- == {
- key1: value1,
- key2: value2,
- key3: value3,
- key4: value4,
- key5: value5,
- key6: value6,
- key7: value7,
- key8: value8,
- key9: value9,
- }
+ == {
+ key1: value1,
+ key2: value2,
+ key3: value3,
+ key4: value4,
+ key5: value5,
+ key6: value6,
+ key7: value7,
+ key8: value8,
+ key9: value9,
+ }
)
```
## Ruff Output
@@ -310,8 +267,8 @@ class C:
if (
# Rule 1
i % 2 == 0
# Rule 2
and i % 3 == 0
# Rule 2
and i % 3 == 0
):
while (
# Just a comment
@@ -329,7 +286,7 @@ class C:
)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
% (test.name, test.filename, lineno, lname, err)
% (test.name, test.filename, lineno, lname, err)
)
def omitting_trailers(self) -> None:
@@ -410,7 +367,7 @@ class C:
key8: value8,
key9: value9,
}
== expected
== expected
), "Not what we expected and the message is too long to fit in one line"
assert expected(
@@ -454,17 +411,17 @@ class C:
assert (
expectedexpectedexpectedexpectedexpectedexpectedexpectedexpectedexpect
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
)
```

View File

@@ -275,131 +275,6 @@ last_call()
) # note: no trailing comma pre-3.6
call(*gidgets[:2])
call(a, *gidgets[:2])
@@ -277,95 +277,95 @@
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
+ 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
+ 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
+ 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
+ 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
+ and threading.current_thread() != threading.main_thread()
+ or signal.getsignal(signal.SIGINT) != signal.default_int_handler
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- / 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
+ | 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
+ | 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
+ + 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
+ * (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
+ / (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
)
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ >> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
bbbb >> bbbb * bbbb
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- ^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- ^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ ^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ ^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
last_call()
# standalone comment at ENDMARKER
```
## Ruff Output
@@ -684,95 +559,95 @@ for (
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
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
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
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
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
and threading.current_thread() != threading.main_thread()
or signal.getsignal(signal.SIGINT) != signal.default_int_handler
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
return True
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
/ 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
| 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
| 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
+ 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
* (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
/ (aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa)
)
aaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaa
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
<< aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
<< aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
bbbb >> bbbb * bbbb
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
last_call()
# standalone comment at ENDMARKER

View File

@@ -110,15 +110,6 @@ elif unformatted:
},
)
@@ -19,7 +18,7 @@
"-la",
]
# fmt: on
- + path,
+ + path,
check=True,
)
@@ -82,6 +81,6 @@
if x:
return x
@@ -152,7 +143,7 @@ run(
"-la",
]
# fmt: on
+ path,
+ path,
check=True,
)

View File

@@ -21,17 +21,15 @@ else:
```diff
--- Black
+++ Ruff
@@ -1,8 +1,8 @@
@@ -1,7 +1,7 @@
a, b, c = 3, 4, 5
if (
a == 3
- and b != 9 # fmt: skip
- and c is not None
+ and b != 9 # fmt: skip
+ and c is not None
+ and b != 9 # fmt: skip
and c is not None
):
print("I'm good!")
else:
```
## Ruff Output
@@ -40,8 +38,8 @@ else:
a, b, c = 3, 4, 5
if (
a == 3
and b != 9 # fmt: skip
and c is not None
and b != 9 # fmt: skip
and c is not None
):
print("I'm good!")
else:

View File

@@ -1,343 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/function_trailing_comma.py
---
## Input
```python
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
@@ -38,16 +38,16 @@
}["a"]
if (
a
- == {
- "a": 1,
- "b": 2,
- "c": 3,
- "d": 4,
- "e": 5,
- "f": 6,
- "g": 7,
- "h": 8,
- }["a"]
+ == {
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ "d": 4,
+ "e": 5,
+ "f": 6,
+ "g": 7,
+ "h": 8,
+ }["a"]
):
pass
```
## Ruff Output
```python
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
```python
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,227 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/import_spacing.py
---
## Input
```python
"""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__
)
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -52,13 +52,13 @@
__all__ = (
base_events.__all__
- + coroutines.__all__
- + events.__all__
- + futures.__all__
- + locks.__all__
- + protocols.__all__
- + runners.__all__
- + queues.__all__
- + streams.__all__
- + tasks.__all__
+ + coroutines.__all__
+ + events.__all__
+ + futures.__all__
+ + locks.__all__
+ + protocols.__all__
+ + runners.__all__
+ + queues.__all__
+ + streams.__all__
+ + tasks.__all__
)
```
## Ruff Output
```python
"""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__
)
```
## Black Output
```python
"""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

@@ -304,52 +304,7 @@ long_unmergable_string_with_pragma = (
```diff
--- Black
+++ Ruff
@@ -40,11 +40,11 @@
sooo="soooo", x=2
),
"A %s %s"
- % (
- "formatted",
- "string",
- ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
- % ("soooo", 2),
+ % (
+ "formatted",
+ "string",
+ ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
+ % ("soooo", 2),
}
func_with_keywords(
@@ -123,7 +123,7 @@
old_fmt_string1 = (
"While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it."
- % ("formatting", "code")
+ % ("formatting", "code")
)
old_fmt_string2 = "This is a %s %s %s %s" % (
@@ -135,12 +135,12 @@
old_fmt_string3 = (
"Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s"
- % (
- "really really really really really",
- "old",
- "way to format strings!",
- "Use f-strings instead!",
- )
+ % (
+ "really really really really really",
+ "old",
+ "way to format strings!",
+ "Use f-strings instead!",
+ )
)
fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one."
@@ -165,36 +165,32 @@
@@ -165,13 +165,9 @@
triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched."""
@@ -365,50 +320,6 @@ long_unmergable_string_with_pragma = (
"formatting"
)
assert some_type_of_boolean_expression, (
"Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s."
- % "formatting"
+ % "formatting"
)
assert some_type_of_boolean_expression, (
"Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s."
- % ("string", "formatting")
+ % ("string", "formatting")
)
some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
- + added
- + " to a variable and then added to another string."
+ + added
+ + " to a variable and then added to another string."
)
some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
- + added
- + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
+ + added
+ + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
"and a second argument",
and_a_third,
)
@@ -249,10 +245,10 @@
annotated_variable: Final = (
"This is a large "
- + STRING
- + " that has been "
- + CONCATENATED
- + "using the '+' operator."
+ + STRING
+ + " that has been "
+ + CONCATENATED
+ + "using the '+' operator."
)
annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped."
annotated_variable: Literal[
```
## Ruff Output
@@ -456,11 +367,11 @@ D4 = {
sooo="soooo", x=2
),
"A %s %s"
% (
"formatted",
"string",
): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
% ("soooo", 2),
% (
"formatted",
"string",
): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
% ("soooo", 2),
}
func_with_keywords(
@@ -539,7 +450,7 @@ fmt_string2 = "But what about when the string is {} but {}".format(
old_fmt_string1 = (
"While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it."
% ("formatting", "code")
% ("formatting", "code")
)
old_fmt_string2 = "This is a %s %s %s %s" % (
@@ -551,12 +462,12 @@ old_fmt_string2 = "This is a %s %s %s %s" % (
old_fmt_string3 = (
"Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s"
% (
"really really really really really",
"old",
"way to format strings!",
"Use f-strings instead!",
)
% (
"really really really really really",
"old",
"way to format strings!",
"Use f-strings instead!",
)
)
fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one."
@@ -589,24 +500,24 @@ assert some_type_of_boolean_expression, "Followed by a really really really long
assert some_type_of_boolean_expression, (
"Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s."
% "formatting"
% "formatting"
)
assert some_type_of_boolean_expression, (
"Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s."
% ("string", "formatting")
% ("string", "formatting")
)
some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
+ added
+ " to a variable and then added to another string."
+ added
+ " to a variable and then added to another string."
)
some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
+ added
+ " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
+ added
+ " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
"and a second argument",
and_a_third,
)
@@ -661,10 +572,10 @@ func_with_bad_parens(
annotated_variable: Final = (
"This is a large "
+ STRING
+ " that has been "
+ CONCATENATED
+ "using the '+' operator."
+ STRING
+ " that has been "
+ CONCATENATED
+ "using the '+' operator."
)
annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped."
annotated_variable: Literal[

View File

@@ -95,96 +95,7 @@ def f(
```diff
--- Black
+++ Ruff
@@ -1,17 +1,17 @@
# This has always worked
z = (
Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
)
# "AnnAssign"s now also work
z: (
Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
)
z: Short | Short2 | Short3 | Short4
z: int
@@ -20,9 +20,9 @@
z: (
Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
- | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
+ | Loooooooooooooooooooooooong
) = 7
z: Short | Short2 | Short3 | Short4 = 8
z: int = 2.3
@@ -31,39 +31,39 @@
# In case I go for not enforcing parantheses, this might get improved at the same time
x = (
z
- == 9999999999999999999999999999999999999999
- | 9999999999999999999999999999999999999999
- | 9999999999999999999999999999999999999999
- | 9999999999999999999999999999999999999999,
+ == 9999999999999999999999999999999999999999
+ | 9999999999999999999999999999999999999999
+ | 9999999999999999999999999999999999999999
+ | 9999999999999999999999999999999999999999,
y
- == 9999999999999999999999999999999999999999
- + 9999999999999999999999999999999999999999
- + 9999999999999999999999999999999999999999
- + 9999999999999999999999999999999999999999,
+ == 9999999999999999999999999999999999999999
+ + 9999999999999999999999999999999999999999
+ + 9999999999999999999999999999999999999999
+ + 9999999999999999999999999999999999999999,
)
x = (
z
- == (
- 9999999999999999999999999999999999999999
- | 9999999999999999999999999999999999999999
- | 9999999999999999999999999999999999999999
- | 9999999999999999999999999999999999999999
- ),
+ == (
+ 9999999999999999999999999999999999999999
+ | 9999999999999999999999999999999999999999
+ | 9999999999999999999999999999999999999999
+ | 9999999999999999999999999999999999999999
+ ),
y
- == (
- 9999999999999999999999999999999999999999
- + 9999999999999999999999999999999999999999
- + 9999999999999999999999999999999999999999
- + 9999999999999999999999999999999999999999
- ),
+ == (
+ 9999999999999999999999999999999999999999
+ + 9999999999999999999999999999999999999999
+ + 9999999999999999999999999999999999999999
+ + 9999999999999999999999999999999999999999
+ ),
)
# handle formatting of "tname"s in parameter list
@@ -63,7 +63,7 @@
# remove unnecessary paren
@@ -199,12 +110,14 @@ def f(
i: int,
- x: (
- Loooooooooooooooooooooooong
+ x: Loooooooooooooooooooooooong
| Looooooooooooooooong
| Looooooooooooooooooooong
- | Looooooooooooooooong
- | Looooooooooooooooooooong
- | Looooooong
- ),
+ | Looooooong,
+ x: Loooooooooooooooooooooooong
+ | Looooooooooooooooong
+ | Looooooooooooooooooooong
+ | Looooooong,
*,
s: str,
) -> None:
@@ -225,17 +138,17 @@ def f(
# This has always worked
z = (
Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
)
# "AnnAssign"s now also work
z: (
Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
)
z: Short | Short2 | Short3 | Short4
z: int
@@ -244,9 +157,9 @@ z: int
z: (
Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
| Loooooooooooooooooooooooong
) = 7
z: Short | Short2 | Short3 | Short4 = 8
z: int = 2.3
@@ -255,32 +168,32 @@ z: int = foo()
# In case I go for not enforcing parantheses, this might get improved at the same time
x = (
z
== 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999,
== 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999,
y
== 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999,
== 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999,
)
x = (
z
== (
9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
),
== (
9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
| 9999999999999999999999999999999999999999
),
y
== (
9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
),
== (
9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
+ 9999999999999999999999999999999999999999
),
)
# handle formatting of "tname"s in parameter list
@@ -297,9 +210,9 @@ def foo(i: (int,)) -> None: ...
def foo(
i: int,
x: Loooooooooooooooooooooooong
| Looooooooooooooooong
| Looooooooooooooooooooong
| Looooooong,
| Looooooooooooooooong
| Looooooooooooooooooooong
| Looooooong,
*,
s: str,
) -> None:

View File

@@ -1,75 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_604.py
---
## Input
```python
def some_very_long_name_function() -> my_module.Asdf | my_module.AnotherType | my_module.YetAnotherType | None:
pass
def some_very_long_name_function() -> my_module.Asdf | my_module.AnotherType | my_module.YetAnotherType | my_module.EvenMoreType | None:
pass
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -6,9 +6,9 @@
def some_very_long_name_function() -> (
my_module.Asdf
- | my_module.AnotherType
- | my_module.YetAnotherType
- | my_module.EvenMoreType
- | None
+ | my_module.AnotherType
+ | my_module.YetAnotherType
+ | my_module.EvenMoreType
+ | None
):
pass
```
## Ruff Output
```python
def some_very_long_name_function() -> (
my_module.Asdf | my_module.AnotherType | my_module.YetAnotherType | None
):
pass
def some_very_long_name_function() -> (
my_module.Asdf
| my_module.AnotherType
| my_module.YetAnotherType
| my_module.EvenMoreType
| None
):
pass
```
## Black Output
```python
def some_very_long_name_function() -> (
my_module.Asdf | my_module.AnotherType | my_module.YetAnotherType | None
):
pass
def some_very_long_name_function() -> (
my_module.Asdf
| my_module.AnotherType
| my_module.YetAnotherType
| my_module.EvenMoreType
| None
):
pass
```

View File

@@ -13,14 +13,12 @@ importA;()<<0**0#
```diff
--- Black
+++ Ruff
@@ -1,6 +1,6 @@
importA
@@ -2,5 +2,5 @@
(
()
- << 0
<< 0
- ** 0
+ << 0
+ **0
+ **0
) #
```
@@ -30,8 +28,8 @@ importA;()<<0**0#
importA
(
()
<< 0
**0
<< 0
**0
) #
```

View File

@@ -85,18 +85,21 @@ class Random:
- a_very_long_variable * and_a_very_long_function_call() / 100000.0
- )
+ "a key in my dict": a_very_long_variable
+ * and_a_very_long_function_call()
+ / 100000.0
+ * and_a_very_long_function_call()
+ / 100000.0
}
my_dict = {
- "a key in my dict": (
- a_very_long_variable
+ "a key in my dict": a_very_long_variable
* and_a_very_long_function_call()
* and_another_long_func()
/ 100000.0
- * and_a_very_long_function_call()
- * and_another_long_func()
- / 100000.0
- )
+ "a key in my dict": a_very_long_variable
+ * and_a_very_long_function_call()
+ * and_another_long_func()
+ / 100000.0
}
my_dict = {
@@ -137,15 +140,15 @@ my_dict = {
my_dict = {
"a key in my dict": a_very_long_variable
* and_a_very_long_function_call()
/ 100000.0
* and_a_very_long_function_call()
/ 100000.0
}
my_dict = {
"a key in my dict": a_very_long_variable
* and_a_very_long_function_call()
* and_another_long_func()
/ 100000.0
* and_a_very_long_function_call()
* and_another_long_func()
/ 100000.0
}
my_dict = {

View File

@@ -439,11 +439,11 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
- "This is a really really really long string that has to go inside of a"
- " dictionary. It is %s bad (#%d)." % ("soooo", 2)
- ),
+ % (
+ "formatted",
+ "string",
+ ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
+ % ("soooo", 2),
+ % (
+ "formatted",
+ "string",
+ ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
+ % ("soooo", 2),
}
D5 = { # Test for https://github.com/psf/black/issues/3261
@@ -622,29 +622,22 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
- "While we are on the topic of %s, we should also note that old-style formatting"
- " must also be preserved, since some %s still uses it." % ("formatting", "code")
+ "While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it."
+ % ("formatting", "code")
+ % ("formatting", "code")
)
old_fmt_string2 = "This is a %s %s %s %s" % (
@@ -271,36 +201,23 @@
@@ -271,8 +201,7 @@
)
old_fmt_string3 = (
- "Whereas only the strings after the percent sign were long in the last example,"
- " this example uses a long initial string as well. This is another %s %s %s %s"
- % (
- "really really really really really",
- "old",
- "way to format strings!",
- "Use f-strings instead!",
- )
+ "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s"
+ % (
+ "really really really really really",
+ "old",
+ "way to format strings!",
+ "Use f-strings instead!",
+ )
% (
"really really really really really",
"old",
@@ -281,26 +210,14 @@
)
)
-fstring = (
@@ -695,37 +688,33 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
- "Followed by a really really really long string that is used to provide context to"
- " the AssertionError exception, which uses dynamic string %s." % "formatting"
+ "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s."
+ % "formatting"
+ % "formatting"
)
assert some_type_of_boolean_expression, (
- "Followed by a really really really long string that is used to provide context to"
- " the AssertionError exception, which uses dynamic %s %s."
- % ("string", "formatting")
+ "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s."
+ % ("string", "formatting")
% ("string", "formatting")
)
some_function_call(
- "With a reallly generic name and with a really really long string that is, at some"
- " point down the line, "
- + added
- + " to a variable and then added to another string."
+ "With a reallly generic name and with a really really long string that is, at some point down the line, "
+ + added
+ + " to a variable and then added to another string."
+ added
+ " to a variable and then added to another string."
)
some_function_call(
- "With a reallly generic name and with a really really long string that is, at some"
- " point down the line, "
- + added
+ "With a reallly generic name and with a really really long string that is, at some point down the line, "
+ added
- + " to a variable and then added to another string. But then what happens when the"
- " final string is also supppppperrrrr long?! Well then that second (realllllllly"
- " long) string should be split too.",
+ "With a reallly generic name and with a really really long string that is, at some point down the line, "
+ + added
+ + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
+ + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
"and a second argument",
and_a_third,
)
@@ -783,7 +772,7 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
x,
y,
z,
@@ -397,61 +306,38 @@
@@ -397,7 +306,7 @@
func_with_bad_parens(
x,
y,
@@ -792,21 +781,14 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
z,
)
annotated_variable: Final = (
"This is a large "
- + STRING
- + " that has been "
- + CONCATENATED
- + "using the '+' operator."
-)
@@ -408,50 +317,27 @@
+ CONCATENATED
+ "using the '+' operator."
)
-annotated_variable: Final = (
- "This is a large string that has a type annotation attached to it. A type"
- " annotation should NOT stop a long string from being wrapped."
+ + STRING
+ + " that has been "
+ + CONCATENATED
+ + "using the '+' operator."
)
-)
+annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped."
annotated_variable: Literal["fakse_literal"] = (
- "This is a large string that has a type annotation attached to it. A type"
@@ -928,16 +910,15 @@ log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share
- + ", \n".join(
- " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name)
- for attrname, visit_name in names
- )
- + "\n ]\n"
+ (" return [\n")
+ + (
+ ", \n".join(
+ " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name)
+ for attrname, visit_name in names
+ )
+ + (
+ ", \n".join(
+ " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name)
+ for attrname, visit_name in names
+ )
+ + ("\n ]\n")
)
- + "\n ]\n"
+ + ("\n ]\n")
)
@@ -1047,11 +1028,11 @@ D4 = {
sooo="soooo", x=2
),
"A %s %s"
% (
"formatted",
"string",
): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
% ("soooo", 2),
% (
"formatted",
"string",
): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)."
% ("soooo", 2),
}
D5 = { # Test for https://github.com/psf/black/issues/3261
@@ -1197,7 +1178,7 @@ fmt_string2 = "But what about when the string is {} but {}".format(
old_fmt_string1 = (
"While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it."
% ("formatting", "code")
% ("formatting", "code")
)
old_fmt_string2 = "This is a %s %s %s %s" % (
@@ -1209,12 +1190,12 @@ old_fmt_string2 = "This is a %s %s %s %s" % (
old_fmt_string3 = (
"Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s"
% (
"really really really really really",
"old",
"way to format strings!",
"Use f-strings instead!",
)
% (
"really really really really really",
"old",
"way to format strings!",
"Use f-strings instead!",
)
)
fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one."
@@ -1247,24 +1228,24 @@ assert some_type_of_boolean_expression, "Followed by a really really really long
assert some_type_of_boolean_expression, (
"Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s."
% "formatting"
% "formatting"
)
assert some_type_of_boolean_expression, (
"Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s."
% ("string", "formatting")
% ("string", "formatting")
)
some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
+ added
+ " to a variable and then added to another string."
+ added
+ " to a variable and then added to another string."
)
some_function_call(
"With a reallly generic name and with a really really long string that is, at some point down the line, "
+ added
+ " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
+ added
+ " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.",
"and a second argument",
and_a_third,
)
@@ -1319,10 +1300,10 @@ func_with_bad_parens(
annotated_variable: Final = (
"This is a large "
+ STRING
+ " that has been "
+ CONCATENATED
+ "using the '+' operator."
+ STRING
+ " that has been "
+ CONCATENATED
+ "using the '+' operator."
)
annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped."
annotated_variable: Literal["fakse_literal"] = (
@@ -1391,13 +1372,13 @@ dict_with_lambda_values = {
# Complex string concatenations with a method call in the middle.
code = (
(" return [\n")
+ (
", \n".join(
" (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name)
for attrname, visit_name in names
)
+ (
", \n".join(
" (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name)
for attrname, visit_name in names
)
+ ("\n ]\n")
)
+ ("\n ]\n")
)

View File

@@ -99,19 +99,18 @@ msg += "This long string should not be split at any point ever since it is just
some_string_inside_a_variable
- + "Some string that is just long enough to cause a split to take"
- " place.............",
+ + "Some string that is just long enough to cause a split to take place.............",
+ + "Some string that is just long enough to cause a split to take place.............",
xyz,
- "Some really long string that needs to get split eventually but I'm running out of"
- " things to say"
- + some_string_inside_a_variable,
+ "Some really long string that needs to get split eventually but I'm running out of things to say"
+ + some_string_inside_a_variable,
+ some_string_inside_a_variable,
)
addition_inside_tuple = (
some_string_inside_a_variable
- + "Some string that is just long enough to cause a split to take"
- " place.............."
+ + "Some string that is just long enough to cause a split to take place.............."
+ + "Some string that is just long enough to cause a split to take place.............."
)
return (
"Hi there. This is areally really reallllly long string that needs to be split!!!"
@@ -132,21 +131,20 @@ msg += "This long string should not be split at any point ever since it is just
str(result)
- == "This long string should be split at some point right close to or around"
- " hereeeeeee"
+ == "This long string should be split at some point right close to or around hereeeeeee"
+ == "This long string should be split at some point right close to or around hereeeeeee"
)
assert (
str(result)
- < "This long string should be split at some point right close to or around"
- " hereeeeee"
+ < "This long string should be split at some point right close to or around hereeeeee"
+ < "This long string should be split at some point right close to or around hereeeeee"
)
assert (
"A format string: %s"
- % "This long string should be split at some point right close to or around"
- " hereeeeeee"
- != result
+ % "This long string should be split at some point right close to or around hereeeeeee"
+ != result
+ % "This long string should be split at some point right close to or around hereeeeeee"
!= result
)
msg += (
"This long string should be wrapped in parens at some point right around hereeeee"
@@ -195,14 +193,14 @@ some_variable = (
)
addition_inside_tuple = (
some_string_inside_a_variable
+ "Some string that is just long enough to cause a split to take place.............",
+ "Some string that is just long enough to cause a split to take place.............",
xyz,
"Some really long string that needs to get split eventually but I'm running out of things to say"
+ some_string_inside_a_variable,
+ some_string_inside_a_variable,
)
addition_inside_tuple = (
some_string_inside_a_variable
+ "Some string that is just long enough to cause a split to take place.............."
+ "Some string that is just long enough to cause a split to take place.............."
)
return (
"Hi there. This is areally really reallllly long string that needs to be split!!!"
@@ -218,16 +216,16 @@ return (
return f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa"
assert (
str(result)
== "This long string should be split at some point right close to or around hereeeeeee"
== "This long string should be split at some point right close to or around hereeeeeee"
)
assert (
str(result)
< "This long string should be split at some point right close to or around hereeeeee"
< "This long string should be split at some point right close to or around hereeeeee"
)
assert (
"A format string: %s"
% "This long string should be split at some point right close to or around hereeeeeee"
!= result
% "This long string should be split at some point right close to or around hereeeeeee"
!= result
)
msg += (
"This long string should be wrapped in parens at some point right around hereeeee"

View File

@@ -660,7 +660,7 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- " on one line at alllll." % "formatting",
+ (
+ "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll."
+ % "formatting"
+ % "formatting"
+ ),
)
@@ -669,7 +669,7 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- " one line at alllll." % ("formatting", "string"),
+ (
+ "A long string with {}. This {} is so long that it is ridiculous. It can't fit on one line at alllll."
+ % ("formatting", "string")
+ % ("formatting", "string")
+ ),
)
@@ -688,17 +688,17 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- xxxx.xxxxxxxxxxxxxx(xx),
+ (
+ "xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx"
+ % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx)
)
+ + (
+ " %.3f (%s) to %.3f (%s).\n"
+ % (
+ xxxx.xxxxxxxxx,
+ xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx),
+ x,
+ xxxx.xxxxxxxxxxxxxx(xx),
+ )
+ % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx)
+ )
+ + (
+ " %.3f (%s) to %.3f (%s).\n"
+ % (
+ xxxx.xxxxxxxxx,
+ xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx),
+ x,
+ xxxx.xxxxxxxxxxxxxx(xx),
+ )
)
)
@@ -777,9 +777,9 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx"
- .xxxxxx(xxxxxx_xxxxxx_xxx)
+ "xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx xxxxxxx "
+ + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx".xxxxxx(
+ xxxxxx_xxxxxx_xxx
+ )
+ + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx".xxxxxx(
+ xxxxxx_xxxxxx_xxx
+ )
)
@@ -832,7 +832,7 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
some_commented_string = ( # This comment stays at the top.
"This string is long but not so long that it needs hahahah toooooo be so greatttt"
@@ -279,37 +280,26 @@
@@ -279,36 +280,25 @@
)
lpar_and_rpar_have_comments = func_call( # LPAR Comment
@@ -852,33 +852,32 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- f" {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'"
-)
+cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'"
+
+cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'"
-cmd_fstring = (
- "sudo -E deluge-console info --detailed --sort-reverse=time_added"
- f" {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'"
-)
+cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {{'' if ID is None else ID}} | perl -nE 'print if /^{field}:/'"
+cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'"
-cmd_fstring = (
- "sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is"
- f" None else ID}} | perl -nE 'print if /^{field}:/'"
-)
+fstring = f"This string really doesn't need to be an {{{{fstring}}}}, but this one most certainly, absolutely {does}."
+cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {{'' if ID is None else ID}} | perl -nE 'print if /^{field}:/'"
+fstring = f"This string really doesn't need to be an {{{{fstring}}}}, but this one most certainly, absolutely {does}."
+
fstring = (
- "This string really doesn't need to be an {{fstring}}, but this one most"
- f" certainly, absolutely {does}."
+ f"We have to remember to escape {braces}." " Like {these}." f" But not {this}."
)
-fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}."
-
-fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}."
class A:
class B:
@@ -364,11 +354,8 @@
@@ -364,10 +354,7 @@
def foo():
if not hasattr(module, name):
raise ValueError(
@@ -886,12 +885,10 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- " serialize things like inner classes. Please move the object into"
- " the main module body to use migrations.\nFor more information,"
- " see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"
- % (name, module_name, get_docs_version())
+ "Could not find object %s in %s.\nPlease note that you cannot serialize things like inner classes. Please move the object into the main module body to use migrations.\nFor more information, see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"
+ % (name, module_name, get_docs_version())
% (name, module_name, get_docs_version())
)
@@ -382,23 +369,19 @@
class Step(StepBase):
@@ -930,19 +927,10 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk"
- r" '{print $2}'); do kill $pid; done" % (i)
+ r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk '{print $2}'); do kill $pid; done"
+ % (i)
+ % (i)
)
@@ -423,7 +406,7 @@
def G():
assert (
c_float(val[0][0] / val[0][1]).value
- == c_float(value[0][0] / value[0][1]).value
+ == c_float(value[0][0] / value[0][1]).value
), "%s didn't roundtrip" % tag
@@ -432,9 +415,7 @@
assert xxxxxxx_xxxx in [
x.xxxxx.xxxxxx.xxxxx.xxxxxx,
@@ -1048,14 +1036,14 @@ s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:
- in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$',"
- " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$',"
- " 'ykangaroo$']"
+ in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
+ in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
)
assert (
str(suffix_arr)
- not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$',"
- " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$',"
- " 'rykangaroo$', 'ykangaroo$']"
+ not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
+ not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
)
message = (
f"1. Go to Google Developers Console and log in with your Google account."
@@ -1335,14 +1323,14 @@ func_call_where_string_arg_has_method_call_and_bad_parens(
func_call_where_string_arg_has_old_fmt_and_bad_parens(
(
"A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll."
% "formatting"
% "formatting"
),
)
func_call_where_string_arg_has_old_fmt_and_bad_parens(
(
"A long string with {}. This {} is so long that it is ridiculous. It can't fit on one line at alllll."
% ("formatting", "string")
% ("formatting", "string")
),
)
@@ -1353,17 +1341,17 @@ class A:
xxxx.xxxxxxx.xxxxx(
(
"xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx"
% (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx)
% (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx)
)
+ (
" %.3f (%s) to %.3f (%s).\n"
% (
xxxx.xxxxxxxxx,
xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx),
x,
xxxx.xxxxxxxxxxxxxx(xx),
)
+ (
" %.3f (%s) to %.3f (%s).\n"
% (
xxxx.xxxxxxxxx,
xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx),
x,
xxxx.xxxxxxxxxxxxxx(xx),
)
)
)
@@ -1413,9 +1401,9 @@ class A:
if True:
xxxxx_xxxxxxxxxxxx(
"xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx xxxxxxx "
+ "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx".xxxxxx(
xxxxxx_xxxxxx_xxx
)
+ "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx".xxxxxx(
xxxxxx_xxxxxx_xxx
)
)
@@ -1566,7 +1554,7 @@ class A:
if not hasattr(module, name):
raise ValueError(
"Could not find object %s in %s.\nPlease note that you cannot serialize things like inner classes. Please move the object into the main module body to use migrations.\nFor more information, see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"
% (name, module_name, get_docs_version())
% (name, module_name, get_docs_version())
)
@@ -1604,7 +1592,7 @@ if __name__ == "__main__":
for i in range(4, 8):
cmd = (
r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk '{print $2}'); do kill $pid; done"
% (i)
% (i)
)
@@ -1617,7 +1605,7 @@ def A():
def G():
assert (
c_float(val[0][0] / val[0][1]).value
== c_float(value[0][0] / value[0][1]).value
== c_float(value[0][0] / value[0][1]).value
), "%s didn't roundtrip" % tag
@@ -1737,11 +1725,11 @@ assert str(suffix_arr) > (
)
assert (
str(suffix_arr)
in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
)
assert (
str(suffix_arr)
not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']"
)
message = (
f"1. Go to Google Developers Console and log in with your Google account."

View File

@@ -201,7 +201,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """dove
+ coo"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
)
call(
@@ -212,7 +212,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """dove
+coo"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
)
call(
@@ -222,7 +222,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """cow
+ moo"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
"dogsay",
)
@@ -234,7 +234,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """crow
+ caw"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
)
call(
@@ -244,7 +244,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """cat
+ meow"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
{"dog", "say"},
)
@@ -256,7 +256,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """horse
+ neigh"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
)
call(
@@ -267,7 +267,7 @@ this_will_also_become_one_line = ( # comment
+ textwrap.dedent(
+ """pig
+ oink"""
+ % "cowabunga"
+ % "cowabunga"
+ ),
)
textwrap.dedent("""A one-line triple-quoted string.""")
@@ -391,7 +391,7 @@ call(
textwrap.dedent(
"""dove
coo"""
% "cowabunga"
% "cowabunga"
),
)
call(
@@ -400,7 +400,7 @@ call(
textwrap.dedent(
"""dove
coo"""
% "cowabunga"
% "cowabunga"
),
)
call(
@@ -408,7 +408,7 @@ call(
textwrap.dedent(
"""cow
moo"""
% "cowabunga"
% "cowabunga"
),
"dogsay",
)
@@ -418,7 +418,7 @@ call(
textwrap.dedent(
"""crow
caw"""
% "cowabunga"
% "cowabunga"
),
)
call(
@@ -426,7 +426,7 @@ call(
textwrap.dedent(
"""cat
meow"""
% "cowabunga"
% "cowabunga"
),
{"dog", "say"},
)
@@ -436,7 +436,7 @@ call(
textwrap.dedent(
"""horse
neigh"""
% "cowabunga"
% "cowabunga"
),
)
call(
@@ -445,7 +445,7 @@ call(
textwrap.dedent(
"""pig
oink"""
% "cowabunga"
% "cowabunga"
),
)
textwrap.dedent("""A one-line triple-quoted string.""")

View File

@@ -1,354 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py
---
## Input
```python
a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
b = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
c = 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1
d = 1**1 ** 1**1 ** 1**1 ** 1**1 ** 1**1**1 ** 1 ** 1**1 ** 1**1**1**1**1 ** 1 ** 1**1**1 **1**1** 1 ** 1 ** 1
e = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟
f = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟
a = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
b = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
c = 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0
d = 1.0**1.0 ** 1.0**1.0 ** 1.0**1.0 ** 1.0**1.0 ** 1.0**1.0**1.0 ** 1.0 ** 1.0**1.0 ** 1.0**1.0**1.0
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,83 +1,83 @@
a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
b = (
1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
- ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
+ ** 1
)
c = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
d = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
e = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟
f = (
𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
- ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
+ ** 𨉟
)
a = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
b = (
1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
- ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
+ ** 1.0
)
c = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
d = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
```
## Ruff Output
```python
a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
b = (
1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
)
c = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
d = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
e = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟
f = (
𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
)
a = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
b = (
1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
)
c = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
d = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
```
## Black Output
```python
a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
b = (
1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
** 1
)
c = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
d = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1
e = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟
f = (
𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
** 𨉟
)
a = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
b = (
1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
** 1.0
)
c = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
d = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0
```

View File

@@ -129,15 +129,6 @@ a = (
some_kind_of_table[
some_key # type: ignore # noqa: E501
@@ -79,7 +77,7 @@
# Right side of assignment contains un-nested pairs of inner parens.
some_kind_of_instance.some_kind_of_map[a_key] = (
isinstance(some_var, SomeClass)
- and table.something_and_something != table.something_else
+ and table.something_and_something != table.something_else
) or (
isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing
)
```
## Ruff Output
@@ -222,7 +213,7 @@ xxxxxxxxx_yyy_zzzzzzzz[
# Right side of assignment contains un-nested pairs of inner parens.
some_kind_of_instance.some_kind_of_map[a_key] = (
isinstance(some_var, SomeClass)
and table.something_and_something != table.something_else
and table.something_and_something != table.something_else
) or (
isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing
)

View File

@@ -127,24 +127,6 @@ def foo(a,b) -> tuple[int, int, int,]:
return 2 * a
@@ -45,7 +53,7 @@
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
- | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
+ | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
@@ -64,7 +72,7 @@
c: int,
) -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
- | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
+ | intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
@@ -124,5 +132,9 @@
# this is broken - the trailing comma is transferred to the param list. Fixed in preview
def foo(
@@ -216,7 +198,7 @@ def foo() -> (
def foo() -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2
@@ -235,7 +217,7 @@ def foo(
c: int,
) -> (
intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
| intsdfsafafafdfdsasdfsfsdfasdfafdsafdfdsfasdskdsdsfdsafdsafsdfdasfffsfdsfdsafafhdskfhdsfjdslkfdlfsdkjhsdfjkdshfkljds
):
return 2

View File

@@ -41,14 +41,12 @@ assert (
```diff
--- Black
+++ Ruff
@@ -1,8 +1,8 @@
importA
@@ -2,7 +2,7 @@
(
()
- << 0
<< 0
- ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525
+ << 0
+ **101234234242352525425252352352525234890264906820496920680926538059059209922523523525
+ **101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert sort_by_dependency(
@@ -72,8 +70,8 @@ assert (
importA
(
()
<< 0
**101234234242352525425252352352525234890264906820496920680926538059059209922523523525
<< 0
**101234234242352525425252352352525234890264906820496920680926538059059209922523523525
) #
assert sort_by_dependency(

View File

@@ -1,129 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens1.py
---
## Input
```python
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
@@ -11,7 +11,7 @@
Vegetable.objects.order_by("-id")[0].id,
Mineral.objects.order_by("-id")[0].id,
)
- + 1
+ + 1
)
```
## Ruff Output
```python
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
```python
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,59 +0,0 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens3.py
---
## Input
```python
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -3,6 +3,6 @@
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
- + "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
+ + "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}
```
## Ruff Output
```python
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}
```
## Black Output
```python
if True:
if True:
if True:
return _(
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
+ "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
"qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
) % {"reported_username": reported_username, "report_reason": report_reason}
```

View File

@@ -56,12 +56,7 @@ assert xxxxxxxxx.xxxxxxxxx.xxxxxxxxx(
# Example from https://github.com/psf/black/issues/3229
@@ -39,12 +37,10 @@
# 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)
+ == long_module.long_class.long_func()["some_key"].another_func(arg1)
@@ -43,8 +41,6 @@
)
# Regression test for https://github.com/psf/black/issues/3414.
@@ -117,7 +112,7 @@ def refresh_token(self, device_family, refresh_token, api_key):
# 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)
== long_module.long_class.long_func()["some_key"].another_func(arg1)
)
# Regression test for https://github.com/psf/black/issues/3414.

View File

@@ -292,7 +292,7 @@ x6 = (
# Regression test for: https://github.com/astral-sh/ruff/issues/7370
result = (
f(111111111111111111111111111111111111111111111111111111111111111111111111111111111)
+ 1
+ 1
).bit_length()
```

View File

@@ -78,20 +78,20 @@ result = await self.request(
result = await (
1
+ f(
1,
2,
3,
)
+ f(
1,
2,
3,
)
)
result = await (
1
+ f(
1,
2,
3,
)
+ f(
1,
2,
3,
)
)
# Optional parentheses.

View File

@@ -430,28 +430,28 @@ if True:
```python
(
aaaaaaaa
+ # trailing operator comment
b # trailing right comment
+ # trailing operator comment
b # trailing right comment
)
(
aaaaaaaa # trailing left comment
+ # trailing operator comment
# leading right comment
b
+ # trailing operator comment
# leading right comment
b
)
(
# leading left most comment
aaaaaaaa
+ # trailing operator comment
# leading b comment
b # trailing b comment
# trailing b ownline comment
+ # trailing second operator comment
# leading c comment
c # trailing c comment
+ # trailing operator comment
# leading b comment
b # trailing b comment
# trailing b ownline comment
+ # trailing second operator comment
# leading c comment
c # trailing c comment
# trailing own line comment
)
@@ -497,24 +497,21 @@ aaaaaaaaaaaaaa + {
# Wraps it in parentheses if it needs to break both left and right
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ [bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eee]
+ [bbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccc, dddddddddddddddd, eee]
) # comment
# But only for expressions that have a statement parent.
not (
aaaaaaaaaaaaaa
+ {
a
for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
}
+ {a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb}
)
[
a
+ [
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
]
in c
+ [
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
]
in c
]
@@ -527,13 +524,13 @@ not (
if (
aaaaaaaaaaaaaaaaaa
+
# has the child process finished?
bbbbbbbbbbbbbbb
+
# the child process has finished, but the
# transport hasn't been notified yet?
ccccccccccc
+
# has the child process finished?
bbbbbbbbbbbbbbb
+
# the child process has finished, but the
# transport hasn't been notified yet?
ccccccccccc
):
pass
@@ -556,7 +553,7 @@ if (
dddddddddddddddddddd,
eeeeeeeeee,
]
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
pass
@@ -572,13 +569,13 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaa & [
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& [
aaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbb,
cccccccccccccccccccc,
dddddddddddddddddddd,
eeeeeeeeee,
]
& [
aaaaaaaaaaaaa,
bbbbbbbbbbbbbbbbbbbb,
cccccccccccccccccccc,
dddddddddddddddddddd,
eeeeeeeeee,
]
):
pass
@@ -677,9 +674,9 @@ if (
iiiiiiiiiiiiiiii,
jjjjjjjjjjjjj,
]
&
# comment
a + b
&
# comment
a + b
):
pass
@@ -696,14 +693,14 @@ for user_id in set(target_user_ids) - {u.user_id for u in updates}:
# Keeps parenthesized left hand sides
(
log(self.price / self.strike)
+ (self.risk_free - self.div_cont + 0.5 * (self.sigma**2)) * self.exp_time
+ (self.risk_free - self.div_cont + 0.5 * (self.sigma**2)) * self.exp_time
) / self.sigmaT
# Stability with end-of-line comments between empty tuples and bin op
x = (
()
- ( #
)
- ( #
)
)
x = (
() - () #
@@ -732,10 +729,10 @@ expected_content = (
</sitemapindex>
"""
# Needs parentheses
% (
self.base_url,
date.today(),
)
% (
self.base_url,
date.today(),
)
)
expected_content = (
@@ -745,12 +742,12 @@ expected_content = (
</sitemap>
</sitemapindex>
"""
%
# Needs parentheses
(
self.base_url,
date.today(),
)
%
# Needs parentheses
(
self.base_url,
date.today(),
)
)
@@ -771,8 +768,8 @@ expected_content = (
</sitemap>
</sitemapindex>
"""
+ sssssssssssssssssssssssssssssssssssssssssooooo
* looooooooooooooooooooooooooooooongggggggggggg
+ sssssssssssssssssssssssssssssssssssssssssooooo
* looooooooooooooooooooooooooooooongggggggggggg
)
call(
@@ -799,10 +796,10 @@ expected_content = (
</sitemap>
</sitemapindex>
"""
% (
# Needs parentheses
self.base_url
)
% (
# Needs parentheses
self.base_url
)
)
# Skip FString content when determining whether to omit optional parentheses or not.0
@@ -810,7 +807,7 @@ expected_content = (
# (Call expressions at the beginning don't count as parenthesized because they don't start with parens).
assert (
format.format_event(spec)
== f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})'
== f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})'
)
# Avoid parentheses for this example because it starts with a tuple expression.
assert (
@@ -820,62 +817,62 @@ assert (
rowuses = [
(1 << j) # column ordinal
| (1 << (n + i - j + n - 1)) # NW-SE ordinal
| (1 << (n + 2 * n - 1 + i + j)) # NE-SW ordinal
| (1 << (n + i - j + n - 1)) # NW-SE ordinal
| (1 << (n + 2 * n - 1 + i + j)) # NE-SW ordinal
for j in rangen
]
rowuses = [
(1 << j) # column ordinal
|
# comment
(1 << (n + i - j + n - 1)) # NW-SE ordinal
| (1 << (n + 2 * n - 1 + i + j)) # NE-SW ordinal
|
# comment
(1 << (n + i - j + n - 1)) # NW-SE ordinal
| (1 << (n + 2 * n - 1 + i + j)) # NE-SW ordinal
for j in rangen
]
skip_bytes = (
header.timecnt * 5 # Transition times and types
+ header.typecnt * 6 # Local time type records
+ header.charcnt # Time zone designations
+ header.leapcnt * 8 # Leap second records
+ header.isstdcnt # Standard/wall indicators
+ header.isutcnt # UT/local indicators
+ header.typecnt * 6 # Local time type records
+ header.charcnt # Time zone designations
+ header.leapcnt * 8 # Leap second records
+ header.isstdcnt # Standard/wall indicators
+ header.isutcnt # UT/local indicators
)
if (
(1 + 2) # test
or (3 + 4) # other
or (4 + 5) # more
or (3 + 4) # other
or (4 + 5) # more
):
pass
if (
(1 and 2) # test
+ (3 and 4) # other
+ (4 and 5) # more
+ (3 and 4) # other
+ (4 and 5) # more
):
pass
if (
(1 + 2) # test
< (3 + 4) # other
> (4 + 5) # more
< (3 + 4) # other
> (4 + 5) # more
):
pass
z = (
a
+
# a: extracts this comment
# b: and this comment
(
# c: formats it as part of the expression
x and y
)
+
# a: extracts this comment
# b: and this comment
(
# c: formats it as part of the expression
x and y
)
)
z = (
@@ -885,7 +882,7 @@ z = (
)
# b: extracts this comment
# c: and this comment
+ a
+ a
)
# Test for https://github.com/astral-sh/ruff/issues/7431

View File

@@ -252,8 +252,8 @@ def test():
),
"post_processed": (
collected["post_processed"]
and ", %s post-processed" % post_processed_count
or ""
and ", %s post-processed" % post_processed_count
or ""
),
}

View File

@@ -198,37 +198,37 @@ if (self._proc
if (
self._proc
# has the child process finished?
and self._returncode
# the child process has finished, but the
# transport hasn't been notified yet?
and self._proc.poll()
and self._returncode
# the child process has finished, but the
# transport hasn't been notified yet?
and self._proc.poll()
):
pass
if (
self._proc
and self._returncode
and self._proc.poll()
and self._proc
and self._returncode
and self._proc.poll()
and self._returncode
and self._proc.poll()
and self._proc
and self._returncode
and self._proc.poll()
):
pass
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
pass
if (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas
and aaaaaaaaaaaaaaaaa
and aaaaaaaaaaaaaaaaa
):
pass
@@ -254,61 +254,61 @@ if [
# Break right only applies for boolean operations with a left and right side
if (
aaaaaaaaaaaaaaaaaaaaaaaaaa
and bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
and ccccccccccccccccc
and [dddddddddddddd, eeeeeeeeee, fffffffffffffff]
and bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
and ccccccccccccccccc
and [dddddddddddddd, eeeeeeeeee, fffffffffffffff]
):
pass
# Regression test for https://github.com/astral-sh/ruff/issues/6068
if not (
isinstance(aaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)
or numpy
and isinstance(ccccccccccc, dddddd)
or numpy
and isinstance(ccccccccccc, dddddd)
):
pass
if not (
isinstance(aaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)
and numpy
or isinstance(ccccccccccc, dddddd)
and numpy
or isinstance(ccccccccccc, dddddd)
):
pass
if not (
isinstance(aaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)
or xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
and isinstance(ccccccccccc, dddddd)
or xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
and isinstance(ccccccccccc, dddddd)
):
pass
if not (
isinstance(aaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)
and xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
or isinstance(ccccccccccc, dddddd)
and xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
or isinstance(ccccccccccc, dddddd)
):
pass
if not (
isinstance(aaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)
or (
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
)
and isinstance(ccccccccccc, dddddd)
or (
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
)
and isinstance(ccccccccccc, dddddd)
):
pass
if not (
isinstance(aaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)
and (
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
)
or isinstance(ccccccccccc, dddddd)
and (
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
)
or isinstance(ccccccccccc, dddddd)
):
pass
@@ -322,8 +322,8 @@ def test():
if "_continue" in request.POST or (
# Redirecting after "Save as new".
"_saveasnew" in request.POST
and self.save_as_continue
and self.has_change_permission(request, obj)
and self.save_as_continue
and self.has_change_permission(request, obj)
):
pass
@@ -333,7 +333,7 @@ if True:
if True:
if (
self.validate_max
and self.total_form_count() - len(self.deleted_forms) > self.max_num
and self.total_form_count() - len(self.deleted_forms) > self.max_num
) or self.management_form.cleaned_data[
TOTAL_FORM_COUNT
] > self.absolute_max:
@@ -343,18 +343,15 @@ if True:
if True:
if (
reference_field_name is None
or
# Unspecified to_field(s).
to_fields is None
or
# Reference to primary key.
(
None in to_fields
and (reference_field is None or reference_field.primary_key)
)
or
# Reference to field.
reference_field_name in to_fields
or
# Unspecified to_field(s).
to_fields is None
or
# Reference to primary key.
(None in to_fields and (reference_field is None or reference_field.primary_key))
or
# Reference to field.
reference_field_name in to_fields
):
pass
@@ -362,9 +359,9 @@ if True:
field = opts.get_field(name)
if (
field.is_relation
and
# Generic foreign keys OR reverse relations
((field.many_to_one and not field.related_model) or field.one_to_many)
and
# Generic foreign keys OR reverse relations
((field.many_to_one and not field.related_model) or field.one_to_many)
):
pass
@@ -372,35 +369,35 @@ if (
if True:
return (
filtered.exists()
and
# It may happen that the object is deleted from the DB right after
# this check, causing the subsequent UPDATE to return zero matching
# rows. The same result can occur in some rare cases when the
# database returns zero despite the UPDATE being executed
# successfully (a row is matched and updated). In order to
# distinguish these two cases, the object's existence in the
# database is again checked for if the UPDATE query returns 0.
(filtered._update(values) > 0 or filtered.exists())
and
# It may happen that the object is deleted from the DB right after
# this check, causing the subsequent UPDATE to return zero matching
# rows. The same result can occur in some rare cases when the
# database returns zero despite the UPDATE being executed
# successfully (a row is matched and updated). In order to
# distinguish these two cases, the object's existence in the
# database is again checked for if the UPDATE query returns 0.
(filtered._update(values) > 0 or filtered.exists())
)
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
# 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
if (
self._proc
# has the child process finished?
* self._returncode
# the child process has finished, but the
# transport hasn't been notified yet?
+ self._proc.poll()
* self._returncode
# the child process has finished, but the
# transport hasn't been notified yet?
+ self._proc.poll()
):
pass
```

View File

@@ -320,7 +320,7 @@ f(
100000 - 100000000000
),
these_arguments_have_values_that_need_to_break_because_they_are_too_long2="akshfdlakjsdfad"
+ "asdfasdfa",
+ "asdfasdfa",
these_arguments_have_values_that_need_to_break_because_they_are_too_long3=session,
)
@@ -543,14 +543,14 @@ f( # a
# f
*args2
# g
** # h
kwargs,
** # h
kwargs,
)
# Regression test for: https://github.com/astral-sh/ruff/issues/7370
result = (
f(111111111111111111111111111111111111111111111111111111111111111111111111111111111)
+ 1
+ 1
)()

View File

@@ -201,14 +201,14 @@ a not in b
(
a
==
# comment
b
==
# comment
b
)
(
a # comment
== b
== b
)
a < b > c == d
@@ -270,25 +270,25 @@ return 1 == 2 and (
self_meta_data,
self_schedule,
)
== (
name,
description,
other_default,
othr_selected,
othr_auto_generated,
othr_parameters,
othr_meta_data,
othr_schedule,
)
== (
name,
description,
other_default,
othr_selected,
othr_auto_generated,
othr_parameters,
othr_meta_data,
othr_schedule,
)
)
[
(
a
+ [
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
]
>= c
+ [
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
]
>= c
)
]
@@ -296,7 +296,7 @@ return 1 == 2 and (
def f():
return (
unicodedata.normalize("NFKC", s1).casefold()
== unicodedata.normalize("NFKC", s2).casefold()
== unicodedata.normalize("NFKC", s2).casefold()
)
@@ -336,7 +336,7 @@ ct_match = (aaaaaaaaaaaaaaaa) == self.get_content_type(
ct_match = (
aaaaaaaaaaact_id
== self.get_content_type[obj, rel_obj, using, instance._state.db].id
== self.get_content_type[obj, rel_obj, using, instance._state.db].id
)
ct_match = {aaaaaaaaaaaaaaaa} == self.get_content_type[
@@ -351,10 +351,10 @@ ct_match = (aaaaaaaaaaaaaaaa) == self.get_content_type[
c = (
1 # 1
>
# 2
3 # 3 # 4
> 5 # 5
>
# 2
3 # 3 # 4
> 5 # 5
# 6
)

View File

@@ -224,18 +224,18 @@ query = {
{
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ [
dddddddddddddddddd,
eeeeeeeeeeeeeeeeeee,
]: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ [
dddddddddddddddddd,
eeeeeeeeeeeeeeeeeee,
]: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
for ccccccccccccccccccccccccccccccccccccccc, ddddddddddddddddddd, [
eeeeeeeeeeeeeeeeeeeeee,
fffffffffffffffffffffffff,
] in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd
if fffffffffffffffffffffffffffffffffffffffffff
< gggggggggggggggggggggggggggggggggggggggggggggg
< hhhhhhhhhhhhhhhhhhhhhhhhhh
< gggggggggggggggggggggggggggggggggggggggggggggg
< hhhhhhhhhhhhhhhhhhhhhhhhhh
if gggggggggggggggggggggggggggggggggggggggggggg
}

View File

@@ -219,9 +219,9 @@ def something():
NamedValuesListIterable
if named
else FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
if flat
else ValuesListIterable
)
@@ -233,9 +233,9 @@ def something():
if named
else (
FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
+ FlatValuesListIterable
if flat
else ValuesListIterable
)

View File

@@ -152,15 +152,15 @@ aaaaaaaaaaaaaaaaaaaaa = [
[
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee]
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee]
for ccccccccccccccccccccccccccccccccccccccc, ddddddddddddddddddd, [
eeeeeeeeeeeeeeeeeeeeee,
fffffffffffffffffffffffff,
] in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd
if fffffffffffffffffffffffffffffffffffffffffff
< gggggggggggggggggggggggggggggggggggggggggggggg
< hhhhhhhhhhhhhhhhhhhhhhhhhh
< gggggggggggggggggggggggggggggggggggggggggggggg
< hhhhhhhhhhhhhhhhhhhhhhhhhh
if gggggggggggggggggggggggggggggggggggggggggggg
]
@@ -248,7 +248,7 @@ aaaaaaaaaaaaaaaaaaaaa = [
[
1
for components in b # pylint: disable=undefined-loop-variable # integer 1 may only have decimal 01-09
+ c # negative decimal
+ c # negative decimal
]
# Parenthesized targets and iterators.

View File

@@ -100,15 +100,15 @@ selected_choices = {
{
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee]
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ [dddddddddddddddddd, eeeeeeeeeeeeeeeeeee]
for ccccccccccccccccccccccccccccccccccccccc, ddddddddddddddddddd, [
eeeeeeeeeeeeeeeeeeeeee,
fffffffffffffffffffffffff,
] in eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffggggggggggggggggggggghhhhhhhhhhhhhhothermoreeand_even_moreddddddddddddddddddddd
if fffffffffffffffffffffffffffffffffffffffffff
< gggggggggggggggggggggggggggggggggggggggggggggg
< hhhhhhhhhhhhhhhhhhhhhhhhhh
< gggggggggggggggggggggggggggggggggggggggggggggg
< hhhhhhhhhhhhhhhhhhhhhhhhhh
if gggggggggggggggggggggggggggggggggggggggggggg
}

View File

@@ -217,7 +217,7 @@ g2 = "g"[(1):(2):(3)]
def f():
return (
package_version is not None
and package_version.split(".")[:2] == package_info.version.split(".")[:2]
and package_version.split(".")[:2] == package_info.version.split(".")[:2]
)

View File

@@ -101,12 +101,12 @@ response = await sync_to_async(
# Expressions with empty parentheses.
ct_match = (
unicodedata.normalize("NFKC", s1).casefold()
== unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
== unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
)
ct_match = (
unicodedata.normalize("NFKC", s1).casefold(1)
== unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
== unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
)
ct_match = unicodedata.normalize("NFKC", s1).casefold(0) == unicodedata.normalize(
@@ -121,19 +121,19 @@ ct_match = (
unicodedata.normalize("NFKC", s1).casefold(
# foo
)
== unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold(
# foo
)
== unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold(
# foo
)
)
ct_match = (
[].unicodedata.normalize("NFKC", s1).casefold()
== [].unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
== [].unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
)
ct_match = (
[].unicodedata.normalize("NFKC", s1).casefold()
== [1].unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
== [1].unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
)
ct_match = [1].unicodedata.normalize("NFKC", s1).casefold() == [].unicodedata.normalize(
@@ -146,12 +146,12 @@ ct_match = [1].unicodedata.normalize("NFKC", s1).casefold() == [
ct_match = (
{}.unicodedata.normalize("NFKC", s1).casefold()
== {}.unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
== {}.unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
)
ct_match = (
{}.unicodedata.normalize("NFKC", s1).casefold()
== {1}.unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
== {1}.unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold()
)
ct_match = {1}.unicodedata.normalize("NFKC", s1).casefold() == {}.unicodedata.normalize(

View File

@@ -16,7 +16,7 @@ result = (
# Regression test for: https://github.com/astral-sh/ruff/issues/7370
result = (
f(111111111111111111111111111111111111111111111111111111111111111111111111111111111)
+ 1
+ 1
)[0]
```

View File

@@ -205,7 +205,7 @@ def foo():
```python
if (
not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -221,7 +221,7 @@ b = 10
if not (
# comment
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -229,14 +229,14 @@ if not (
if ~(
# comment
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
if -(
# comment
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -244,14 +244,14 @@ if -(
if +(
# comment
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
if (
# comment
not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -259,14 +259,14 @@ if (
if (
# comment
~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
if (
# comment
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -274,7 +274,7 @@ if (
if (
# comment
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -286,21 +286,21 @@ if (
not (
# comment
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)
):
pass
if not (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & (
not (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)
):
pass
@@ -308,9 +308,9 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & (
if (
not (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
pass
@@ -319,7 +319,7 @@ if (
if ( # comment
not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -327,14 +327,14 @@ if ( # comment
if (
# comment
~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
if (
# comment
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -342,7 +342,7 @@ if (
if (
# comment
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
):
pass
@@ -355,8 +355,8 @@ if not a:
# Regression test for: https://github.com/astral-sh/ruff/issues/5338
if (
a
and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
):
pass
@@ -377,7 +377,7 @@ if True:
if True:
if not yn_question(
Fore.RED
+ "WARNING: Removing listed files. Do you really want to continue. yes/n)? "
+ "WARNING: Removing listed files. Do you really want to continue. yes/n)? "
):
pass

View File

@@ -154,7 +154,7 @@ aaaaaaaa = (
aaaaaaaa = (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)

View File

@@ -195,8 +195,8 @@ def foo():
yield (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
)
@@ -259,20 +259,20 @@ result = yield
result = yield (
1
+ f(
1,
2,
3,
)
+ f(
1,
2,
3,
)
)
result = yield (
1
+ f(
1,
2,
3,
)
+ f(
1,
2,
3,
)
)
print((yield x))

View File

@@ -78,7 +78,7 @@ call(
textwrap.dedent(
"""dove
coo"""
% "cowabunga"
% "cowabunga"
),
)

View File

@@ -298,13 +298,13 @@ c1 = (
).filter(
entry__pub_date__year=2008,
)
+ Blog.objects.filter(
entry__headline__contains="McCartney",
)
.limit_results[:10]
.filter(
entry__pub_date__year=2010,
)
+ Blog.objects.filter(
entry__headline__contains="McCartney",
)
.limit_results[:10]
.filter(
entry__pub_date__year=2010,
)
).all()
# Test different cases with trailing end of line comments:
@@ -378,10 +378,10 @@ if (
pass
h2 = (
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ccccccccccccccccccccccccc()
.dddddddddddddddddddddd()
.eeeeeeeeee()
.ffffffffffffffffffffff()
+ ccccccccccccccccccccccccc()
.dddddddddddddddddddddd()
.eeeeeeeeee()
.ffffffffffffffffffffff()
)
# Parentheses aren't allowed on statement level, don't use fluent style here

View File

@@ -87,12 +87,12 @@ call(
a = (
a
+ b
+ c
+ d
+ ( # Hello
e + f + g
)
+ b
+ c
+ d
+ ( # Hello
e + f + g
)
)
a = int( # type: ignore
@@ -106,23 +106,23 @@ a = int( # type: ignore
# Stability and correctness checks
b1 = (
()
- ( #
)
- ( #
)
)
(
()
- ( #
)
- ( #
)
)
b2 = (
()
- f( #
)
- f( #
)
)
(
()
- f( #
)
- f( #
)
)
b3 = (
#

View File

@@ -145,7 +145,7 @@ def f():
)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
cccccccc.ccccccccccccc.cccccccc
+ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
)
self._cache: dict[
@@ -211,7 +211,7 @@ def f():
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
cccccccc.ccccccccccccc(d).cccccccc + e
@@ -57,9 +56,9 @@
+ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
)
- self._cache: dict[
@@ -300,7 +300,7 @@ def f():
)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
cccccccc.ccccccccccccc.cccccccc
+ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
)
self._cache: dict[DependencyCacheKey, list[list[DependencyPackage]]] = (

View File

@@ -24,8 +24,8 @@ def format_range_after_inserted_parens ():
def needs_parentheses( ) -> bool:
return (
item.sizing_mode is None
and item.width_policy == "auto"
and item.height_policy == "automatic"
and item.width_policy == "auto"
and item.height_policy == "automatic"
)
def no_longer_needs_parentheses( ) -> bool:

View File

@@ -223,7 +223,7 @@ def test():
key8: value8,
key9: value9,
}
== expected
== expected
), "Not what we expected and the message is too long to fit ineeeeee one line"
assert (
@@ -238,7 +238,7 @@ def test():
key8: value8,
key9: value9,
}
== expected
== expected
), "Not what we expected and the message is too long to fit in one lineeeee"
assert (
@@ -253,7 +253,7 @@ def test():
key8: value8,
key9: value9,
}
== expected
== expected
), "Not what we expected and the message is too long to fit in one lineeeeeeeeeeeee"
assert (
@@ -268,7 +268,7 @@ def test():
key8: value8,
key9: value9,
}
== expectedeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
== expectedeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
), "Not what we expected and the message is too long to fit in one lin"
assert (
@@ -283,7 +283,7 @@ def test():
key8: value8,
key9: value9,
}
== expectedeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
== expectedeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
), "Not what we expected and the message is too long to fit in one lineeeeeeeeeeeeeeeee"
assert expected == {
@@ -300,47 +300,47 @@ def test():
assert (
expected
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
== {
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 lineeeeeeeeeeeeeeeeeeee"
assert (
expectedeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
== {
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 lin"
assert (
expectedeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
== {
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
key6: value6,
key7: value7,
key8: value8,
key9: value9,
}
== {
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 lineeeeeeeeeeeeeee"

View File

@@ -151,7 +151,7 @@ def main() -> None:
some_very_long_variable_name_abcdefghijk = (
some_very_long_variable_name_abcdefghijk[
some_very_long_variable_name_abcdefghijk.some_very_long_attribute_name
== "This is a very long string abcdefghijk"
== "This is a very long string abcdefghijk"
]
)

View File

@@ -17,7 +17,7 @@ tree_depth += 1
greeting += (
"This is very long, formal greeting for whomever is name here. Dear %s, it will break the line"
% len(name)
% len(name)
)
```

View File

@@ -270,10 +270,10 @@ class Test((Aaaa)):
class Test(
aaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccccc
+ dddddddddddddddddddddd
+ eeeeeeeee,
+ bbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccccc
+ dddddddddddddddddddddd
+ eeeeeeeee,
ffffffffffffffffff,
gggggggggggggggggg,
):
@@ -282,9 +282,9 @@ class Test(
class Test(
aaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccc
+ dddddddddddddddddddddd
+ eeeeeeeee,
+ bbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccc
+ dddddddddddddddddddddd
+ eeeeeeeee,
ffffffffffffffffff,
gggggggggggggggggg,
):

View File

@@ -505,7 +505,7 @@ def kwarg_with_leading_comments(
def argument_with_long_default(
a,
b=ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+ [dddddddddddddddddddd, eeeeeeeeeeeeeeeeeeee, ffffffffffffffffffffffff],
+ [dddddddddddddddddddd, eeeeeeeeeeeeeeeeeeee, ffffffffffffffffffffffff],
h=[],
):
...
@@ -514,8 +514,8 @@ def argument_with_long_default(
def argument_with_long_type_annotation(
a,
b: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
| yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
| zzzzzzzzzzzzzzzzzzz = [0, 1, 2, 3],
| yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
| zzzzzzzzzzzzzzzzzzz = [0, 1, 2, 3],
h=[],
):
...
@@ -1064,7 +1064,7 @@ def function_with_one_argument_and_a_keyword_separator(
def argument_with_long_default(
@@ -75,8 +71,7 @@
b=ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+ [dddddddddddddddddddd, eeeeeeeeeeeeeeeeeeee, ffffffffffffffffffffffff],
+ [dddddddddddddddddddd, eeeeeeeeeeeeeeeeeeee, ffffffffffffffffffffffff],
h=[],
-):
- ...
@@ -1073,8 +1073,8 @@ def function_with_one_argument_and_a_keyword_separator(
def argument_with_long_type_annotation(
@@ -85,12 +80,10 @@
| yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
| zzzzzzzzzzzzzzzzzzz = [0, 1, 2, 3],
| yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
| zzzzzzzzzzzzzzzzzzz = [0, 1, 2, 3],
h=[],
-):
- ...

View File

@@ -181,17 +181,17 @@ x6: VeryLongClassNameWithAwkwardGenericSubtype[
x7: CustomTrainingJob | CustomContainerTrainingJob | CustomPythonPackageTrainingJob
x8: (
None
| datasets.ImageDataset
| datasets.TabularDataset
| datasets.TextDataset
| datasets.VideoDataset
| datasets.ImageDataset
| datasets.TabularDataset
| datasets.TextDataset
| datasets.VideoDataset
) = None
x9: None | (
datasets.ImageDataset
| datasets.TabularDataset
| datasets.TextDataset
| datasets.VideoDataset
| datasets.TabularDataset
| datasets.TextDataset
| datasets.VideoDataset
) = None
@@ -199,11 +199,11 @@ x10: (
aaaaaaaaaaaaaaaaaaaaaaaa[
bbbbbbbbbbb,
Subscript
| None
| datasets.ImageDataset
| datasets.TabularDataset
| datasets.TextDataset
| datasets.VideoDataset,
| None
| datasets.ImageDataset
| datasets.TabularDataset
| datasets.TextDataset
| datasets.VideoDataset,
],
bbb[other],
) = None
@@ -334,13 +334,13 @@ nested_comment: None | [
-] | Other | More | AndMore | None = None
+x1: (
+ A[b]
+ | EventHandler
+ | EventSpec
+ | list[EventHandler | EventSpec]
+ | Other
+ | More
+ | AndMore
+ | None
+ | EventHandler
+ | EventSpec
+ | list[EventHandler | EventSpec]
+ | Other
+ | More
+ | AndMore
+ | None
+) = None
-x2: "VeryLongClassNameWithAwkwardGenericSubtype[int] |" "VeryLongClassNameWithAwkwardGenericSubtype[str]"
@@ -363,13 +363,13 @@ nested_comment: None | [
-] | Other = None
+x12: (
+ None
+ | [
+ datasets.ImageDataset,
+ datasets.TabularDataset,
+ datasets.TextDataset,
+ datasets.VideoDataset,
+ ]
+ | Other
+ | [
+ datasets.ImageDataset,
+ datasets.TabularDataset,
+ datasets.TextDataset,
+ datasets.VideoDataset,
+ ]
+ | Other
+) = None
@@ -396,13 +396,13 @@ nested_comment: None | [
+ datasets.TextDataset,
+ datasets.VideoDataset,
+ ]
+ | [
+ datasets.ImageDataset,
+ datasets.TabularDataset,
+ datasets.TextDataset,
+ datasets.VideoDataset,
+ ]
+ | Other
+ | [
+ datasets.ImageDataset,
+ datasets.TabularDataset,
+ datasets.TextDataset,
+ datasets.VideoDataset,
+ ]
+ | Other
+) = None
-x16: None | Literal[
@@ -416,15 +416,15 @@ nested_comment: None | [
-] = None
+x16: (
+ None
+ | Literal[
+ "split",
+ "a bit longer",
+ "records",
+ "index",
+ "table",
+ "columns",
+ "values",
+ ]
+ | Literal[
+ "split",
+ "a bit longer",
+ "records",
+ "index",
+ "table",
+ "columns",
+ "values",
+ ]
+) = None
x17: None | [

View File

@@ -137,29 +137,29 @@ raise OsError(
raise (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccc
+ ddddddddddddddddddddddddd
+ bbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccc
+ ddddddddddddddddddddddddd
)
raise (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbb
+ (cccccccccccccccccccccc + ddddddddddddddddddddddddd)
+ bbbbbbbbbbbbbbbbbbbbbbbbbb
+ (cccccccccccccccccccccc + ddddddddddddddddddddddddd)
)
raise (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccc
+ ddddddddddddddddddddddddd
+ bbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccc
+ ddddddddddddddddddddddddd
)
raise ( # hey
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
# Holala
+ bbbbbbbbbbbbbbbbbbbbbbbbbb # stay
+ cccccccccccccccccccccc
+ ddddddddddddddddddddddddd # where I'm going
+ bbbbbbbbbbbbbbbbbbbbbbbbbb # stay
+ cccccccccccccccccccccc
+ ddddddddddddddddddddddddd # where I'm going
# I don't know
) # whaaaaat
# the end
@@ -180,13 +180,13 @@ raise aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflak
raise (
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
< aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
< aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
< aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
< aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
)
raise aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfk < (
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajl
< aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashd
< aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashd
) # the other end
# sneaky comment

View File

@@ -76,9 +76,9 @@ return (
def f():
return (
self.get_filename()
+ ".csv"
+ "text/csv"
+ output.getvalue().encode("utf-8----------------"),
+ ".csv"
+ "text/csv"
+ output.getvalue().encode("utf-8----------------"),
)
@@ -100,9 +100,9 @@ def f():
def f():
return (
self.get_filename()
+ ".csv"
+ "text/csv"
+ output.getvalue().encode("utf-8----------------"),
+ ".csv"
+ "text/csv"
+ output.getvalue().encode("utf-8----------------"),
)

View File

@@ -486,9 +486,9 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx(
def double() -> (
first_item
and foo.bar.baz().bop(
1,
)
and foo.bar.baz().bop(
1,
)
):
return 2 * a
@@ -530,24 +530,9 @@ def double(
a: int,
) -> (
int
| list[
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
] # Hello
| list[
int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int
] # Hello
):
pass

View File

@@ -137,8 +137,8 @@ type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
type X = Ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
type X = (
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
| Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
| Ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
| Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
| Ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
)
type XXXXXXXXXXXXX = (
Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment

View File

@@ -65,8 +65,8 @@ while (
while (
some_condition(unformatted, args) # trailing some condition
and anotherCondition
or aThirdCondition # trailing third condition
and anotherCondition
or aThirdCondition # trailing third condition
): # comment
print("Do something")
```

View File

@@ -487,9 +487,9 @@ with (
dddddddddddddddddddddddddddddddd,
] as example1,
aaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccccccccc
+ ddddddddddddddddd as example2,
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccccccccc
+ ddddddddddddddddd as example2,
CtxManager2() as example2,
CtxManager2() as example2,
CtxManager2() as example2,
@@ -623,14 +623,14 @@ with (
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
c as d,
):
pass
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
c as d,
):
pass
@@ -649,8 +649,8 @@ if True:
if True:
with (
anyio.CancelScope(shield=True)
and B
and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee]
and B
and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee]
):
pass
@@ -677,7 +677,7 @@ with Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Document(
with (
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
- + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
+ (
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ ) as b,
@@ -867,9 +867,9 @@ with (
dddddddddddddddddddddddddddddddd,
] as example1,
aaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccccccccc
+ ddddddddddddddddd as example2,
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ cccccccccccccccccccccccccccc
+ ddddddddddddddddd as example2,
CtxManager2() as example2,
CtxManager2() as example2,
CtxManager2() as example2,
@@ -884,9 +884,9 @@ with (
dddddddddddddddddddddddddddddddd,
] as example1,
aaaaaaaaaaaaaaaaaaaaaaaaaa
* bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
* cccccccccccccccccccccccccccc
+ ddddddddddddddddd as example2,
* bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
* cccccccccccccccccccccccccccc
+ ddddddddddddddddd as example2,
CtxManager222222222222222() as example2,
):
pass
@@ -1016,7 +1016,7 @@ with (
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b
):
pass
@@ -1030,7 +1030,7 @@ with (
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
c as d,
):
pass
@@ -1057,8 +1057,8 @@ if True:
if True:
with (
anyio.CancelScope(shield=True)
and B
and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee]
and B
and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee]
):
pass

View File

@@ -61,7 +61,7 @@ source_type = Python
# Fits with tab width 2
(
1
+ " 012345678901234567890123456789012345678901234567890123456789012345678901234567"
+ " 012345678901234567890123456789012345678901234567890123456789012345678901234567"
)
# Fits with tab width 4
@@ -91,13 +91,13 @@ source_type = Python
# Fits with tab width 2
(
1
+ " 012345678901234567890123456789012345678901234567890123456789012345678901234567"
+ " 012345678901234567890123456789012345678901234567890123456789012345678901234567"
)
# Fits with tab width 4
(
1
+ " 0123456789012345678901234567890123456789012345678901234567890123456789012345"
+ " 0123456789012345678901234567890123456789012345678901234567890123456789012345"
)
# Fits with tab width 8

View File

@@ -406,7 +406,7 @@ where
}
/// Abstraction for a type checker, conservatively checks for the intended type(s).
pub trait TypeChecker {
trait TypeChecker {
/// Check annotation expression to match the intended type(s).
fn match_annotation(annotation: &Expr, semantic: &SemanticModel) -> bool;
/// Check initializer expression to match the intended type(s).
@@ -421,17 +421,14 @@ pub trait TypeChecker {
fn check_type<T: TypeChecker>(binding: &Binding, semantic: &SemanticModel) -> bool {
match binding.kind {
BindingKind::Assignment => match binding.statement(semantic) {
// Given:
//
// ```python
// x = init_expr
// ```
//
// The type checker might know how to infer the type based on `init_expr`.
Some(Stmt::Assign(ast::StmtAssign { targets, value, .. })) => targets
.iter()
.find_map(|target| match_value(binding, target, value.as_ref()))
.is_some_and(|value| T::match_initializer(value, semantic)),
Some(Stmt::Assign(ast::StmtAssign { value, .. })) => {
T::match_initializer(value.as_ref(), semantic)
}
// ```python
// x: annotation = some_expr
@@ -441,40 +438,6 @@ fn check_type<T: TypeChecker>(binding: &Binding, semantic: &SemanticModel) -> bo
Some(Stmt::AnnAssign(ast::StmtAnnAssign { annotation, .. })) => {
T::match_annotation(annotation.as_ref(), semantic)
}
_ => false,
},
BindingKind::NamedExprAssignment => {
// ```python
// if (x := some_expr) is not None:
// ...
// ```
binding.source.is_some_and(|source| {
semantic
.expressions(source)
.find_map(|expr| expr.as_named_expr_expr())
.and_then(|ast::ExprNamedExpr { target, value, .. }| {
match_value(binding, target.as_ref(), value.as_ref())
})
.is_some_and(|value| T::match_initializer(value, semantic))
})
}
BindingKind::WithItemVar => match binding.statement(semantic) {
// ```python
// with open("file.txt") as x:
// ...
// ```
Some(Stmt::With(ast::StmtWith { items, .. })) => items
.iter()
.find_map(|item| {
let target = item.optional_vars.as_ref()?;
let value = &item.context_expr;
match_value(binding, target, value)
})
.is_some_and(|value| T::match_initializer(value, semantic)),
_ => false,
},
@@ -494,7 +457,6 @@ fn check_type<T: TypeChecker>(binding: &Binding, semantic: &SemanticModel) -> bo
};
T::match_annotation(annotation.as_ref(), semantic)
}
_ => false,
},
@@ -603,125 +565,35 @@ impl BuiltinTypeChecker for TupleChecker {
const EXPR_TYPE: PythonType = PythonType::Tuple;
}
pub struct IoBaseChecker;
impl TypeChecker for IoBaseChecker {
fn match_annotation(annotation: &Expr, semantic: &SemanticModel) -> bool {
semantic
.resolve_call_path(annotation)
.is_some_and(|call_path| {
if semantic.match_typing_call_path(&call_path, "IO") {
return true;
}
if semantic.match_typing_call_path(&call_path, "BinaryIO") {
return true;
}
if semantic.match_typing_call_path(&call_path, "TextIO") {
return true;
}
matches!(
call_path.as_slice(),
[
"io",
"IOBase"
| "RawIOBase"
| "BufferedIOBase"
| "TextIOBase"
| "BytesIO"
| "StringIO"
| "BufferedReader"
| "BufferedWriter"
| "BufferedRandom"
| "BufferedRWPair"
| "TextIOWrapper"
] | ["os", "Path" | "PathLike"]
| [
"pathlib",
"Path" | "PurePath" | "PurePosixPath" | "PureWindowsPath"
]
)
})
}
fn match_initializer(initializer: &Expr, semantic: &SemanticModel) -> bool {
let Expr::Call(ast::ExprCall { func, .. }) = initializer else {
return false;
};
// Ex) `pathlib.Path("file.txt")`
if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() {
if attr.as_str() == "open" {
if let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() {
return semantic.resolve_call_path(func).is_some_and(|call_path| {
matches!(
call_path.as_slice(),
[
"pathlib",
"Path" | "PurePath" | "PurePosixPath" | "PureWindowsPath"
]
)
});
}
}
}
// Ex) `open("file.txt")`
semantic
.resolve_call_path(func.as_ref())
.is_some_and(|call_path| {
matches!(
call_path.as_slice(),
["io", "open" | "open_code"] | ["os" | "", "open"]
)
})
}
}
/// Test whether the given binding can be considered a list.
///
/// Test whether the given binding (and the given name) can be considered a list.
/// For this, we check what value might be associated with it through it's initialization and
/// what annotation it has (we consider `list` and `typing.List`).
pub fn is_list(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<ListChecker>(binding, semantic)
}
/// Test whether the given binding can be considered a dictionary.
///
/// Test whether the given binding (and the given name) can be considered a dictionary.
/// For this, we check what value might be associated with it through it's initialization and
/// what annotation it has (we consider `dict` and `typing.Dict`).
pub fn is_dict(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<DictChecker>(binding, semantic)
}
/// Test whether the given binding can be considered a set.
///
/// Test whether the given binding (and the given name) can be considered a set.
/// For this, we check what value might be associated with it through it's initialization and
/// what annotation it has (we consider `set` and `typing.Set`).
pub fn is_set(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<SetChecker>(binding, semantic)
}
/// Test whether the given binding can be considered a tuple.
///
/// For this, we check what value might be associated with it through
/// Test whether the given binding (and the given name) can be considered a
/// tuple. For this, we check what value might be associated with it through
/// it's initialization and what annotation it has (we consider `tuple` and
/// `typing.Tuple`).
pub fn is_tuple(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<TupleChecker>(binding, semantic)
}
/// Test whether the given binding can be considered a file-like object (i.e., a type that
/// implements `io.IOBase`).
pub fn is_io_base(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<IoBaseChecker>(binding, semantic)
}
/// Test whether the given expression can be considered a file-like object (i.e., a type that
/// implements `io.IOBase`).
pub fn is_io_base_expr(expr: &Expr, semantic: &SemanticModel) -> bool {
IoBaseChecker::match_initializer(expr, semantic)
}
/// Find the [`ParameterWithDefault`] corresponding to the given [`Binding`].
#[inline]
fn find_parameter<'a>(
@@ -795,7 +667,6 @@ pub fn find_assigned_value<'a>(symbol: &str, semantic: &'a SemanticModel<'a>) ->
///
/// This function will return a `NumberLiteral` with value `Int(42)` when called with `foo` and a
/// `StringLiteral` with value `"str"` when called with `bla`.
#[allow(clippy::single_match)]
pub fn find_binding_value<'a>(binding: &Binding, semantic: &'a SemanticModel) -> Option<&'a Expr> {
match binding.kind {
// Ex) `x := 1`
@@ -809,32 +680,25 @@ pub fn find_binding_value<'a>(binding: &Binding, semantic: &'a SemanticModel) ->
}
}
// Ex) `x = 1`
BindingKind::Assignment => match binding.statement(semantic) {
Some(Stmt::Assign(ast::StmtAssign { value, targets, .. })) => {
return targets
.iter()
.find_map(|target| match_value(binding, target, value.as_ref()))
BindingKind::Assignment => {
let parent_id = binding.source?;
let parent = semantic.statement(parent_id);
match parent {
Stmt::Assign(ast::StmtAssign { value, targets, .. }) => {
return targets
.iter()
.find_map(|target| match_value(binding, target, value.as_ref()))
}
Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value),
target,
..
}) => {
return match_value(binding, target, value.as_ref());
}
_ => {}
}
Some(Stmt::AnnAssign(ast::StmtAnnAssign {
value: Some(value),
target,
..
})) => {
return match_value(binding, target, value.as_ref());
}
_ => {}
},
// Ex) `with open("file.txt") as f:`
BindingKind::WithItemVar => match binding.statement(semantic) {
Some(Stmt::With(ast::StmtWith { items, .. })) => {
return items.iter().find_map(|item| {
let target = item.optional_vars.as_ref()?;
let value = &item.context_expr;
match_value(binding, target, value)
});
}
_ => {}
},
}
_ => {}
}
None

View File

@@ -640,9 +640,13 @@ impl<'a> SemanticModel<'a> {
/// only binding to that name in its scope.
pub fn only_binding(&self, name: &ast::ExprName) -> Option<BindingId> {
self.resolve_name(name).filter(|id| {
// Find the correct scope.
let binding = self.binding(*id);
let scope = &self.scopes[binding.scope];
scope.shadowed_binding(*id).is_none()
// Ensure that the name is only bound once in the scope.
let mut bindings = scope.get_all(&name.id);
bindings.next().is_some_and(|binding| binding == *id) && bindings.next().is_none()
})
}
@@ -1489,11 +1493,6 @@ impl<'a> SemanticModel<'a> {
.intersects(SemanticModelFlags::TYPE_CHECKING_BLOCK)
}
/// Return `true` if the model is in a docstring.
pub const fn in_docstring(&self) -> bool {
self.flags.intersects(SemanticModelFlags::DOCSTRING)
}
/// Return `true` if the model has traversed past the "top-of-file" import boundary.
pub const fn seen_import_boundary(&self) -> bool {
self.flags.intersects(SemanticModelFlags::IMPORT_BOUNDARY)
@@ -1858,26 +1857,6 @@ bitflags! {
/// ```
const COMPREHENSION_ASSIGNMENT = 1 << 19;
/// The model is in a module / class / function docstring.
///
/// For example, the model could be visiting either the module, class,
/// or function docstring in:
/// ```python
/// """Module docstring."""
///
///
/// class Foo:
/// """Class docstring."""
/// pass
///
///
/// def foo():
/// """Function docstring."""
/// pass
/// ```
const DOCSTRING = 1 << 20;
/// The context is in any type annotation.
const ANNOTATION = Self::TYPING_ONLY_ANNOTATION.bits() | Self::RUNTIME_EVALUATED_ANNOTATION.bits() | Self::RUNTIME_REQUIRED_ANNOTATION.bits();

View File

@@ -268,9 +268,6 @@ Instead, apply the `# fmt: off` comment to the entire statement:
# fmt: on
```
Like Black, Ruff will _also_ recognize [YAPF](https://github.com/google/yapf)'s `# yapf: disable` and `# yapf: enable` pragma
comments, which are treated equivalently to `# fmt: off` and `# fmt: on`, respectively.
`# fmt: skip` comments suppress formatting for a preceding statement, case header, decorator,
function definition, or class definition:
@@ -290,30 +287,8 @@ def test(a, b, c, d, e, f) -> int: # fmt: skip
pass
```
As such, adding `# fmt: skip` comments at the end of an expressions will have no effect. In
the following example, the list entry `'1'` will be formatted, despite the `# fmt: skip`:
```python
a = call(
[
'1', # fmt: skip
'2',
],
b
)
```
Instead, apply the `# fmt: skip` comment to the entire statement:
```python
a = call(
[
'1',
'2',
],
b
) # fmt: skip
```
Like Black, Ruff will _also_ recognize [YAPF](https://github.com/google/yapf)'s `# yapf: disable` and `# yapf: enable` pragma
comments, which are treated equivalently to `# fmt: off` and `# fmt: on`, respectively.
## Conflicting lint rules

2
ruff.schema.json generated
View File

@@ -2988,8 +2988,6 @@
"FURB11",
"FURB113",
"FURB118",
"FURB12",
"FURB129",
"FURB13",
"FURB131",
"FURB132",