Improve dummy_implementations preview style formatting (#9240)

This commit is contained in:
Micha Reiser 2023-12-22 12:44:14 +09:00 committed by GitHub
parent a06723da2b
commit 9cc257ee7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 294 deletions

View file

@ -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()
{

View file

@ -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::{
@ -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)?;
}
}
}
}