mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 05:25:17 +00:00
Fix invalid syntax for binary expression in unary op (#5370)
This commit is contained in:
parent
38189ed913
commit
955e9ef821
20 changed files with 200 additions and 116 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2088,6 +2088,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"similar",
|
"similar",
|
||||||
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -26,6 +26,7 @@ once_cell = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
rustpython-parser = { workspace = true }
|
rustpython-parser = { workspace = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
smallvec = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ruff_formatter = { path = "../ruff_formatter", features = ["serde"]}
|
ruff_formatter = { path = "../ruff_formatter", features = ["serde"]}
|
||||||
|
|
|
@ -10,6 +10,19 @@
|
||||||
b
|
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 own line comment
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Black breaks the right side first for the following expressions:
|
# Black breaks the right side first for the following expressions:
|
||||||
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(argument1, argument2, argument3)
|
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(argument1, argument2, argument3)
|
||||||
|
|
|
@ -136,3 +136,7 @@ if (
|
||||||
if not \
|
if not \
|
||||||
a:
|
a:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Regression: https://github.com/astral-sh/ruff/issues/5338
|
||||||
|
if a and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
|
||||||
|
...
|
||||||
|
|
|
@ -32,5 +32,8 @@ class Test((Aaaa)):
|
||||||
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
|
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
|
||||||
|
pass
|
||||||
|
|
||||||
class Test(Aaaa): # trailing comment
|
class Test(Aaaa): # trailing comment
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustpython_parser::ast::{self, Expr};
|
||||||
|
|
||||||
use ruff_formatter::{format_args, write};
|
use ruff_formatter::{format_args, write};
|
||||||
|
|
||||||
use crate::expression::parentheses::Parentheses;
|
use crate::expression::parentheses::{is_expression_parenthesized, Parentheses};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// Trait to implement a binary like syntax that has a left operand, an operator, and a right operand.
|
/// Trait to implement a binary like syntax that has a left operand, an operator, and a right operand.
|
||||||
|
@ -24,7 +24,7 @@ pub(super) trait FormatBinaryLike<'ast> {
|
||||||
let right = self.right()?;
|
let right = self.right()?;
|
||||||
|
|
||||||
let layout = if parentheses == Some(Parentheses::Custom) {
|
let layout = if parentheses == Some(Parentheses::Custom) {
|
||||||
self.binary_layout()
|
self.binary_layout(f.context().contents())
|
||||||
} else {
|
} else {
|
||||||
BinaryLayout::Default
|
BinaryLayout::Default
|
||||||
};
|
};
|
||||||
|
@ -113,9 +113,9 @@ pub(super) trait FormatBinaryLike<'ast> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines which binary layout to use.
|
/// Determines which binary layout to use.
|
||||||
fn binary_layout(&self) -> BinaryLayout {
|
fn binary_layout(&self, source: &str) -> BinaryLayout {
|
||||||
if let (Ok(left), Ok(right)) = (self.left(), self.right()) {
|
if let (Ok(left), Ok(right)) = (self.left(), self.right()) {
|
||||||
BinaryLayout::from_left_right(left, right)
|
BinaryLayout::from_left_right(left, right, source)
|
||||||
} else {
|
} else {
|
||||||
BinaryLayout::Default
|
BinaryLayout::Default
|
||||||
}
|
}
|
||||||
|
@ -134,8 +134,8 @@ pub(super) trait FormatBinaryLike<'ast> {
|
||||||
fn operator(&self) -> Self::FormatOperator;
|
fn operator(&self) -> Self::FormatOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_break_expr(expr: &Expr) -> bool {
|
fn can_break_expr(expr: &Expr, source: &str) -> bool {
|
||||||
match expr {
|
let can_break = match expr {
|
||||||
Expr::Tuple(ast::ExprTuple {
|
Expr::Tuple(ast::ExprTuple {
|
||||||
elts: expressions, ..
|
elts: expressions, ..
|
||||||
})
|
})
|
||||||
|
@ -153,12 +153,11 @@ fn can_break_expr(expr: &Expr) -> bool {
|
||||||
!(args.is_empty() && keywords.is_empty())
|
!(args.is_empty() && keywords.is_empty())
|
||||||
}
|
}
|
||||||
Expr::ListComp(_) | Expr::SetComp(_) | Expr::DictComp(_) | Expr::GeneratorExp(_) => true,
|
Expr::ListComp(_) | Expr::SetComp(_) | Expr::DictComp(_) | Expr::GeneratorExp(_) => true,
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp { operand, .. }) => match operand.as_ref() {
|
Expr::UnaryOp(ast::ExprUnaryOp { operand, .. }) => can_break_expr(operand.as_ref(), source),
|
||||||
Expr::BinOp(_) => true,
|
|
||||||
_ => can_break_expr(operand.as_ref()),
|
|
||||||
},
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
can_break || is_expression_parenthesized(expr.into(), source)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -206,8 +205,8 @@ pub(super) enum BinaryLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinaryLayout {
|
impl BinaryLayout {
|
||||||
pub(super) fn from_left_right(left: &Expr, right: &Expr) -> BinaryLayout {
|
pub(super) fn from_left_right(left: &Expr, right: &Expr, source: &str) -> BinaryLayout {
|
||||||
match (can_break_expr(left), can_break_expr(right)) {
|
match (can_break_expr(left, source), can_break_expr(right, source)) {
|
||||||
(false, false) => BinaryLayout::Default,
|
(false, false) => BinaryLayout::Default,
|
||||||
(true, false) => BinaryLayout::ExpandLeft,
|
(true, false) => BinaryLayout::ExpandLeft,
|
||||||
(false, true) => BinaryLayout::ExpandRight,
|
(false, true) => BinaryLayout::ExpandRight,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::comments::{trailing_comments, Comments};
|
use crate::comments::{trailing_comments, trailing_node_comments, Comments};
|
||||||
use crate::expression::binary_like::{BinaryLayout, FormatBinaryLike};
|
use crate::expression::binary_like::{BinaryLayout, FormatBinaryLike};
|
||||||
use crate::expression::parentheses::{
|
use crate::expression::parentheses::{
|
||||||
default_expression_needs_parentheses, NeedsParentheses, Parenthesize,
|
default_expression_needs_parentheses, NeedsParentheses, Parenthesize,
|
||||||
|
@ -10,6 +10,8 @@ use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule, FormatRuleWi
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, UnaryOp,
|
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, UnaryOp,
|
||||||
};
|
};
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FormatExprBinOp {
|
pub struct FormatExprBinOp {
|
||||||
|
@ -40,41 +42,68 @@ impl<'ast> FormatBinaryLike<'ast> for ExprBinOp {
|
||||||
type FormatOperator = FormatOwnedWithRule<Operator, FormatOperator, PyFormatContext<'ast>>;
|
type FormatOperator = FormatOwnedWithRule<Operator, FormatOperator, PyFormatContext<'ast>>;
|
||||||
|
|
||||||
fn fmt_default(&self, f: &mut PyFormatter<'ast, '_>) -> FormatResult<()> {
|
fn fmt_default(&self, f: &mut PyFormatter<'ast, '_>) -> FormatResult<()> {
|
||||||
let ExprBinOp {
|
|
||||||
range: _,
|
|
||||||
left,
|
|
||||||
op,
|
|
||||||
right,
|
|
||||||
} = self;
|
|
||||||
|
|
||||||
let comments = f.context().comments().clone();
|
let comments = f.context().comments().clone();
|
||||||
let operator_comments = comments.dangling_comments(self);
|
|
||||||
let needs_space = !is_simple_power_expression(self);
|
|
||||||
|
|
||||||
let before_operator_space = if needs_space {
|
let format_inner = format_with(|f| {
|
||||||
soft_line_break_or_space()
|
let binary_chain: SmallVec<[&ExprBinOp; 4]> =
|
||||||
} else {
|
iter::successors(Some(self), |parent| parent.left.as_bin_op_expr()).collect();
|
||||||
soft_line_break()
|
|
||||||
};
|
|
||||||
|
|
||||||
write!(
|
// SAFETY: `binary_chain` is guaranteed not to be empty because it always contains the current expression.
|
||||||
f,
|
let left_most = binary_chain.last().unwrap();
|
||||||
[
|
|
||||||
left.format(),
|
|
||||||
before_operator_space,
|
|
||||||
op.format(),
|
|
||||||
trailing_comments(operator_comments),
|
|
||||||
]
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Format the operator on its own line if the right side has any leading comments.
|
// Format the left most expression
|
||||||
if comments.has_leading_comments(right.as_ref()) {
|
group(&left_most.left.format()).fmt(f)?;
|
||||||
write!(f, [hard_line_break()])?;
|
|
||||||
} else if needs_space {
|
|
||||||
write!(f, [space()])?;
|
|
||||||
}
|
|
||||||
|
|
||||||
write!(f, [group(&right.format())])
|
// Iterate upwards in the binary expression tree and, for each level, format the operator
|
||||||
|
// and the right expression.
|
||||||
|
for current in binary_chain.into_iter().rev() {
|
||||||
|
let ExprBinOp {
|
||||||
|
range: _,
|
||||||
|
left: _,
|
||||||
|
op,
|
||||||
|
right,
|
||||||
|
} = current;
|
||||||
|
|
||||||
|
let operator_comments = comments.dangling_comments(current);
|
||||||
|
let needs_space = !is_simple_power_expression(current);
|
||||||
|
|
||||||
|
let before_operator_space = if needs_space {
|
||||||
|
soft_line_break_or_space()
|
||||||
|
} else {
|
||||||
|
soft_line_break()
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
[
|
||||||
|
before_operator_space,
|
||||||
|
op.format(),
|
||||||
|
trailing_comments(operator_comments),
|
||||||
|
]
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Format the operator on its own line if the right side has any leading comments.
|
||||||
|
if comments.has_leading_comments(right.as_ref()) || !operator_comments.is_empty() {
|
||||||
|
hard_line_break().fmt(f)?;
|
||||||
|
} else if needs_space {
|
||||||
|
space().fmt(f)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
group(&right.format()).fmt(f)?;
|
||||||
|
|
||||||
|
// It's necessary to format the trailing comments because the code bypasses
|
||||||
|
// `FormatNodeRule::fmt` for the nested binary expressions.
|
||||||
|
// Don't call the formatting function for the most outer binary expression because
|
||||||
|
// these comments have already been formatted.
|
||||||
|
if current != self {
|
||||||
|
trailing_node_comments(current).fmt(f)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
group(&format_inner).fmt(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn left(&self) -> FormatResult<&Expr> {
|
fn left(&self) -> FormatResult<&Expr> {
|
||||||
|
@ -162,7 +191,7 @@ impl NeedsParentheses for ExprBinOp {
|
||||||
) -> Parentheses {
|
) -> Parentheses {
|
||||||
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
||||||
Parentheses::Optional => {
|
Parentheses::Optional => {
|
||||||
if self.binary_layout() == BinaryLayout::Default
|
if self.binary_layout(source) == BinaryLayout::Default
|
||||||
|| comments.has_leading_comments(self.right.as_ref())
|
|| comments.has_leading_comments(self.right.as_ref())
|
||||||
|| comments.has_dangling_comments(self)
|
|| comments.has_dangling_comments(self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,9 +31,9 @@ impl FormatNodeRule<ExprBoolOp> for FormatExprBoolOp {
|
||||||
impl<'ast> FormatBinaryLike<'ast> for ExprBoolOp {
|
impl<'ast> FormatBinaryLike<'ast> for ExprBoolOp {
|
||||||
type FormatOperator = FormatOwnedWithRule<BoolOp, FormatBoolOp, PyFormatContext<'ast>>;
|
type FormatOperator = FormatOwnedWithRule<BoolOp, FormatBoolOp, PyFormatContext<'ast>>;
|
||||||
|
|
||||||
fn binary_layout(&self) -> BinaryLayout {
|
fn binary_layout(&self, source: &str) -> BinaryLayout {
|
||||||
match self.values.as_slice() {
|
match self.values.as_slice() {
|
||||||
[left, right] => BinaryLayout::from_left_right(left, right),
|
[left, right] => BinaryLayout::from_left_right(left, right, source),
|
||||||
[..] => BinaryLayout::Default,
|
[..] => BinaryLayout::Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ impl NeedsParentheses for ExprBoolOp {
|
||||||
comments: &Comments,
|
comments: &Comments,
|
||||||
) -> Parentheses {
|
) -> Parentheses {
|
||||||
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
||||||
Parentheses::Optional => match self.binary_layout() {
|
Parentheses::Optional => match self.binary_layout(source) {
|
||||||
BinaryLayout::Default => Parentheses::Optional,
|
BinaryLayout::Default => Parentheses::Optional,
|
||||||
|
|
||||||
BinaryLayout::ExpandRight
|
BinaryLayout::ExpandRight
|
||||||
|
|
|
@ -34,10 +34,10 @@ impl FormatNodeRule<ExprCompare> for FormatExprCompare {
|
||||||
impl<'ast> FormatBinaryLike<'ast> for ExprCompare {
|
impl<'ast> FormatBinaryLike<'ast> for ExprCompare {
|
||||||
type FormatOperator = FormatOwnedWithRule<CmpOp, FormatCmpOp, PyFormatContext<'ast>>;
|
type FormatOperator = FormatOwnedWithRule<CmpOp, FormatCmpOp, PyFormatContext<'ast>>;
|
||||||
|
|
||||||
fn binary_layout(&self) -> BinaryLayout {
|
fn binary_layout(&self, source: &str) -> BinaryLayout {
|
||||||
if self.ops.len() == 1 {
|
if self.ops.len() == 1 {
|
||||||
match self.comparators.as_slice() {
|
match self.comparators.as_slice() {
|
||||||
[right] => BinaryLayout::from_left_right(&self.left, right),
|
[right] => BinaryLayout::from_left_right(&self.left, right, source),
|
||||||
[..] => BinaryLayout::Default,
|
[..] => BinaryLayout::Default,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,7 +102,7 @@ impl NeedsParentheses for ExprCompare {
|
||||||
comments: &Comments,
|
comments: &Comments,
|
||||||
) -> Parentheses {
|
) -> Parentheses {
|
||||||
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
|
||||||
parentheses @ Parentheses::Optional => match self.binary_layout() {
|
parentheses @ Parentheses::Optional => match self.binary_layout(source) {
|
||||||
BinaryLayout::Default => parentheses,
|
BinaryLayout::Default => parentheses,
|
||||||
|
|
||||||
BinaryLayout::ExpandRight
|
BinaryLayout::ExpandRight
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ruff_formatter::{
|
||||||
};
|
};
|
||||||
use rustpython_parser::ast::Expr;
|
use rustpython_parser::ast::Expr;
|
||||||
|
|
||||||
mod binary_like;
|
pub(crate) mod binary_like;
|
||||||
pub(crate) mod expr_attribute;
|
pub(crate) mod expr_attribute;
|
||||||
pub(crate) mod expr_await;
|
pub(crate) mod expr_await;
|
||||||
pub(crate) mod expr_bin_op;
|
pub(crate) mod expr_bin_op;
|
||||||
|
|
|
@ -147,7 +147,7 @@ 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
|
an_element_with_a_long_value = calls() or more_calls() and more() # type: bool
|
||||||
|
|
||||||
tup = (
|
tup = (
|
||||||
@@ -100,19 +98,35 @@
|
@@ -100,19 +98,32 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
c = call(
|
c = call(
|
||||||
|
@ -169,10 +169,7 @@ aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*ite
|
||||||
|
|
||||||
-AAAAAAAAAAAAA = [AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA # type: ignore
|
-AAAAAAAAAAAAA = [AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA # type: ignore
|
||||||
+AAAAAAAAAAAAA = (
|
+AAAAAAAAAAAAA = (
|
||||||
+ [AAAAAAAAAAAAA]
|
+ [AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA
|
||||||
+ + SHARED_AAAAAAAAAAAAA
|
|
||||||
+ + USER_AAAAAAAAAAAAA
|
|
||||||
+ + AAAAAAAAAAAAA
|
|
||||||
+) # type: ignore
|
+) # type: ignore
|
||||||
|
|
||||||
call_to_some_function_asdf(
|
call_to_some_function_asdf(
|
||||||
|
@ -308,10 +305,7 @@ def func(
|
||||||
result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa
|
result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa
|
||||||
|
|
||||||
AAAAAAAAAAAAA = (
|
AAAAAAAAAAAAA = (
|
||||||
[AAAAAAAAAAAAA]
|
[AAAAAAAAAAAAA] + SHARED_AAAAAAAAAAAAA + USER_AAAAAAAAAAAAA + AAAAAAAAAAAAA
|
||||||
+ SHARED_AAAAAAAAAAAAA
|
|
||||||
+ USER_AAAAAAAAAAAAA
|
|
||||||
+ AAAAAAAAAAAAA
|
|
||||||
) # type: ignore
|
) # type: ignore
|
||||||
|
|
||||||
call_to_some_function_asdf(
|
call_to_some_function_asdf(
|
||||||
|
|
|
@ -274,11 +274,20 @@ last_call()
|
||||||
Name
|
Name
|
||||||
None
|
None
|
||||||
True
|
True
|
||||||
@@ -30,33 +31,39 @@
|
@@ -23,40 +24,46 @@
|
||||||
|
1 >> v2
|
||||||
|
1 % finished
|
||||||
|
1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
|
||||||
|
-((1 + v2) - (v3 * 4)) ^ (((5**v6) / 7) // 8)
|
||||||
|
+(1 + v2 - (v3 * 4)) ^ (5**v6 / 7 // 8)
|
||||||
|
not great
|
||||||
|
~great
|
||||||
|
+value
|
||||||
-1
|
-1
|
||||||
~int and not v1 ^ 123 + v2 | True
|
~int and not v1 ^ 123 + v2 | True
|
||||||
(~int) and (not ((v1 ^ (123 + v2)) | True))
|
-(~int) and (not ((v1 ^ (123 + v2)) | True))
|
||||||
-+(really ** -(confusing ** ~(operator**-precedence)))
|
-+(really ** -(confusing ** ~(operator**-precedence)))
|
||||||
|
+(~int) and (not (v1 ^ (123 + v2) | True))
|
||||||
++really ** -confusing ** ~operator**-precedence
|
++really ** -confusing ** ~operator**-precedence
|
||||||
flags & ~select.EPOLLIN and waiters.write_task is not None
|
flags & ~select.EPOLLIN and waiters.write_task is not None
|
||||||
-lambda arg: None
|
-lambda arg: None
|
||||||
|
@ -638,13 +647,13 @@ v1 << 2
|
||||||
1 >> v2
|
1 >> v2
|
||||||
1 % finished
|
1 % finished
|
||||||
1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
|
1 + v2 - v3 * 4 ^ 5**v6 / 7 // 8
|
||||||
((1 + v2) - (v3 * 4)) ^ (((5**v6) / 7) // 8)
|
(1 + v2 - (v3 * 4)) ^ (5**v6 / 7 // 8)
|
||||||
not great
|
not great
|
||||||
~great
|
~great
|
||||||
+value
|
+value
|
||||||
-1
|
-1
|
||||||
~int and not v1 ^ 123 + v2 | True
|
~int and not v1 ^ 123 + v2 | True
|
||||||
(~int) and (not ((v1 ^ (123 + v2)) | True))
|
(~int) and (not (v1 ^ (123 + v2) | True))
|
||||||
+really ** -confusing ** ~operator**-precedence
|
+really ** -confusing ** ~operator**-precedence
|
||||||
flags & ~select.EPOLLIN and waiters.write_task is not None
|
flags & ~select.EPOLLIN and waiters.write_task is not None
|
||||||
lambda x: True
|
lambda x: True
|
||||||
|
|
|
@ -202,11 +202,11 @@ d={'a':1,
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
-import asyncio
|
-import asyncio
|
||||||
-import sys
|
-import sys
|
||||||
|
-
|
||||||
|
-from third_party import X, Y, Z
|
||||||
+NOT_YET_IMPLEMENTED_StmtImport
|
+NOT_YET_IMPLEMENTED_StmtImport
|
||||||
+NOT_YET_IMPLEMENTED_StmtImport
|
+NOT_YET_IMPLEMENTED_StmtImport
|
||||||
|
|
||||||
-from third_party import X, Y, Z
|
|
||||||
-
|
|
||||||
-from library import some_connection, some_decorator
|
-from library import some_connection, some_decorator
|
||||||
+NOT_YET_IMPLEMENTED_StmtImportFrom
|
+NOT_YET_IMPLEMENTED_StmtImportFrom
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ d={'a':1,
|
||||||
h: str = "",
|
h: str = "",
|
||||||
i: str = r"",
|
i: str = r"",
|
||||||
):
|
):
|
||||||
@@ -64,55 +86,55 @@
|
@@ -64,55 +86,54 @@
|
||||||
|
|
||||||
something = {
|
something = {
|
||||||
# fmt: off
|
# fmt: off
|
||||||
|
@ -327,8 +327,7 @@ d={'a':1,
|
||||||
+ "some big and",
|
+ "some big and",
|
||||||
+ "complex subscript",
|
+ "complex subscript",
|
||||||
+ # fmt: on
|
+ # fmt: on
|
||||||
+ goes
|
+ goes + here,
|
||||||
+ + here,
|
|
||||||
+ andhere,
|
+ andhere,
|
||||||
+ )
|
+ )
|
||||||
]
|
]
|
||||||
|
@ -382,7 +381,7 @@ d={'a':1,
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
@@ -133,10 +155,10 @@
|
@@ -133,10 +154,10 @@
|
||||||
"""Another known limitation."""
|
"""Another known limitation."""
|
||||||
# fmt: on
|
# fmt: on
|
||||||
# fmt: off
|
# fmt: off
|
||||||
|
@ -397,7 +396,7 @@ d={'a':1,
|
||||||
# fmt: on
|
# fmt: on
|
||||||
# fmt: off
|
# fmt: off
|
||||||
# ...but comments still get reformatted even though they should not be
|
# ...but comments still get reformatted even though they should not be
|
||||||
@@ -151,12 +173,10 @@
|
@@ -151,12 +172,10 @@
|
||||||
ast_args.kw_defaults,
|
ast_args.kw_defaults,
|
||||||
parameters,
|
parameters,
|
||||||
implicit_default=True,
|
implicit_default=True,
|
||||||
|
@ -412,17 +411,16 @@ d={'a':1,
|
||||||
# fmt: on
|
# fmt: on
|
||||||
_type_comment_re = re.compile(
|
_type_comment_re = re.compile(
|
||||||
r"""
|
r"""
|
||||||
@@ -179,7 +199,8 @@
|
@@ -179,7 +198,7 @@
|
||||||
$
|
$
|
||||||
""",
|
""",
|
||||||
# fmt: off
|
# fmt: off
|
||||||
- re.MULTILINE|re.VERBOSE
|
- re.MULTILINE|re.VERBOSE
|
||||||
+ re.MULTILINE
|
+ re.MULTILINE | re.VERBOSE,
|
||||||
+ | re.VERBOSE,
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -217,8 +238,7 @@
|
@@ -217,8 +236,7 @@
|
||||||
xxxxxxxxxx_xxxxxxxxxxx_xxxxxxx_xxxxxxxxx=5,
|
xxxxxxxxxx_xxxxxxxxxxx_xxxxxxx_xxxxxxxxx=5,
|
||||||
)
|
)
|
||||||
# fmt: off
|
# fmt: off
|
||||||
|
@ -538,8 +536,7 @@ def subscriptlist():
|
||||||
"some big and",
|
"some big and",
|
||||||
"complex subscript",
|
"complex subscript",
|
||||||
# fmt: on
|
# fmt: on
|
||||||
goes
|
goes + here,
|
||||||
+ here,
|
|
||||||
andhere,
|
andhere,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -640,8 +637,7 @@ def long_lines():
|
||||||
$
|
$
|
||||||
""",
|
""",
|
||||||
# fmt: off
|
# fmt: off
|
||||||
re.MULTILINE
|
re.MULTILINE | re.VERBOSE,
|
||||||
| re.VERBOSE,
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -111,14 +111,14 @@ def __await__(): return (yield)
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
-import asyncio
|
-import asyncio
|
||||||
-import sys
|
-import sys
|
||||||
-
|
|
||||||
-from third_party import X, Y, Z
|
|
||||||
+NOT_YET_IMPLEMENTED_StmtImport
|
+NOT_YET_IMPLEMENTED_StmtImport
|
||||||
+NOT_YET_IMPLEMENTED_StmtImport
|
+NOT_YET_IMPLEMENTED_StmtImport
|
||||||
|
|
||||||
-from library import some_connection, some_decorator
|
-from third_party import X, Y, Z
|
||||||
+NOT_YET_IMPLEMENTED_StmtImportFrom
|
+NOT_YET_IMPLEMENTED_StmtImportFrom
|
||||||
|
|
||||||
|
-from library import some_connection, some_decorator
|
||||||
|
-
|
||||||
-f"trigger 3.6 mode"
|
-f"trigger 3.6 mode"
|
||||||
+NOT_YET_IMPLEMENTED_StmtImportFrom
|
+NOT_YET_IMPLEMENTED_StmtImportFrom
|
||||||
+NOT_YET_IMPLEMENTED_ExprJoinedStr
|
+NOT_YET_IMPLEMENTED_ExprJoinedStr
|
||||||
|
@ -215,17 +215,7 @@ def __await__(): return (yield)
|
||||||
)
|
)
|
||||||
_type_comment_re = re.compile(
|
_type_comment_re = re.compile(
|
||||||
r"""
|
r"""
|
||||||
@@ -118,7 +124,8 @@
|
@@ -135,14 +141,8 @@
|
||||||
)
|
|
||||||
$
|
|
||||||
""",
|
|
||||||
- re.MULTILINE | re.VERBOSE,
|
|
||||||
+ re.MULTILINE
|
|
||||||
+ | re.VERBOSE,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -135,14 +142,8 @@
|
|
||||||
a,
|
a,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> A:
|
) -> A:
|
||||||
|
@ -373,8 +363,7 @@ def long_lines():
|
||||||
)
|
)
|
||||||
$
|
$
|
||||||
""",
|
""",
|
||||||
re.MULTILINE
|
re.MULTILINE | re.VERBOSE,
|
||||||
| re.VERBOSE,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -115,12 +115,13 @@ x[
|
||||||
ham[lower + offset : upper + offset]
|
ham[lower + offset : upper + offset]
|
||||||
|
|
||||||
slice[::, ::]
|
slice[::, ::]
|
||||||
@@ -50,10 +50,14 @@
|
@@ -49,11 +49,14 @@
|
||||||
|
|
||||||
slice[
|
slice[
|
||||||
# A
|
# A
|
||||||
1
|
- 1
|
||||||
- + 2 :
|
- + 2 :
|
||||||
+ + 2 :
|
+ 1 + 2 :
|
||||||
# B
|
# B
|
||||||
- 3 :
|
- 3 :
|
||||||
+ 3 :
|
+ 3 :
|
||||||
|
@ -189,8 +190,7 @@ slice[
|
||||||
|
|
||||||
slice[
|
slice[
|
||||||
# A
|
# A
|
||||||
1
|
1 + 2 :
|
||||||
+ 2 :
|
|
||||||
# B
|
# B
|
||||||
3 :
|
3 :
|
||||||
# C
|
# C
|
||||||
|
|
|
@ -16,6 +16,19 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression
|
||||||
b
|
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 own line comment
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Black breaks the right side first for the following expressions:
|
# Black breaks the right side first for the following expressions:
|
||||||
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(argument1, argument2, argument3)
|
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(argument1, argument2, argument3)
|
||||||
|
@ -204,7 +217,8 @@ for user_id in set(target_user_ids) - {u.user_id for u in updates}:
|
||||||
```py
|
```py
|
||||||
(
|
(
|
||||||
aaaaaaaa
|
aaaaaaaa
|
||||||
+ b # trailing operator comment # trailing right comment
|
+ # trailing operator comment
|
||||||
|
b # trailing right comment
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,6 +229,19 @@ for user_id in set(target_user_ids) - {u.user_id for u in updates}:
|
||||||
b
|
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 own line comment
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Black breaks the right side first for the following expressions:
|
# Black breaks the right side first for the following expressions:
|
||||||
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(
|
aaaaaaaaaaaaaa + caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal(
|
||||||
|
@ -269,8 +296,7 @@ not (aaaaaaaaaaaaaa + {NOT_IMPLEMENTED_set_value for value in NOT_IMPLEMENTED_se
|
||||||
# leading comment
|
# leading comment
|
||||||
(
|
(
|
||||||
# comment
|
# comment
|
||||||
content
|
content + b
|
||||||
+ b
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,8 +443,7 @@ if (
|
||||||
&
|
&
|
||||||
(
|
(
|
||||||
# comment
|
# comment
|
||||||
a
|
a + b
|
||||||
+ b
|
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
@ -433,8 +458,7 @@ if (
|
||||||
]
|
]
|
||||||
&
|
&
|
||||||
# comment
|
# comment
|
||||||
a
|
a + b
|
||||||
+ b
|
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,10 @@ if (
|
||||||
if not \
|
if not \
|
||||||
a:
|
a:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Regression: https://github.com/astral-sh/ruff/issues/5338
|
||||||
|
if a and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
|
||||||
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
@ -253,10 +257,8 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & (
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if (
|
if (
|
||||||
not (
|
not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|
||||||
)
|
|
||||||
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
@ -295,6 +297,14 @@ if (
|
||||||
|
|
||||||
if not a:
|
if not a:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Regression: https://github.com/astral-sh/ruff/issues/5338
|
||||||
|
if (
|
||||||
|
a
|
||||||
|
and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
):
|
||||||
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,8 +125,7 @@ f(
|
||||||
f(
|
f(
|
||||||
this_is_a_very_long_argument_asökdhflakjslaslhfdlaffahflahsöfdhasägporejfäalkdsjäfalisjäfdlkasjd,
|
this_is_a_very_long_argument_asökdhflakjslaslhfdlaffahflahsöfdhasägporejfäalkdsjäfalisjäfdlkasjd,
|
||||||
these_arguments_have_values_that_need_to_break_because_they_are_too_long1=(
|
these_arguments_have_values_that_need_to_break_because_they_are_too_long1=(
|
||||||
100000
|
100000 - 100000000000
|
||||||
- 100000000000
|
|
||||||
),
|
),
|
||||||
these_arguments_have_values_that_need_to_break_because_they_are_too_long2="akshfdlakjsdfad"
|
these_arguments_have_values_that_need_to_break_because_they_are_too_long2="akshfdlakjsdfad"
|
||||||
+ "asdfasdfa",
|
+ "asdfasdfa",
|
||||||
|
|
|
@ -38,6 +38,9 @@ class Test((Aaaa)):
|
||||||
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
|
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
|
||||||
|
pass
|
||||||
|
|
||||||
class Test(Aaaa): # trailing comment
|
class Test(Aaaa): # trailing comment
|
||||||
pass
|
pass
|
||||||
```
|
```
|
||||||
|
@ -88,6 +91,17 @@ class Test(
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Test(
|
||||||
|
aaaaaaaaaaaaaaa
|
||||||
|
+ bbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccc
|
||||||
|
+ dddddddddddddddddddddd
|
||||||
|
+ eeeeeeeee,
|
||||||
|
ffffffffffffffffff,
|
||||||
|
gggggggggggggggggg,
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Test(Aaaa): # trailing comment
|
class Test(Aaaa): # trailing comment
|
||||||
pass
|
pass
|
||||||
```
|
```
|
||||||
|
|
|
@ -114,8 +114,7 @@ with a: # should remove brackets
|
||||||
# WithItem allow the `aa + bb` content expression to be wrapped
|
# WithItem allow the `aa + bb` content expression to be wrapped
|
||||||
with (
|
with (
|
||||||
(
|
(
|
||||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|
||||||
) as c,
|
) as c,
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue