Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D403: Require capitalizing single word sentence #10776

Merged
merged 2 commits into from Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pydocstyle/D403.py
Expand Up @@ -25,3 +25,9 @@ def non_ascii():

def all_caps():
"""th•s is not capitalized."""

def single_word():
"""singleword."""

def single_word_no_dot():
"""singleword"""
30 changes: 20 additions & 10 deletions crates/ruff_linter/src/rules/pydocstyle/rules/capitalized.rs
Expand Up @@ -59,26 +59,36 @@ pub(crate) fn capitalized(checker: &mut Checker, docstring: &Docstring) {
}

let body = docstring.body();
let Some(first_word) = body.split(' ').next() else {
return;
};

// Like pydocstyle, we only support ASCII for now.
for char in first_word.chars() {
if !char.is_ascii_alphabetic() && char != '\'' {
return;
}
}
let first_word = body.split_once(' ').map_or_else(
|| {
// If the docstring is a single word, trim the punctuation marks because
// it makes the ASCII test below fail.
body.trim_end_matches(['.', '!', '?'])
},
|(first_word, _)| first_word,
);

let mut first_word_chars = first_word.chars();
let Some(first_char) = first_word_chars.next() else {
return;
};

if !first_char.is_ascii() {
return;
}

let uppercase_first_char = first_char.to_ascii_uppercase();
if first_char == uppercase_first_char {
return;
}

// Like pydocstyle, we only support ASCII for now.
for char in first_word.chars().skip(1) {
if !char.is_ascii_alphabetic() && char != '\'' {
return;
}
}

Comment on lines +85 to +91
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this down to avoid checking all characters of the first word if the character is uppercase anyway.

let capitalized_word = uppercase_first_char.to_string() + first_word_chars.as_str();

let mut diagnostic = Diagnostic::new(
Expand Down
Expand Up @@ -19,4 +19,37 @@ D403.py:2:5: D403 [*] First word of the first line should be capitalized: `this`
4 4 | def good_function():
5 5 | """This docstring is capitalized."""

D403.py:30:5: D403 [*] First word of the first line should be capitalized: `singleword` -> `Singleword`
|
29 | def single_word():
30 | """singleword."""
| ^^^^^^^^^^^^^^^^^ D403
31 |
32 | def single_word_no_dot():
|
= help: Capitalize `singleword` to `Singleword`

ℹ Safe fix
27 27 | """th•s is not capitalized."""
28 28 |
29 29 | def single_word():
30 |- """singleword."""
30 |+ """Singleword."""
31 31 |
32 32 | def single_word_no_dot():
33 33 | """singleword"""

D403.py:33:5: D403 [*] First word of the first line should be capitalized: `singleword` -> `Singleword`
|
32 | def single_word_no_dot():
33 | """singleword"""
| ^^^^^^^^^^^^^^^^ D403
|
= help: Capitalize `singleword` to `Singleword`

ℹ Safe fix
30 30 | """singleword."""
31 31 |
32 32 | def single_word_no_dot():
33 |- """singleword"""
33 |+ """Singleword"""