mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
Improve dummy_implementations
preview style formatting (#9240)
This commit is contained in:
parent
a06723da2b
commit
9cc257ee7d
6 changed files with 159 additions and 294 deletions
|
@ -253,4 +253,23 @@ if True:
|
||||||
# empty line(s) at the end of the file due to nested function
|
# empty line(s) at the end of the file due to nested function
|
||||||
if True:
|
if True:
|
||||||
def nested_trailing_function():
|
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): ...
|
||||||
|
|
|
@ -392,9 +392,13 @@ pub(crate) fn clause_body<'a>(
|
||||||
|
|
||||||
impl Format<PyFormatContext<'_>> for FormatClauseBody<'_> {
|
impl Format<PyFormatContext<'_>> for FormatClauseBody<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||||
// In stable, stubs are only collapsed in stub files, in preview this is consistently
|
// In stable, stubs are only collapsed in stub files, in preview stubs in functions
|
||||||
// applied everywhere
|
// or classes are collapsed too
|
||||||
if (f.options().source_type().is_stub() || is_dummy_implementations_enabled(f.context()))
|
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())
|
&& contains_only_an_ellipsis(self.body, f.context().comments())
|
||||||
&& self.trailing_comments.is_empty()
|
&& self.trailing_comments.is_empty()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,8 @@ use crate::context::{NodeLevel, TopLevelStatementPosition, WithIndentLevel, With
|
||||||
use crate::expression::expr_string_literal::ExprStringLiteralKind;
|
use crate::expression::expr_string_literal::ExprStringLiteralKind;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::preview::{
|
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::statement::stmt_expr::FormatStmtExpr;
|
||||||
use crate::verbatim::{
|
use crate::verbatim::{
|
||||||
|
@ -261,12 +262,31 @@ impl FormatRule<Suite, PyFormatContext<'_>> for FormatSuite {
|
||||||
f,
|
f,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
match self.kind {
|
// Preserve empty lines after a stub implementation but don't insert a new one if there isn't any present in the source.
|
||||||
SuiteKind::TopLevel => {
|
// This is useful when having multiple function overloads that should be grouped to getter by omitting new lines between them.
|
||||||
write!(f, [empty_line(), empty_line()])?;
|
let is_preceding_stub_function_without_empty_line =
|
||||||
}
|
is_dummy_implementations_enabled(f.context())
|
||||||
SuiteKind::Function | SuiteKind::Class | SuiteKind::Other => {
|
&& following.is_function_def_stmt()
|
||||||
empty_line().fmt(f)?;
|
&& 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)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
---
|
|
||||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
|
||||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py
|
|
||||||
---
|
|
||||||
## Input
|
|
||||||
|
|
||||||
```python
|
|
||||||
from typing import NoReturn, Protocol, Union, overload
|
|
||||||
|
|
||||||
class Empty:
|
|
||||||
...
|
|
||||||
|
|
||||||
def dummy(a): ...
|
|
||||||
async def other(b): ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def a(arg: int) -> int: ...
|
|
||||||
@overload
|
|
||||||
def a(arg: str) -> str: ...
|
|
||||||
@overload
|
|
||||||
def a(arg: object) -> NoReturn: ...
|
|
||||||
def a(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
return arg
|
|
||||||
|
|
||||||
class Proto(Protocol):
|
|
||||||
def foo(self, a: int) -> int:
|
|
||||||
...
|
|
||||||
|
|
||||||
def bar(self, b: str) -> str: ...
|
|
||||||
def baz(self, c: bytes) -> str:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_two():
|
|
||||||
...
|
|
||||||
@dummy
|
|
||||||
def dummy_three():
|
|
||||||
...
|
|
||||||
|
|
||||||
def dummy_four():
|
|
||||||
...
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: int) -> int: ...
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: str) -> str: ...
|
|
||||||
@overload
|
|
||||||
def b(arg: object) -> NoReturn: ...
|
|
||||||
|
|
||||||
def b(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
return arg
|
|
||||||
|
|
||||||
def has_comment():
|
|
||||||
... # still a dummy
|
|
||||||
|
|
||||||
if some_condition:
|
|
||||||
...
|
|
||||||
|
|
||||||
if already_dummy: ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Black Differences
|
|
||||||
|
|
||||||
```diff
|
|
||||||
--- Black
|
|
||||||
+++ Ruff
|
|
||||||
@@ -5,15 +5,23 @@
|
|
||||||
|
|
||||||
|
|
||||||
def dummy(a): ...
|
|
||||||
+
|
|
||||||
+
|
|
||||||
async def other(b): ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def a(arg: int) -> int: ...
|
|
||||||
+
|
|
||||||
+
|
|
||||||
@overload
|
|
||||||
def a(arg: str) -> str: ...
|
|
||||||
+
|
|
||||||
+
|
|
||||||
@overload
|
|
||||||
def a(arg: object) -> NoReturn: ...
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def a(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
@@ -24,10 +32,13 @@
|
|
||||||
def foo(self, a: int) -> int: ...
|
|
||||||
|
|
||||||
def bar(self, b: str) -> str: ...
|
|
||||||
+
|
|
||||||
def baz(self, c: bytes) -> str: ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_two(): ...
|
|
||||||
+
|
|
||||||
+
|
|
||||||
@dummy
|
|
||||||
def dummy_three(): ...
|
|
||||||
|
|
||||||
@@ -41,6 +52,8 @@
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: str) -> str: ...
|
|
||||||
+
|
|
||||||
+
|
|
||||||
@overload
|
|
||||||
def b(arg: object) -> NoReturn: ...
|
|
||||||
|
|
||||||
@@ -54,8 +67,6 @@
|
|
||||||
def has_comment(): ... # still a dummy
|
|
||||||
|
|
||||||
|
|
||||||
-if some_condition:
|
|
||||||
- ...
|
|
||||||
+if some_condition: ...
|
|
||||||
|
|
||||||
-if already_dummy:
|
|
||||||
- ...
|
|
||||||
+if already_dummy: ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ruff Output
|
|
||||||
|
|
||||||
```python
|
|
||||||
from typing import NoReturn, Protocol, Union, overload
|
|
||||||
|
|
||||||
|
|
||||||
class Empty: ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy(a): ...
|
|
||||||
|
|
||||||
|
|
||||||
async def other(b): ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def a(arg: int) -> int: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def a(arg: str) -> str: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def a(arg: object) -> NoReturn: ...
|
|
||||||
|
|
||||||
|
|
||||||
def a(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
return arg
|
|
||||||
|
|
||||||
|
|
||||||
class Proto(Protocol):
|
|
||||||
def foo(self, a: int) -> int: ...
|
|
||||||
|
|
||||||
def bar(self, b: str) -> str: ...
|
|
||||||
|
|
||||||
def baz(self, c: bytes) -> str: ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_two(): ...
|
|
||||||
|
|
||||||
|
|
||||||
@dummy
|
|
||||||
def dummy_three(): ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_four(): ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: int) -> int: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: str) -> str: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: object) -> NoReturn: ...
|
|
||||||
|
|
||||||
|
|
||||||
def b(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
return arg
|
|
||||||
|
|
||||||
|
|
||||||
def has_comment(): ... # still a dummy
|
|
||||||
|
|
||||||
|
|
||||||
if some_condition: ...
|
|
||||||
|
|
||||||
if already_dummy: ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Black Output
|
|
||||||
|
|
||||||
```python
|
|
||||||
from typing import NoReturn, Protocol, Union, overload
|
|
||||||
|
|
||||||
|
|
||||||
class Empty: ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy(a): ...
|
|
||||||
async def other(b): ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def a(arg: int) -> int: ...
|
|
||||||
@overload
|
|
||||||
def a(arg: str) -> str: ...
|
|
||||||
@overload
|
|
||||||
def a(arg: object) -> NoReturn: ...
|
|
||||||
def a(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
return arg
|
|
||||||
|
|
||||||
|
|
||||||
class Proto(Protocol):
|
|
||||||
def foo(self, a: int) -> int: ...
|
|
||||||
|
|
||||||
def bar(self, b: str) -> str: ...
|
|
||||||
def baz(self, c: bytes) -> str: ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_two(): ...
|
|
||||||
@dummy
|
|
||||||
def dummy_three(): ...
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_four(): ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: int) -> int: ...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def b(arg: str) -> str: ...
|
|
||||||
@overload
|
|
||||||
def b(arg: object) -> NoReturn: ...
|
|
||||||
|
|
||||||
|
|
||||||
def b(arg: Union[int, str, object]) -> Union[int, str]:
|
|
||||||
if not isinstance(arg, (int, str)):
|
|
||||||
raise TypeError
|
|
||||||
return arg
|
|
||||||
|
|
||||||
|
|
||||||
def has_comment(): ... # still a dummy
|
|
||||||
|
|
||||||
|
|
||||||
if some_condition:
|
|
||||||
...
|
|
||||||
|
|
||||||
if already_dummy:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,27 @@ if True:
|
||||||
# empty line(s) at the end of the file due to nested function
|
# empty line(s) at the end of the file due to nested function
|
||||||
if True:
|
if True:
|
||||||
def nested_trailing_function():
|
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): ...
|
||||||
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
```python
|
```python
|
||||||
|
@ -546,6 +566,40 @@ if True:
|
||||||
|
|
||||||
def nested_trailing_function():
|
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):
|
||||||
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -569,6 +623,48 @@ if True:
|
||||||
|
|
||||||
|
|
||||||
def fakehttp():
|
def fakehttp():
|
||||||
|
@@ -283,20 +281,14 @@
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
-def overload1():
|
||||||
|
- ... # trailing comment
|
||||||
|
+def overload1(): ... # trailing comment
|
||||||
|
+def overload1(a: int): ...
|
||||||
|
|
||||||
|
|
||||||
|
-def overload1(a: int):
|
||||||
|
- ...
|
||||||
|
+def overload2(): ... # trailing comment
|
||||||
|
|
||||||
|
|
||||||
|
-def overload2():
|
||||||
|
- ... # trailing comment
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-def overload2(a: int):
|
||||||
|
- ...
|
||||||
|
+def overload2(a: int): ...
|
||||||
|
|
||||||
|
|
||||||
|
def overload3():
|
||||||
|
@@ -304,8 +296,7 @@
|
||||||
|
# trailing comment
|
||||||
|
|
||||||
|
|
||||||
|
-def overload3(a: int):
|
||||||
|
- ...
|
||||||
|
+def overload3(a: int): ...
|
||||||
|
|
||||||
|
|
||||||
|
def overload4():
|
||||||
|
@@ -313,5 +304,4 @@
|
||||||
|
# trailing comment
|
||||||
|
|
||||||
|
|
||||||
|
-def overload4(a: int):
|
||||||
|
- ...
|
||||||
|
+def overload4(a: int): ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -150,21 +150,23 @@ def quuz():
|
||||||
|
|
||||||
|
|
||||||
class Baz(Qux):
|
class Baz(Qux):
|
||||||
@@ -49,12 +44,10 @@
|
@@ -49,14 +44,8 @@
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
-def bar():
|
-def bar():
|
||||||
- ...
|
- ...
|
||||||
+def bar(): ...
|
-
|
||||||
|
-
|
||||||
|
|
||||||
-def baz():
|
-def baz():
|
||||||
- ...
|
- ...
|
||||||
|
-
|
||||||
|
-
|
||||||
|
+def bar(): ...
|
||||||
+def baz(): ...
|
+def baz(): ...
|
||||||
|
|
||||||
|
|
||||||
def quux():
|
def quux():
|
||||||
|
"""Some docstring."""
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue