Skip to content

Commit 26800c0

Browse files
authored
Ruff 2025 style guide (#13906)
Closes #13371
1 parent 0837cdd commit 26800c0

File tree

62 files changed

+1789
-3880
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1789
-3880
lines changed

crates/ruff_python_formatter/generate.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ def rustfmt(code: str) -> str:
3737
# `FStringLiteralElement`, `FStringFormatSpec` and `FStringExpressionElement` are handled by the `FString`
3838
# implementation.
3939
if node in (
40-
"FString",
4140
"FStringLiteralElement",
4241
"FStringExpressionElement",
4342
"FStringFormatSpec",

crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/join_implicit_concatenated_string.options.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/join_implicit_concatenated_string_assignment.options.json

Lines changed: 0 additions & 5 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
[
22
{
3-
"quote_style": "preserve",
4-
"preview": "enabled"
3+
"quote_style": "preserve"
54
},
65
{
76
"quote_style": "preserve",
8-
"preview": "enabled",
97
"target_version": "py312"
108
}
119
]
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[
22
{
3-
"preview": "enabled",
43
"source_type": "Stub"
54
}
65
]

crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.options.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

crates/ruff_python_formatter/src/expression/expr_f_string.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use ruff_python_ast::{AnyNodeRef, ExprFString, StringLike};
2-
use ruff_text_size::TextSlice;
32

43
use crate::expression::parentheses::{
54
in_parentheses_only_group, NeedsParentheses, OptionalParentheses,
65
};
7-
use crate::other::f_string::{FStringLayout, FormatFString};
6+
use crate::other::f_string::FStringLayout;
87
use crate::prelude::*;
98
use crate::string::implicit::{
109
FormatImplicitConcatenatedString, FormatImplicitConcatenatedStringFlat,
1110
};
12-
use crate::string::{Quoting, StringLikeExtensions};
11+
use crate::string::StringLikeExtensions;
1312

1413
#[derive(Default)]
1514
pub struct FormatExprFString;
@@ -23,7 +22,7 @@ impl FormatNodeRule<ExprFString> for FormatExprFString {
2322
// [`ruff_python_ast::FStringValue::single`] constructor.
2423
let f_string = f_string_part.as_f_string().unwrap();
2524

26-
FormatFString::new(f_string, f_string_quoting(item, f.context().source())).fmt(f)
25+
f_string.format().fmt(f)
2726
} else {
2827
// Always join fstrings that aren't parenthesized and thus, are always on a single line.
2928
if !f.context().node_level().is_parenthesized() {
@@ -58,28 +57,3 @@ impl NeedsParentheses for ExprFString {
5857
}
5958
}
6059
}
61-
62-
pub(crate) fn f_string_quoting(f_string: &ExprFString, source: &str) -> Quoting {
63-
let unprefixed = source
64-
.slice(f_string)
65-
.trim_start_matches(|c| c != '"' && c != '\'');
66-
let triple_quoted = unprefixed.starts_with(r#"""""#) || unprefixed.starts_with(r"'''");
67-
68-
if f_string
69-
.value
70-
.elements()
71-
.filter_map(|element| element.as_expression())
72-
.any(|expression| {
73-
let string_content = source.slice(expression);
74-
if triple_quoted {
75-
string_content.contains(r#"""""#) || string_content.contains("'''")
76-
} else {
77-
string_content.contains(['"', '\''])
78-
}
79-
})
80-
{
81-
Quoting::Preserve
82-
} else {
83-
Quoting::CanChange
84-
}
85-
}

crates/ruff_python_formatter/src/expression/expr_subscript.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::expression::parentheses::{
88
};
99
use crate::expression::CallChainLayout;
1010
use crate::prelude::*;
11-
use crate::preview::is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled;
1211

1312
#[derive(Default)]
1413
pub struct FormatExprSubscript {
@@ -108,13 +107,14 @@ impl NeedsParentheses for ExprSubscript {
108107
if function.returns.as_deref().is_some_and(|returns| {
109108
AnyNodeRef::ptr_eq(returns.into(), self.into())
110109
}) {
111-
if is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled(context) &&
112-
function.parameters.is_empty() && !context.comments().has(&*function.parameters) {
110+
if function.parameters.is_empty()
111+
&& !context.comments().has(&*function.parameters)
112+
{
113113
// Apply the `optional_parentheses` layout when the subscript
114114
// is in a return type position of a function without parameters.
115115
// This ensures the subscript is parenthesized if it has a very
116116
// long name that goes over the line length limit.
117-
return OptionalParentheses::Multiline
117+
return OptionalParentheses::Multiline;
118118
}
119119

120120
// Don't use the best fitting layout for return type annotation because it results in the

crates/ruff_python_formatter/src/expression/mod.rs

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ use crate::expression::parentheses::{
1919
OptionalParentheses, Parentheses, Parenthesize,
2020
};
2121
use crate::prelude::*;
22-
use crate::preview::{
23-
is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled,
24-
is_f_string_formatting_enabled, is_hug_parens_with_braces_and_square_brackets_enabled,
25-
};
22+
use crate::preview::is_hug_parens_with_braces_and_square_brackets_enabled;
2623

2724
mod binary_like;
2825
pub(crate) mod expr_attribute;
@@ -388,18 +385,12 @@ impl Format<PyFormatContext<'_>> for MaybeParenthesizeExpression<'_> {
388385
// is parenthesized. Unless, it's the `Parenthesize::IfBreaksParenthesizedNested` layout
389386
// where parenthesizing nested `maybe_parenthesized_expression` is explicitly desired.
390387
_ if f.context().node_level().is_parenthesized() => {
391-
if !is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled(
392-
f.context(),
393-
) {
394-
OptionalParentheses::Never
395-
} else if matches!(parenthesize, Parenthesize::IfBreaksParenthesizedNested) {
396-
return parenthesize_if_expands(
397-
&expression.format().with_options(Parentheses::Never),
398-
)
399-
.with_indent(!is_expression_huggable(expression, f.context()))
400-
.fmt(f);
388+
return if matches!(parenthesize, Parenthesize::IfBreaksParenthesizedNested) {
389+
parenthesize_if_expands(&expression.format().with_options(Parentheses::Never))
390+
.with_indent(!is_expression_huggable(expression, f.context()))
391+
.fmt(f)
401392
} else {
402-
return expression.format().with_options(Parentheses::Never).fmt(f);
393+
expression.format().with_options(Parentheses::Never).fmt(f)
403394
}
404395
}
405396
needs_parentheses => needs_parentheses,
@@ -409,13 +400,12 @@ impl Format<PyFormatContext<'_>> for MaybeParenthesizeExpression<'_> {
409400

410401
match needs_parentheses {
411402
OptionalParentheses::Multiline => match parenthesize {
412-
Parenthesize::IfBreaksParenthesized | Parenthesize::IfBreaksParenthesizedNested if !is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled(f.context()) => {
413-
parenthesize_if_expands(&unparenthesized).fmt(f)
414-
}
415-
416403
Parenthesize::IfRequired => unparenthesized.fmt(f),
417404

418-
Parenthesize::Optional | Parenthesize::IfBreaks | Parenthesize::IfBreaksParenthesized | Parenthesize::IfBreaksParenthesizedNested => {
405+
Parenthesize::Optional
406+
| Parenthesize::IfBreaks
407+
| Parenthesize::IfBreaksParenthesized
408+
| Parenthesize::IfBreaksParenthesizedNested => {
419409
if can_omit_optional_parentheses(expression, f.context()) {
420410
optional_parentheses(&unparenthesized).fmt(f)
421411
} else {
@@ -424,9 +414,6 @@ impl Format<PyFormatContext<'_>> for MaybeParenthesizeExpression<'_> {
424414
}
425415
},
426416
OptionalParentheses::BestFit => match parenthesize {
427-
Parenthesize::IfBreaksParenthesized | Parenthesize::IfBreaksParenthesizedNested if !is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled(f.context()) =>
428-
parenthesize_if_expands(&unparenthesized).fmt(f),
429-
430417
Parenthesize::IfBreaksParenthesized | Parenthesize::IfBreaksParenthesizedNested => {
431418
// Can-omit layout is relevant for `"abcd".call`. We don't want to add unnecessary
432419
// parentheses in this case.
@@ -454,15 +441,11 @@ impl Format<PyFormatContext<'_>> for MaybeParenthesizeExpression<'_> {
454441
}
455442
},
456443
OptionalParentheses::Never => match parenthesize {
457-
Parenthesize::IfBreaksParenthesized | Parenthesize::IfBreaksParenthesizedNested if !is_empty_parameters_no_unnecessary_parentheses_around_return_value_enabled(f.context()) => {
458-
parenthesize_if_expands(&unparenthesized)
459-
.with_indent(!is_expression_huggable(expression, f.context()))
460-
.fmt(f)
461-
}
462-
463-
Parenthesize::Optional | Parenthesize::IfBreaks | Parenthesize::IfRequired | Parenthesize::IfBreaksParenthesized | Parenthesize::IfBreaksParenthesizedNested => {
464-
unparenthesized.fmt(f)
465-
}
444+
Parenthesize::Optional
445+
| Parenthesize::IfBreaks
446+
| Parenthesize::IfRequired
447+
| Parenthesize::IfBreaksParenthesized
448+
| Parenthesize::IfBreaksParenthesizedNested => unparenthesized.fmt(f),
466449
},
467450

468451
OptionalParentheses::Always => {
@@ -766,32 +749,6 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> {
766749
return;
767750
}
768751

769-
Expr::StringLiteral(ast::ExprStringLiteral { value, .. })
770-
if value.is_implicit_concatenated() =>
771-
{
772-
if !is_f_string_formatting_enabled(self.context) {
773-
self.update_max_precedence(OperatorPrecedence::String);
774-
}
775-
776-
return;
777-
}
778-
Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. })
779-
if value.is_implicit_concatenated() =>
780-
{
781-
if !is_f_string_formatting_enabled(self.context) {
782-
self.update_max_precedence(OperatorPrecedence::String);
783-
}
784-
785-
return;
786-
}
787-
Expr::FString(ast::ExprFString { value, .. }) if value.is_implicit_concatenated() => {
788-
if !is_f_string_formatting_enabled(self.context) {
789-
self.update_max_precedence(OperatorPrecedence::String);
790-
}
791-
792-
return;
793-
}
794-
795752
// Non terminal nodes that don't have a termination token.
796753
Expr::Named(_) | Expr::Generator(_) | Expr::Tuple(_) => {}
797754

@@ -1193,8 +1150,6 @@ enum OperatorPrecedence {
11931150
BitwiseXor,
11941151
BitwiseOr,
11951152
Comparator,
1196-
// Implicit string concatenation
1197-
String,
11981153
BooleanOperation,
11991154
Conditional,
12001155
}

crates/ruff_python_formatter/src/generated.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,6 +2935,34 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
29352935
}
29362936
}
29372937

2938+
impl FormatRule<ast::FString, PyFormatContext<'_>> for crate::other::f_string::FormatFString {
2939+
#[inline]
2940+
fn fmt(&self, node: &ast::FString, f: &mut PyFormatter) -> FormatResult<()> {
2941+
FormatNodeRule::<ast::FString>::fmt(self, node, f)
2942+
}
2943+
}
2944+
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::FString {
2945+
type Format<'a> = FormatRefWithRule<
2946+
'a,
2947+
ast::FString,
2948+
crate::other::f_string::FormatFString,
2949+
PyFormatContext<'ast>,
2950+
>;
2951+
fn format(&self) -> Self::Format<'_> {
2952+
FormatRefWithRule::new(self, crate::other::f_string::FormatFString::default())
2953+
}
2954+
}
2955+
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::FString {
2956+
type Format = FormatOwnedWithRule<
2957+
ast::FString,
2958+
crate::other::f_string::FormatFString,
2959+
PyFormatContext<'ast>,
2960+
>;
2961+
fn into_format(self) -> Self::Format {
2962+
FormatOwnedWithRule::new(self, crate::other::f_string::FormatFString::default())
2963+
}
2964+
}
2965+
29382966
impl FormatRule<ast::StringLiteral, PyFormatContext<'_>>
29392967
for crate::other::string_literal::FormatStringLiteral
29402968
{

0 commit comments

Comments
 (0)