avoid extra parentheses for nested collections
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use ruff_formatter::{Buffer, FormatResult, format_args, write};
|
||||
use ruff_python_ast::{Comprehension, Expr};
|
||||
use ruff_python_ast::{self as ast, Comprehension, Expr};
|
||||
use ruff_python_trivia::{SimpleTokenKind, find_only_token_in_range};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
@@ -117,7 +117,11 @@ impl FormatNodeRule<Comprehension> for FormatComprehension {
|
||||
maybe_parenthesize_expression(
|
||||
iter,
|
||||
item,
|
||||
Parenthesize::IfBreaksParenthesizedNested
|
||||
if needs_nested_parentheses(iter) {
|
||||
Parenthesize::IfBreaksParenthesizedNested
|
||||
} else {
|
||||
Parenthesize::IfBreaks
|
||||
}
|
||||
)
|
||||
]
|
||||
)?;
|
||||
@@ -188,3 +192,68 @@ impl Format<PyFormatContext<'_>> for ExprTupleWithoutParentheses<'_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the expression needs additional parentheses when used as the `in` clause of a
|
||||
/// comprehension.
|
||||
///
|
||||
/// For example, we need to parenthesize a long attribute expression:
|
||||
///
|
||||
/// ```python
|
||||
/// [
|
||||
/// a
|
||||
/// for graph_path_expression in (
|
||||
/// refined_constraint.condition_as_predicate.variables
|
||||
/// )
|
||||
/// ]
|
||||
/// ```
|
||||
///
|
||||
/// but avoid adding additional parentheses to a set or other collection:
|
||||
///
|
||||
/// ```python
|
||||
/// [
|
||||
/// x
|
||||
/// for x in { # _not_ `({`
|
||||
/// x
|
||||
/// for x in "long line long line long line long line long line long line long line"
|
||||
/// }
|
||||
/// ]
|
||||
/// ```
|
||||
fn needs_nested_parentheses(expr: &Expr) -> bool {
|
||||
match expr {
|
||||
Expr::Tuple(_)
|
||||
| Expr::List(_)
|
||||
| Expr::Set(_)
|
||||
| Expr::Dict(_)
|
||||
| Expr::ListComp(_)
|
||||
| Expr::SetComp(_)
|
||||
| Expr::DictComp(_) => false,
|
||||
|
||||
Expr::Starred(ast::ExprStarred { value, .. }) => needs_nested_parentheses(value),
|
||||
|
||||
Expr::BoolOp(_)
|
||||
| Expr::Named(_)
|
||||
| Expr::BinOp(_)
|
||||
| Expr::UnaryOp(_)
|
||||
| Expr::Lambda(_)
|
||||
| Expr::If(_)
|
||||
| Expr::Generator(_)
|
||||
| Expr::Await(_)
|
||||
| Expr::Yield(_)
|
||||
| Expr::YieldFrom(_)
|
||||
| Expr::Compare(_)
|
||||
| Expr::Call(_)
|
||||
| Expr::Attribute(_)
|
||||
| Expr::Subscript(_)
|
||||
| Expr::Name(_)
|
||||
| Expr::Slice(_)
|
||||
| Expr::IpyEscapeCommand(_)
|
||||
| Expr::NumberLiteral(_)
|
||||
| Expr::BooleanLiteral(_)
|
||||
| Expr::NoneLiteral(_)
|
||||
| Expr::StringLiteral(_)
|
||||
| Expr::BytesLiteral(_)
|
||||
| Expr::FString(_)
|
||||
| Expr::TString(_)
|
||||
| Expr::EllipsisLiteral(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user