mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
Ignore same-line docstrings for lines-before and lines-after rules (#6344)
These rules assume that the docstring is on its own line. pydocstyle treats them inconsistently, so I'm just going to disable them in this case. Closes https://github.com/astral-sh/ruff/issues/6329.
This commit is contained in:
parent
08dd87e04d
commit
fa5c9cced9
5 changed files with 115 additions and 36 deletions
|
@ -634,3 +634,8 @@ def starts_with_this():
|
||||||
@expect('D404: First word of the docstring should not be "This"')
|
@expect('D404: First word of the docstring should not be "This"')
|
||||||
def starts_with_space_then_this():
|
def starts_with_space_then_this():
|
||||||
""" This is a docstring that starts with a space.""" # noqa: D210
|
""" This is a docstring that starts with a space.""" # noqa: D210
|
||||||
|
|
||||||
|
|
||||||
|
class SameLine: """This is a docstring on the same line"""
|
||||||
|
|
||||||
|
def same_line(): """This is a docstring on the same line"""
|
||||||
|
|
|
@ -43,9 +43,7 @@ use crate::registry::{AsRule, Rule};
|
||||||
///
|
///
|
||||||
/// [D211]: https://beta.ruff.rs/docs/rules/blank-line-before-class
|
/// [D211]: https://beta.ruff.rs/docs/rules/blank-line-before-class
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct OneBlankLineBeforeClass {
|
pub struct OneBlankLineBeforeClass;
|
||||||
lines: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for OneBlankLineBeforeClass {
|
impl AlwaysAutofixableViolation for OneBlankLineBeforeClass {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
|
@ -97,9 +95,7 @@ impl AlwaysAutofixableViolation for OneBlankLineBeforeClass {
|
||||||
///
|
///
|
||||||
/// [PEP 257]: https://peps.python.org/pep-0257/
|
/// [PEP 257]: https://peps.python.org/pep-0257/
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct OneBlankLineAfterClass {
|
pub struct OneBlankLineAfterClass;
|
||||||
lines: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for OneBlankLineAfterClass {
|
impl AlwaysAutofixableViolation for OneBlankLineAfterClass {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
|
@ -144,9 +140,7 @@ impl AlwaysAutofixableViolation for OneBlankLineAfterClass {
|
||||||
///
|
///
|
||||||
/// [D203]: https://beta.ruff.rs/docs/rules/one-blank-line-before-class
|
/// [D203]: https://beta.ruff.rs/docs/rules/one-blank-line-before-class
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BlankLineBeforeClass {
|
pub struct BlankLineBeforeClass;
|
||||||
lines: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for BlankLineBeforeClass {
|
impl AlwaysAutofixableViolation for BlankLineBeforeClass {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
|
@ -170,14 +164,24 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Special-case: the docstring is on the same line as the class. For example:
|
||||||
|
// ```python
|
||||||
|
// class PhotoMetadata: """Metadata about a photo."""
|
||||||
|
// ```
|
||||||
|
let between_range = TextRange::new(stmt.start(), docstring.start());
|
||||||
|
if !checker.locator().contains_line_break(between_range) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if checker.enabled(Rule::OneBlankLineBeforeClass) || checker.enabled(Rule::BlankLineBeforeClass)
|
if checker.enabled(Rule::OneBlankLineBeforeClass) || checker.enabled(Rule::BlankLineBeforeClass)
|
||||||
{
|
{
|
||||||
let before = checker
|
let mut lines = UniversalNewlineIterator::with_offset(
|
||||||
.locator()
|
checker.locator().slice(between_range),
|
||||||
.slice(TextRange::new(stmt.start(), docstring.start()));
|
between_range.start(),
|
||||||
|
)
|
||||||
|
.rev();
|
||||||
|
|
||||||
let mut blank_lines_before = 0usize;
|
let mut blank_lines_before = 0usize;
|
||||||
let mut lines = UniversalNewlineIterator::with_offset(before, stmt.start()).rev();
|
|
||||||
let mut blank_lines_start = lines.next().map(|line| line.start()).unwrap_or_default();
|
let mut blank_lines_start = lines.next().map(|line| line.start()).unwrap_or_default();
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
|
@ -191,12 +195,7 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr
|
||||||
|
|
||||||
if checker.enabled(Rule::BlankLineBeforeClass) {
|
if checker.enabled(Rule::BlankLineBeforeClass) {
|
||||||
if blank_lines_before != 0 {
|
if blank_lines_before != 0 {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(BlankLineBeforeClass, docstring.range());
|
||||||
BlankLineBeforeClass {
|
|
||||||
lines: blank_lines_before,
|
|
||||||
},
|
|
||||||
docstring.range(),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
// Delete the blank line before the class.
|
// Delete the blank line before the class.
|
||||||
diagnostic.set_fix(Fix::automatic(Edit::deletion(
|
diagnostic.set_fix(Fix::automatic(Edit::deletion(
|
||||||
|
@ -209,12 +208,7 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::OneBlankLineBeforeClass) {
|
if checker.enabled(Rule::OneBlankLineBeforeClass) {
|
||||||
if blank_lines_before != 1 {
|
if blank_lines_before != 1 {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(OneBlankLineBeforeClass, docstring.range());
|
||||||
OneBlankLineBeforeClass {
|
|
||||||
lines: blank_lines_before,
|
|
||||||
},
|
|
||||||
docstring.range(),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
// Insert one blank line before the class.
|
// Insert one blank line before the class.
|
||||||
diagnostic.set_fix(Fix::automatic(Edit::replacement(
|
diagnostic.set_fix(Fix::automatic(Edit::replacement(
|
||||||
|
@ -229,9 +223,9 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr
|
||||||
}
|
}
|
||||||
|
|
||||||
if checker.enabled(Rule::OneBlankLineAfterClass) {
|
if checker.enabled(Rule::OneBlankLineAfterClass) {
|
||||||
let after = checker
|
let after_range = TextRange::new(docstring.end(), stmt.end());
|
||||||
.locator()
|
|
||||||
.slice(TextRange::new(docstring.end(), stmt.end()));
|
let after = checker.locator().slice(after_range);
|
||||||
|
|
||||||
let all_blank_after = after.universal_newlines().skip(1).all(|line| {
|
let all_blank_after = after.universal_newlines().skip(1).all(|line| {
|
||||||
line.trim_whitespace().is_empty() || line.trim_whitespace_start().starts_with('#')
|
line.trim_whitespace().is_empty() || line.trim_whitespace_start().starts_with('#')
|
||||||
|
@ -240,9 +234,10 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut blank_lines_after = 0usize;
|
let mut lines = UniversalNewlineIterator::with_offset(after, after_range.start());
|
||||||
let mut lines = UniversalNewlineIterator::with_offset(after, docstring.end());
|
|
||||||
let first_line_start = lines.next().map(|l| l.start()).unwrap_or_default();
|
let first_line_start = lines.next().map(|l| l.start()).unwrap_or_default();
|
||||||
|
let mut blank_lines_after = 0usize;
|
||||||
let mut blank_lines_end = docstring.end();
|
let mut blank_lines_end = docstring.end();
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
|
@ -255,12 +250,7 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr
|
||||||
}
|
}
|
||||||
|
|
||||||
if blank_lines_after != 1 {
|
if blank_lines_after != 1 {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(OneBlankLineAfterClass, docstring.range());
|
||||||
OneBlankLineAfterClass {
|
|
||||||
lines: blank_lines_after,
|
|
||||||
},
|
|
||||||
docstring.range(),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
// Insert a blank line before the class (replacing any existing lines).
|
// Insert a blank line before the class (replacing any existing lines).
|
||||||
diagnostic.set_fix(Fix::automatic(Edit::replacement(
|
diagnostic.set_fix(Fix::automatic(Edit::replacement(
|
||||||
|
|
|
@ -272,4 +272,38 @@ D.py:615:5: D400 [*] First line should end with a period
|
||||||
617 617 | """
|
617 617 | """
|
||||||
618 618 |
|
618 618 |
|
||||||
|
|
||||||
|
D.py:639:17: D400 [*] First line should end with a period
|
||||||
|
|
|
||||||
|
639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D400
|
||||||
|
640 |
|
||||||
|
641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
|
|
||||||
|
= help: Add period
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
636 636 | """ This is a docstring that starts with a space.""" # noqa: D210
|
||||||
|
637 637 |
|
||||||
|
638 638 |
|
||||||
|
639 |-class SameLine: """This is a docstring on the same line"""
|
||||||
|
639 |+class SameLine: """This is a docstring on the same line."""
|
||||||
|
640 640 |
|
||||||
|
641 641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
|
||||||
|
D.py:641:18: D400 [*] First line should end with a period
|
||||||
|
|
|
||||||
|
639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
640 |
|
||||||
|
641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D400
|
||||||
|
|
|
||||||
|
= help: Add period
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
638 638 |
|
||||||
|
639 639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
640 640 |
|
||||||
|
641 |-def same_line(): """This is a docstring on the same line"""
|
||||||
|
641 |+def same_line(): """This is a docstring on the same line."""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,20 @@ D.py:636:5: D404 First word of the docstring should not be "This"
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D404
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D404
|
||||||
|
|
|
|
||||||
|
|
||||||
|
D.py:639:17: D404 First word of the docstring should not be "This"
|
||||||
|
|
|
||||||
|
639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D404
|
||||||
|
640 |
|
||||||
|
641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
|
|
||||||
|
|
||||||
|
D.py:641:18: D404 First word of the docstring should not be "This"
|
||||||
|
|
|
||||||
|
639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
640 |
|
||||||
|
641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D404
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -254,4 +254,38 @@ D.py:615:5: D415 [*] First line should end with a period, question mark, or excl
|
||||||
617 617 | """
|
617 617 | """
|
||||||
618 618 |
|
618 618 |
|
||||||
|
|
||||||
|
D.py:639:17: D415 [*] First line should end with a period, question mark, or exclamation point
|
||||||
|
|
|
||||||
|
639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D415
|
||||||
|
640 |
|
||||||
|
641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
|
|
||||||
|
= help: Add closing punctuation
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
636 636 | """ This is a docstring that starts with a space.""" # noqa: D210
|
||||||
|
637 637 |
|
||||||
|
638 638 |
|
||||||
|
639 |-class SameLine: """This is a docstring on the same line"""
|
||||||
|
639 |+class SameLine: """This is a docstring on the same line."""
|
||||||
|
640 640 |
|
||||||
|
641 641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
|
||||||
|
D.py:641:18: D415 [*] First line should end with a period, question mark, or exclamation point
|
||||||
|
|
|
||||||
|
639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
640 |
|
||||||
|
641 | def same_line(): """This is a docstring on the same line"""
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D415
|
||||||
|
|
|
||||||
|
= help: Add closing punctuation
|
||||||
|
|
||||||
|
ℹ Suggested fix
|
||||||
|
638 638 |
|
||||||
|
639 639 | class SameLine: """This is a docstring on the same line"""
|
||||||
|
640 640 |
|
||||||
|
641 |-def same_line(): """This is a docstring on the same line"""
|
||||||
|
641 |+def same_line(): """This is a docstring on the same line."""
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue