mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:13:08 +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
|
@ -254,3 +254,22 @@ if True:
|
|||
if True:
|
||||
def nested_trailing_function():
|
||||
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<'_> {
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -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,6 +262,24 @@ impl FormatRule<Suite, PyFormatContext<'_>> for FormatSuite {
|
|||
f,
|
||||
)?;
|
||||
} else {
|
||||
// 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()])?;
|
||||
|
@ -270,6 +289,7 @@ impl FormatRule<Suite, PyFormatContext<'_>> for FormatSuite {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if is_import_definition(preceding)
|
||||
&& (!is_import_definition(following) || following_comments.has_leading())
|
||||
{
|
||||
|
|
|
@ -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
|
||||
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): ...
|
||||
```
|
||||
|
||||
## Output
|
||||
```python
|
||||
|
@ -546,6 +566,40 @@ if True:
|
|||
|
||||
def nested_trailing_function():
|
||||
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():
|
||||
@@ -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):
|
||||
@@ -49,12 +44,10 @@
|
||||
@@ -49,14 +44,8 @@
|
||||
pass
|
||||
|
||||
|
||||
-def bar():
|
||||
- ...
|
||||
+def bar(): ...
|
||||
|
||||
|
||||
-
|
||||
-
|
||||
-def baz():
|
||||
- ...
|
||||
-
|
||||
-
|
||||
+def bar(): ...
|
||||
+def baz(): ...
|
||||
|
||||
|
||||
def quux():
|
||||
"""Some docstring."""
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue