Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruff 2024.2 style #9639

Merged
merged 1 commit into from Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
90 changes: 42 additions & 48 deletions crates/ruff/tests/format.rs
Expand Up @@ -358,58 +358,52 @@ def f(x):
'''
pass
"#), @r###"
success: true
exit_code: 0
----- stdout -----
def f(x):
"""
Something about `f`. And an example:

.. code-block:: python

(
foo,
bar,
quux,
) = this_is_a_long_line(
lion,
hippo,
lemur,
bear,
success: true
exit_code: 0
----- stdout -----
def f(x):
"""
Something about `f`. And an example:

.. code-block:: python

foo, bar, quux = (
this_is_a_long_line(
lion,
hippo,
lemur,
bear,
)
)

Another example:

```py
foo, bar, quux = (
this_is_a_long_line(
lion,
hippo,
lemur,
bear,
)
)
```

Another example:
And another:

```py
(
foo,
bar,
quux,
) = this_is_a_long_line(
lion,
hippo,
lemur,
bear,
)
```

And another:
>>> foo, bar, quux = (
... this_is_a_long_line(
... lion,
... hippo,
... lemur,
... bear,
... )
... )
"""
pass

>>> (
... foo,
... bar,
... quux,
... ) = this_is_a_long_line(
... lion,
... hippo,
... lemur,
... bear,
... )
"""
pass

----- stderr -----
"###);
----- stderr -----
"###);
Ok(())
}

Expand Down
6 changes: 1 addition & 5 deletions crates/ruff_python_formatter/src/comments/format.rs
Expand Up @@ -10,7 +10,6 @@ use ruff_text_size::{Ranged, TextLen, TextRange};
use crate::comments::SourceComment;
use crate::context::NodeLevel;
use crate::prelude::*;
use crate::preview::is_blank_line_after_nested_stub_class_enabled;
use crate::statement::suite::should_insert_blank_line_after_class_in_stub_file;

/// Formats the leading comments of a node.
Expand Down Expand Up @@ -544,10 +543,7 @@ pub(crate) fn empty_lines_before_trailing_comments<'a>(
// Black has different rules for stub vs. non-stub and top level vs. indented
let empty_lines = match (f.options().source_type(), f.context().node_level()) {
(PySourceType::Stub, NodeLevel::TopLevel(_)) => 1,
(PySourceType::Stub, _) => u32::from(
is_blank_line_after_nested_stub_class_enabled(f.context())
&& node_kind == NodeKind::StmtClassDef,
),
(PySourceType::Stub, _) => u32::from(node_kind == NodeKind::StmtClassDef),
(_, NodeLevel::TopLevel(_)) => 2,
(_, _) => 1,
};
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_python_formatter/src/context.rs
Expand Up @@ -99,6 +99,7 @@ impl<'a> PyFormatContext<'a> {
}

/// Returns `true` if preview mode is enabled.
#[allow(unused)]
pub(crate) const fn is_preview(&self) -> bool {
self.options.preview().is_enabled()
}
Expand Down
Expand Up @@ -20,7 +20,6 @@ use crate::expression::parentheses::{
};
use crate::expression::OperatorPrecedence;
use crate::prelude::*;
use crate::preview::is_fix_power_op_line_length_enabled;
use crate::string::{AnyString, FormatStringContinuation};

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -722,9 +721,7 @@ impl Format<PyFormatContext<'_>> for FlatBinaryExpressionSlice<'_> {
{
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)?;
}
in_parentheses_only_if_group_breaks(&space()).fmt(f)?;
} else {
space().fmt(f)?;
}
Expand Down
5 changes: 0 additions & 5 deletions crates/ruff_python_formatter/src/other/arguments.rs
Expand Up @@ -9,7 +9,6 @@ use crate::expression::is_expression_huggable;
use crate::expression::parentheses::{empty_parenthesized, parenthesized, Parentheses};
use crate::other::commas;
use crate::prelude::*;
use crate::preview::is_multiline_string_handling_enabled;
use crate::string::AnyString;

#[derive(Default)]
Expand Down Expand Up @@ -238,10 +237,6 @@ fn is_huggable_string_argument(
arguments: &Arguments,
context: &PyFormatContext,
) -> bool {
if !is_multiline_string_handling_enabled(context) {
return false;
}

if string.is_implicit_concatenated() || !string.is_multiline(context.source()) {
return false;
}
Expand Down
2 changes: 0 additions & 2 deletions crates/ruff_python_formatter/src/other/f_string_element.rs
Expand Up @@ -9,7 +9,6 @@ use ruff_text_size::Ranged;
use crate::comments::{dangling_open_parenthesis_comments, trailing_comments};
use crate::context::{FStringState, NodeLevel, WithFStringState, WithNodeLevel};
use crate::prelude::*;
use crate::preview::is_hex_codes_in_unicode_sequences_enabled;
use crate::string::normalize_string;
use crate::verbatim::verbatim_text;

Expand Down Expand Up @@ -62,7 +61,6 @@ impl Format<PyFormatContext<'_>> for FormatFStringLiteralElement<'_> {
0,
self.context.quotes(),
self.context.prefix(),
is_hex_codes_in_unicode_sequences_enabled(f.context()),
true,
);
match &normalized {
Expand Down
5 changes: 1 addition & 4 deletions crates/ruff_python_formatter/src/other/with_item.rs
Expand Up @@ -7,7 +7,6 @@ use crate::expression::parentheses::{
is_expression_parenthesized, parenthesized, Parentheses, Parenthesize,
};
use crate::prelude::*;
use crate::preview::is_wrap_multiple_context_managers_in_parens_enabled;

#[derive(Default)]
pub struct FormatWithItem;
Expand All @@ -30,9 +29,7 @@ impl FormatNodeRule<WithItem> for FormatWithItem {
);

// Remove the parentheses of the `with_items` if the with statement adds parentheses
if f.context().node_level().is_parenthesized()
&& is_wrap_multiple_context_managers_in_parens_enabled(f.context())
{
if f.context().node_level().is_parenthesized() {
if is_parenthesized {
// ...except if the with item is parenthesized, then use this with item as a preferred breaking point
// or when it has comments, then parenthesize it to prevent comments from moving.
Expand Down
70 changes: 1 addition & 69 deletions crates/ruff_python_formatter/src/preview.rs
Expand Up @@ -4,12 +4,8 @@
//! to stable. The challenge with directly using [`is_preview`](PyFormatContext::is_preview) is that it is unclear
//! for which specific feature this preview check is for. Having named functions simplifies the promotion:
//! Simply delete the function and let Rust tell you which checks you have to remove.
use crate::PyFormatContext;

/// Returns `true` if the [`fix_power_op_line_length`](https://github.com/astral-sh/ruff/issues/8938) preview style is enabled.
pub(crate) const fn is_fix_power_op_line_length_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}
use crate::PyFormatContext;

/// Returns `true` if the [`hug_parens_with_braces_and_square_brackets`](https://github.com/astral-sh/ruff/issues/8279) preview style is enabled.
pub(crate) const fn is_hug_parens_with_braces_and_square_brackets_enabled(
Expand All @@ -18,70 +14,6 @@ pub(crate) const fn is_hug_parens_with_braces_and_square_brackets_enabled(
context.is_preview()
}

/// Returns `true` if the [`prefer_splitting_right_hand_side_of_assignments`](https://github.com/astral-sh/ruff/issues/6975) preview style is enabled.
pub(crate) const fn is_prefer_splitting_right_hand_side_of_assignments_enabled(
context: &PyFormatContext,
) -> bool {
context.is_preview()
}

/// Returns `true` if the [`parenthesize_long_type_hints`](https://github.com/astral-sh/ruff/issues/8894) preview style is enabled.
pub(crate) const fn is_parenthesize_long_type_hints_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}

/// Returns `true` if the [`no_blank_line_before_class_docstring`] preview style is enabled.
///
/// [`no_blank_line_before_class_docstring`]: https://github.com/astral-sh/ruff/issues/8888
pub(crate) const fn is_no_blank_line_before_class_docstring_enabled(
context: &PyFormatContext,
) -> bool {
context.is_preview()
}

/// Returns `true` if the [`wrap_multiple_context_managers_in_parens`](https://github.com/astral-sh/ruff/issues/8889) preview style is enabled.
///
/// Unlike Black, we re-use the same preview style feature flag for [`improved_async_statements_handling`](https://github.com/astral-sh/ruff/issues/8890)
pub(crate) const fn is_wrap_multiple_context_managers_in_parens_enabled(
context: &PyFormatContext,
) -> bool {
context.is_preview()
}

/// Returns `true` if the [`blank_line_after_nested_stub_class`](https://github.com/astral-sh/ruff/issues/8891) preview style is enabled.
pub(crate) const fn is_blank_line_after_nested_stub_class_enabled(
context: &PyFormatContext,
) -> bool {
context.is_preview()
}

/// Returns `true` if the [`module_docstring_newlines`](https://github.com/astral-sh/ruff/issues/7995) preview style is enabled.
pub(crate) const fn is_module_docstring_newlines_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}

/// Returns `true` if the [`dummy_implementations`](https://github.com/astral-sh/ruff/issues/8357) preview style is enabled.
pub(crate) const fn is_dummy_implementations_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}

/// Returns `true` if the [`hex_codes_in_unicode_sequences`](https://github.com/psf/black/pull/2916) preview style is enabled.
pub(crate) const fn is_hex_codes_in_unicode_sequences_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}

/// Returns `true` if the [`multiline_string_handling`](https://github.com/astral-sh/ruff/issues/8896) preview style is enabled.
pub(crate) const fn is_multiline_string_handling_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}

/// Returns `true` if the [`multiline_string_handling`](https://github.com/astral-sh/ruff/pull/9725) preview style is enabled.
/// Black does not [`format docstrings`](https://github.com/psf/black/issues/3493) so we keep this
/// preview for compatibility with Black.
pub(crate) const fn is_format_module_docstring_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}

/// Returns `true` if the [`f-string formatting`](https://github.com/astral-sh/ruff/issues/7594) preview style is enabled.
pub(crate) fn is_f_string_formatting_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
Expand Down
4 changes: 1 addition & 3 deletions crates/ruff_python_formatter/src/statement/clause.rs
Expand Up @@ -8,7 +8,6 @@ use ruff_python_trivia::{SimpleToken, SimpleTokenKind, SimpleTokenizer};
use ruff_text_size::{Ranged, TextRange, TextSize};

use crate::comments::{leading_alternate_branch_comments, trailing_comments, SourceComment};
use crate::preview::is_dummy_implementations_enabled;
use crate::statement::suite::{contains_only_an_ellipsis, SuiteKind};
use crate::verbatim::write_suppressed_clause_header;
use crate::{has_skip_comment, prelude::*};
Expand Down Expand Up @@ -405,8 +404,7 @@ impl Format<PyFormatContext<'_>> for FormatClauseBody<'_> {
// In stable, stubs are only collapsed in stub files, in preview stubs in functions
// or classes are collapsed too
let should_collapse_stub = f.options().source_type().is_stub()
|| (is_dummy_implementations_enabled(f.context())
&& matches!(self.kind, SuiteKind::Function | SuiteKind::Class));
|| matches!(self.kind, SuiteKind::Function | SuiteKind::Class);

if should_collapse_stub
&& contains_only_an_ellipsis(self.body, f.context().comments())
Expand Down
47 changes: 15 additions & 32 deletions crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs
Expand Up @@ -2,12 +2,8 @@ use ruff_formatter::write;
use ruff_python_ast::StmtAnnAssign;

use crate::comments::SourceComment;
use crate::expression::is_splittable_expression;
use crate::expression::parentheses::Parentheses;
use crate::expression::{has_parentheses, is_splittable_expression};
use crate::preview::{
is_parenthesize_long_type_hints_enabled,
is_prefer_splitting_right_hand_side_of_assignments_enabled,
};
use crate::statement::stmt_assign::{
AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression,
};
Expand All @@ -30,13 +26,7 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
write!(f, [target.format(), token(":"), space()])?;

if let Some(value) = value {
if is_prefer_splitting_right_hand_side_of_assignments_enabled(f.context())
// The `has_parentheses` check can be removed when stabilizing `is_parenthesize_long_type_hints`.
// because `is_splittable_expression` covers both.
&& (has_parentheses(annotation, f.context()).is_some()
|| (is_parenthesize_long_type_hints_enabled(f.context())
&& is_splittable_expression(annotation, f.context())))
{
if is_splittable_expression(annotation, f.context()) {
FormatStatementsLastExpression::RightToLeft {
before_operator: AnyBeforeOperator::Expression(annotation),
operator: AnyAssignmentOperator::Assign,
Expand All @@ -47,23 +37,20 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
} else {
// Remove unnecessary parentheses around the annotation if the parenthesize long type hints preview style is enabled.
// Ensure we keep the parentheses if the annotation has any comments.
if is_parenthesize_long_type_hints_enabled(f.context()) {
if f.context().comments().has_leading(annotation.as_ref())
|| f.context().comments().has_trailing(annotation.as_ref())
{
annotation
.format()
.with_options(Parentheses::Always)
.fmt(f)?;
} else {
annotation
.format()
.with_options(Parentheses::Never)
.fmt(f)?;
}
if f.context().comments().has_leading(annotation.as_ref())
|| f.context().comments().has_trailing(annotation.as_ref())
{
annotation
.format()
.with_options(Parentheses::Always)
.fmt(f)?;
} else {
annotation.format().fmt(f)?;
annotation
.format()
.with_options(Parentheses::Never)
.fmt(f)?;
}

write!(
f,
[
Expand All @@ -83,11 +70,7 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
// Decimal # the user's age, used to determine if it's safe for them to use ruff
// )
// ```
if is_parenthesize_long_type_hints_enabled(f.context()) {
FormatStatementsLastExpression::left_to_right(annotation, item).fmt(f)?;
} else {
annotation.format().fmt(f)?;
}
FormatStatementsLastExpression::left_to_right(annotation, item).fmt(f)?;
}

if f.options().source_type().is_ipynb()
Expand Down