mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:44:56 +00:00
[flake8-pyi
] Preserve inline comment in ellipsis removal (PYI013
) (#19399)
## Summary Fixes #19385. Based on [unnecessary-placeholder (PIE790)](https://docs.astral.sh/ruff/rules/unnecessary-placeholder/) behavior, [ellipsis-in-non-empty-class-body (PYI013)](https://docs.astral.sh/ruff/rules/ellipsis-in-non-empty-class-body/) now safely preserve inline comment on ellipsis removal. ## Test Plan A new test class was added: ```python class NonEmptyChildWithInlineComment: value: int ... # preserve me ``` with the following expected fix: ```python class NonEmptyChildWithInlineComment: value: int # preserve me ```
This commit is contained in:
parent
88a679945c
commit
ae26fa020c
5 changed files with 88 additions and 25 deletions
|
@ -39,6 +39,11 @@ class NonEmptyWithInit:
|
|||
pass
|
||||
|
||||
|
||||
class NonEmptyChildWithInlineComment:
|
||||
value: int
|
||||
... # preserve me
|
||||
|
||||
|
||||
class EmptyClass:
|
||||
...
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ class NonEmptyWithInit:
|
|||
def __init__():
|
||||
pass
|
||||
|
||||
class NonEmptyChildWithInlineComment:
|
||||
value: int
|
||||
... # preserve me
|
||||
|
||||
# Not violations
|
||||
|
||||
class EmptyClass: ...
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::whitespace::trailing_comment_start_offset;
|
||||
use ruff_python_ast::{Stmt, StmtExpr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix;
|
||||
use crate::{Fix, FixAvailability, Violation};
|
||||
use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
|
||||
/// ## What it does
|
||||
/// Removes ellipses (`...`) in otherwise non-empty class bodies.
|
||||
|
@ -50,15 +51,21 @@ pub(crate) fn ellipsis_in_non_empty_class_body(checker: &Checker, body: &[Stmt])
|
|||
}
|
||||
|
||||
for stmt in body {
|
||||
let Stmt::Expr(StmtExpr { value, .. }) = &stmt else {
|
||||
let Stmt::Expr(StmtExpr { value, .. }) = stmt else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if value.is_ellipsis_literal_expr() {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(EllipsisInNonEmptyClassBody, stmt.range());
|
||||
let edit =
|
||||
fix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer());
|
||||
|
||||
// Try to preserve trailing comment if it exists
|
||||
let edit = if let Some(index) = trailing_comment_start_offset(stmt, checker.source()) {
|
||||
Edit::range_deletion(stmt.range().add_end(index))
|
||||
} else {
|
||||
fix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer())
|
||||
};
|
||||
|
||||
diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation(
|
||||
checker.semantic().current_statement_id(),
|
||||
)));
|
||||
|
|
|
@ -145,3 +145,22 @@ PYI013.py:36:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
37 36 |
|
||||
38 37 | def __init__():
|
||||
39 38 | pass
|
||||
|
||||
PYI013.py:44:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
42 | class NonEmptyChildWithInlineComment:
|
||||
43 | value: int
|
||||
44 | ... # preserve me
|
||||
| ^^^ PYI013
|
||||
|
|
||||
= help: Remove unnecessary `...`
|
||||
|
||||
ℹ Safe fix
|
||||
41 41 |
|
||||
42 42 | class NonEmptyChildWithInlineComment:
|
||||
43 43 | value: int
|
||||
44 |- ... # preserve me
|
||||
44 |+ # preserve me
|
||||
45 45 |
|
||||
46 46 |
|
||||
47 47 | class EmptyClass:
|
||||
|
|
|
@ -17,9 +17,10 @@ PYI013.pyi:5:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
3 3 | class OneAttributeClass:
|
||||
4 4 | value: int
|
||||
5 |- ... # Error
|
||||
6 5 |
|
||||
7 6 | class OneAttributeClass2:
|
||||
8 7 | ... # Error
|
||||
5 |+ # Error
|
||||
6 6 |
|
||||
7 7 | class OneAttributeClass2:
|
||||
8 8 | ... # Error
|
||||
|
||||
PYI013.pyi:8:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
|
@ -35,9 +36,10 @@ PYI013.pyi:8:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
6 6 |
|
||||
7 7 | class OneAttributeClass2:
|
||||
8 |- ... # Error
|
||||
9 8 | value: int
|
||||
10 9 |
|
||||
11 10 | class MyClass:
|
||||
8 |+ # Error
|
||||
9 9 | value: int
|
||||
10 10 |
|
||||
11 11 | class MyClass:
|
||||
|
||||
PYI013.pyi:12:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
|
@ -91,9 +93,10 @@ PYI013.pyi:17:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
15 15 | class TwoEllipsesClass:
|
||||
16 16 | ...
|
||||
17 |- ... # Error
|
||||
18 17 |
|
||||
19 18 | class DocstringClass:
|
||||
20 19 | """
|
||||
17 |+ # Error
|
||||
18 18 |
|
||||
19 19 | class DocstringClass:
|
||||
20 20 | """
|
||||
|
||||
PYI013.pyi:24:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
|
@ -111,9 +114,10 @@ PYI013.pyi:24:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
22 22 | """
|
||||
23 23 |
|
||||
24 |- ... # Error
|
||||
25 24 |
|
||||
26 25 | class NonEmptyChild(Exception):
|
||||
27 26 | value: int
|
||||
24 |+ # Error
|
||||
25 25 |
|
||||
26 26 | class NonEmptyChild(Exception):
|
||||
27 27 | value: int
|
||||
|
||||
PYI013.pyi:28:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
|
@ -131,9 +135,10 @@ PYI013.pyi:28:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
26 26 | class NonEmptyChild(Exception):
|
||||
27 27 | value: int
|
||||
28 |- ... # Error
|
||||
29 28 |
|
||||
30 29 | class NonEmptyChild2(Exception):
|
||||
31 30 | ... # Error
|
||||
28 |+ # Error
|
||||
29 29 |
|
||||
30 30 | class NonEmptyChild2(Exception):
|
||||
31 31 | ... # Error
|
||||
|
||||
PYI013.pyi:31:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
|
@ -149,9 +154,10 @@ PYI013.pyi:31:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
29 29 |
|
||||
30 30 | class NonEmptyChild2(Exception):
|
||||
31 |- ... # Error
|
||||
32 31 | value: int
|
||||
33 32 |
|
||||
34 33 | class NonEmptyWithInit:
|
||||
31 |+ # Error
|
||||
32 32 | value: int
|
||||
33 33 |
|
||||
34 34 | class NonEmptyWithInit:
|
||||
|
||||
PYI013.pyi:36:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
|
@ -169,6 +175,28 @@ PYI013.pyi:36:5: PYI013 [*] Non-empty class body must not contain `...`
|
|||
34 34 | class NonEmptyWithInit:
|
||||
35 35 | value: int
|
||||
36 |- ... # Error
|
||||
37 36 |
|
||||
38 37 | def __init__():
|
||||
39 38 | pass
|
||||
36 |+ # Error
|
||||
37 37 |
|
||||
38 38 | def __init__():
|
||||
39 39 | pass
|
||||
|
||||
PYI013.pyi:43:5: PYI013 [*] Non-empty class body must not contain `...`
|
||||
|
|
||||
41 | class NonEmptyChildWithInlineComment:
|
||||
42 | value: int
|
||||
43 | ... # preserve me
|
||||
| ^^^ PYI013
|
||||
44 |
|
||||
45 | # Not violations
|
||||
|
|
||||
= help: Remove unnecessary `...`
|
||||
|
||||
ℹ Safe fix
|
||||
40 40 |
|
||||
41 41 | class NonEmptyChildWithInlineComment:
|
||||
42 42 | value: int
|
||||
43 |- ... # preserve me
|
||||
43 |+ # preserve me
|
||||
44 44 |
|
||||
45 45 | # Not violations
|
||||
46 46 |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue