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

Improve dummy_implementations preview style formatting #9240

Merged
merged 1 commit into from Dec 22, 2023
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
Expand Up @@ -253,4 +253,23 @@ def y():
# empty line(s) at the end of the file due to nested function
if True:
def nested_trailing_function():
pass
pass


def overload1(): ... # trailing comment
def overload1(a: int): ...

def overload2(): ... # trailing comment

def overload2(a: int): ...

def overload3():
...
# trailing comment
def overload3(a: int): ...

def overload4():
...
# trailing comment

def overload4(a: int): ...
10 changes: 7 additions & 3 deletions crates/ruff_python_formatter/src/statement/clause.rs
Expand Up @@ -392,9 +392,13 @@ pub(crate) fn clause_body<'a>(

impl Format<PyFormatContext<'_>> for FormatClauseBody<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
// In stable, stubs are only collapsed in stub files, in preview this is consistently
// applied everywhere
if (f.options().source_type().is_stub() || is_dummy_implementations_enabled(f.context()))
// 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));

if should_collapse_stub
&& contains_only_an_ellipsis(self.body, f.context().comments())
&& self.trailing_comments.is_empty()
{
Expand Down
34 changes: 27 additions & 7 deletions crates/ruff_python_formatter/src/statement/suite.rs
Expand Up @@ -12,7 +12,8 @@ use crate::context::{NodeLevel, TopLevelStatementPosition, WithIndentLevel, With
use crate::expression::expr_string_literal::ExprStringLiteralKind;
use crate::prelude::*;
use crate::preview::{
is_module_docstring_newlines_enabled, is_no_blank_line_before_class_docstring_enabled,
is_dummy_implementations_enabled, is_module_docstring_newlines_enabled,
is_no_blank_line_before_class_docstring_enabled,
};
use crate::statement::stmt_expr::FormatStmtExpr;
use crate::verbatim::{
Expand Down Expand Up @@ -261,12 +262,31 @@ impl FormatRule<Suite, PyFormatContext<'_>> for FormatSuite {
f,
)?;
} else {
match self.kind {
SuiteKind::TopLevel => {
write!(f, [empty_line(), empty_line()])?;
}
SuiteKind::Function | SuiteKind::Class | SuiteKind::Other => {
empty_line().fmt(f)?;
// Preserve empty lines after a stub implementation but don't insert a new one if there isn't any present in the source.
// This is useful when having multiple function overloads that should be grouped to getter by omitting new lines between them.
let is_preceding_stub_function_without_empty_line =
is_dummy_implementations_enabled(f.context())
&& following.is_function_def_stmt()
&& preceding
.as_function_def_stmt()
.is_some_and(|preceding_stub| {
contains_only_an_ellipsis(
&preceding_stub.body,
f.context().comments(),
) && lines_after_ignoring_end_of_line_trivia(
preceding_stub.end(),
f.context().source(),
) < 2
});

if !is_preceding_stub_function_without_empty_line {
match self.kind {
SuiteKind::TopLevel => {
write!(f, [empty_line(), empty_line()])?;
}
SuiteKind::Function | SuiteKind::Class | SuiteKind::Other => {
empty_line().fmt(f)?;
}
}
}
}
Expand Down

This file was deleted.