Enforce max-doc-length for multi-line docstrings (#4347)

This commit is contained in:
Charlie Marsh 2023-05-10 11:06:07 -04:00 committed by GitHub
parent ddbe5a1243
commit 5f64d2346f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 12 deletions

View file

@ -2,7 +2,7 @@
"""Here's a top-level docstring that's over the limit."""
def f():
def f1():
"""Here's a docstring that's also over the limit."""
x = 1 # Here's a comment that's over the limit, but it's not standalone.
@ -16,3 +16,16 @@ def f():
"This is also considered a docstring, and is over the limit."
def f2():
"""Here's a multi-line docstring.
It's over the limit on this line, which isn't the first line in the docstring.
"""
def f3():
"""Here's a multi-line docstring.
It's over the limit on this line, which isn't the first line in the docstring."""

View file

@ -118,7 +118,7 @@ pub fn check_physical_lines(
}
while doc_lines_iter
.next_if(|doc_line_start| line.range().contains(**doc_line_start))
.next_if(|doc_line_start| line.range().contains_inclusive(**doc_line_start))
.is_some()
{
if enforce_doc_line_too_long {

View file

@ -1,14 +1,15 @@
//! Doc line extraction. In this context, a doc line is a line consisting of a
//! standalone comment or a constant string statement.
use ruff_text_size::{TextRange, TextSize};
use std::iter::FusedIterator;
use ruff_python_ast::source_code::Locator;
use ruff_text_size::{TextRange, TextSize};
use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind, Suite};
use rustpython_parser::lexer::LexResult;
use rustpython_parser::Tok;
use ruff_python_ast::newlines::UniversalNewlineIterator;
use ruff_python_ast::source_code::Locator;
use ruff_python_ast::visitor;
use ruff_python_ast::visitor::Visitor;
@ -69,12 +70,12 @@ impl Iterator for DocLines<'_> {
impl FusedIterator for DocLines<'_> {}
#[derive(Default)]
struct StringLinesVisitor {
struct StringLinesVisitor<'a> {
string_lines: Vec<TextSize>,
locator: &'a Locator<'a>,
}
impl Visitor<'_> for StringLinesVisitor {
impl Visitor<'_> for StringLinesVisitor<'_> {
fn visit_stmt(&mut self, stmt: &Stmt) {
if let StmtKind::Expr { value } = &stmt.node {
if let ExprKind::Constant {
@ -82,16 +83,30 @@ impl Visitor<'_> for StringLinesVisitor {
..
} = &value.node
{
self.string_lines.push(value.start());
for line in UniversalNewlineIterator::with_offset(
self.locator.slice(value.range()),
value.start(),
) {
self.string_lines.push(line.start());
}
}
}
visitor::walk_stmt(self, stmt);
}
}
impl<'a> StringLinesVisitor<'a> {
fn new(locator: &'a Locator<'a>) -> Self {
Self {
string_lines: Vec::new(),
locator,
}
}
}
/// Extract doc lines (standalone strings) start positions from an AST.
pub fn doc_lines_from_ast(python_ast: &Suite) -> Vec<TextSize> {
let mut visitor = StringLinesVisitor::default();
pub fn doc_lines_from_ast(python_ast: &Suite, locator: &Locator) -> Vec<TextSize> {
let mut visitor = StringLinesVisitor::new(locator);
visitor.visit_body(python_ast);
visitor.string_lines
}

View file

@ -163,7 +163,7 @@ pub fn check_path(
diagnostics.extend(import_diagnostics);
}
if use_doc_lines {
doc_lines.extend(doc_lines_from_ast(&python_ast));
doc_lines.extend(doc_lines_from_ast(&python_ast, locator));
}
}
Err(parse_error) => {

View file

@ -10,7 +10,7 @@ W505.py:2:51: W505 Doc line too long (57 > 50 characters)
W505.py:6:51: W505 Doc line too long (56 > 50 characters)
|
6 | def f():
6 | def f1():
7 | """Here's a docstring that's also over the limit."""
| ^^^^^^ W505
8 |
@ -42,4 +42,21 @@ W505.py:18:51: W505 Doc line too long (61 > 50 characters)
| ^^^^^^^^^^^ W505
|
W505.py:24:51: W505 Doc line too long (82 > 50 characters)
|
24 | """Here's a multi-line docstring.
25 |
26 | It's over the limit on this line, which isn't the first line in the docstring.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ W505
27 | """
|
W505.py:31:51: W505 Doc line too long (85 > 50 characters)
|
31 | """Here's a multi-line docstring.
32 |
33 | It's over the limit on this line, which isn't the first line in the docstring."""
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ W505
|