Skip to content

Commit 83b1c48

Browse files
authored
Make setting and retrieving pydocstyle settings less tedious (#12582)
1 parent 138e70b commit 83b1c48

File tree

14 files changed

+146
-134
lines changed

14 files changed

+146
-134
lines changed

crates/ruff_linter/src/checkers/ast/analyze/definitions.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
174174
if enforce_docstrings || enforce_pydoclint {
175175
if pydocstyle::helpers::should_ignore_definition(
176176
definition,
177-
&checker.settings.pydocstyle.ignore_decorators,
177+
&checker.settings.pydocstyle,
178178
&checker.semantic,
179179
) {
180180
continue;
@@ -271,7 +271,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
271271
pydocstyle::rules::non_imperative_mood(
272272
checker,
273273
&docstring,
274-
&checker.settings.pydocstyle.property_decorators,
274+
&checker.settings.pydocstyle,
275275
);
276276
}
277277
if checker.enabled(Rule::NoSignature) {
@@ -310,15 +310,15 @@ pub(crate) fn definitions(checker: &mut Checker) {
310310
if enforce_sections || enforce_pydoclint {
311311
let section_contexts = pydocstyle::helpers::get_section_contexts(
312312
&docstring,
313-
checker.settings.pydocstyle.convention.as_ref(),
313+
checker.settings.pydocstyle.convention(),
314314
);
315315

316316
if enforce_sections {
317317
pydocstyle::rules::sections(
318318
checker,
319319
&docstring,
320320
&section_contexts,
321-
checker.settings.pydocstyle.convention.as_ref(),
321+
checker.settings.pydocstyle.convention(),
322322
);
323323
}
324324

@@ -327,7 +327,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
327327
checker,
328328
definition,
329329
&section_contexts,
330-
checker.settings.pydocstyle.convention.as_ref(),
330+
checker.settings.pydocstyle.convention(),
331331
);
332332
}
333333
}

crates/ruff_linter/src/rules/flake8_return/rules/function.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use ruff_diagnostics::{AlwaysFixableViolation, FixAvailability, Violation};
66
use ruff_diagnostics::{Diagnostic, Edit, Fix};
77
use ruff_macros::{derive_message_formats, violation};
88
use ruff_python_ast::helpers::{is_const_false, is_const_true};
9-
use ruff_python_ast::name::QualifiedName;
109
use ruff_python_ast::stmt_if::elif_else_range;
1110
use ruff_python_ast::visitor::Visitor;
1211
use ruff_python_ast::whitespace::indentation;
@@ -375,18 +374,10 @@ fn unnecessary_return_none(checker: &mut Checker, decorator_list: &[Decorator],
375374
continue;
376375
}
377376

378-
let extra_property_decorators = checker
379-
.settings
380-
.pydocstyle
381-
.property_decorators
382-
.iter()
383-
.map(|decorator| QualifiedName::from_dotted_name(decorator))
384-
.collect::<Vec<QualifiedName>>();
385-
386377
// Skip property functions
387378
if is_property(
388379
decorator_list,
389-
&extra_property_decorators,
380+
checker.settings.pydocstyle.property_decorators(),
390381
checker.semantic(),
391382
) {
392383
return;

crates/ruff_linter/src/rules/pydoclint/mod.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ pub(crate) mod rules;
33

44
#[cfg(test)]
55
mod tests {
6-
use std::collections::BTreeSet;
76
use std::convert::AsRef;
87
use std::path::Path;
98

109
use anyhow::Result;
1110
use test_case::test_case;
1211

1312
use crate::registry::Rule;
14-
use crate::rules::pydocstyle::settings::{Convention, Settings};
13+
use crate::rules::pydocstyle;
14+
use crate::rules::pydocstyle::settings::Convention;
1515
use crate::test::test_path;
1616
use crate::{assert_messages, settings};
1717

@@ -35,11 +35,7 @@ mod tests {
3535
let diagnostics = test_path(
3636
Path::new("pydoclint").join(path).as_path(),
3737
&settings::LinterSettings {
38-
pydocstyle: Settings {
39-
convention: Some(Convention::Google),
40-
ignore_decorators: BTreeSet::new(),
41-
property_decorators: BTreeSet::new(),
42-
},
38+
pydocstyle: pydocstyle::settings::Settings::new(Some(Convention::Google), [], []),
4339
..settings::LinterSettings::for_rule(rule_code)
4440
},
4541
)?;
@@ -56,11 +52,7 @@ mod tests {
5652
let diagnostics = test_path(
5753
Path::new("pydoclint").join(path).as_path(),
5854
&settings::LinterSettings {
59-
pydocstyle: Settings {
60-
convention: Some(Convention::Numpy),
61-
ignore_decorators: BTreeSet::new(),
62-
property_decorators: BTreeSet::new(),
63-
},
55+
pydocstyle: pydocstyle::settings::Settings::new(Some(Convention::Numpy), [], []),
6456
..settings::LinterSettings::for_rule(rule_code)
6557
},
6658
)?;

crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ pub(crate) fn check_docstring(
444444
checker: &mut Checker,
445445
definition: &Definition,
446446
section_contexts: &SectionContexts,
447-
convention: Option<&Convention>,
447+
convention: Option<Convention>,
448448
) {
449449
let mut diagnostics = Vec::new();
450450
let Definition::Member(member) = definition else {
@@ -478,14 +478,8 @@ pub(crate) fn check_docstring(
478478

479479
// DOC201
480480
if checker.enabled(Rule::DocstringMissingReturns) && docstring_sections.returns.is_none() {
481-
let extra_property_decorators = checker
482-
.settings
483-
.pydocstyle
484-
.property_decorators
485-
.iter()
486-
.map(|decorator| QualifiedName::from_dotted_name(decorator))
487-
.collect::<Vec<QualifiedName>>();
488-
if !definition.is_property(&extra_property_decorators, checker.semantic()) {
481+
let extra_property_decorators = checker.settings.pydocstyle.property_decorators();
482+
if !definition.is_property(extra_property_decorators, checker.semantic()) {
489483
if let Some(body_return) = body_entries.returns.first() {
490484
let diagnostic = Diagnostic::new(DocstringMissingReturns, body_return.range());
491485
diagnostics.push(diagnostic);

crates/ruff_linter/src/rules/pydocstyle/helpers.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
use std::collections::BTreeSet;
2-
31
use ruff_python_ast::helpers::map_callable;
4-
use ruff_python_ast::name::QualifiedName;
52
use ruff_python_semantic::{Definition, SemanticModel};
63
use ruff_source_file::UniversalNewlines;
74

85
use crate::docstrings::sections::{SectionContexts, SectionKind};
96
use crate::docstrings::styles::SectionStyle;
107
use crate::docstrings::Docstring;
11-
use crate::rules::pydocstyle::settings::Convention;
8+
use crate::rules::pydocstyle::settings::{Convention, Settings};
129

1310
/// Return the index of the first logical line in a string.
1411
pub(super) fn logical_line(content: &str) -> Option<usize> {
@@ -45,10 +42,12 @@ pub(super) fn ends_with_backslash(line: &str) -> bool {
4542
/// Check decorator list to see if function should be ignored.
4643
pub(crate) fn should_ignore_definition(
4744
definition: &Definition,
48-
ignore_decorators: &BTreeSet<String>,
45+
settings: &Settings,
4946
semantic: &SemanticModel,
5047
) -> bool {
51-
if ignore_decorators.is_empty() {
48+
let ignore_decorators = settings.ignore_decorators();
49+
50+
if ignore_decorators.len() == 0 {
5251
return false;
5352
}
5453

@@ -61,15 +60,15 @@ pub(crate) fn should_ignore_definition(
6160
.resolve_qualified_name(map_callable(&decorator.expression))
6261
.is_some_and(|qualified_name| {
6362
ignore_decorators
64-
.iter()
65-
.any(|decorator| QualifiedName::from_dotted_name(decorator) == qualified_name)
63+
.clone()
64+
.any(|decorator| decorator == qualified_name)
6665
})
6766
})
6867
}
6968

7069
pub(crate) fn get_section_contexts<'a>(
7170
docstring: &'a Docstring<'a>,
72-
convention: Option<&'a Convention>,
71+
convention: Option<Convention>,
7372
) -> SectionContexts<'a> {
7473
match convention {
7574
Some(Convention::Google) => {

crates/ruff_linter/src/rules/pydocstyle/mod.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ pub mod settings;
55

66
#[cfg(test)]
77
mod tests {
8-
use std::collections::BTreeSet;
98
use std::path::Path;
109

1110
use anyhow::Result;
@@ -98,13 +97,11 @@ mod tests {
9897
let diagnostics = test_path(
9998
Path::new("pydocstyle").join(path).as_path(),
10099
&settings::LinterSettings {
101-
pydocstyle: Settings {
102-
convention: None,
103-
ignore_decorators: BTreeSet::from_iter(["functools.wraps".to_string()]),
104-
property_decorators: BTreeSet::from_iter([
105-
"gi.repository.GObject.Property".to_string()
106-
]),
107-
},
100+
pydocstyle: Settings::new(
101+
None,
102+
["functools.wraps".to_string()],
103+
["gi.repository.GObject.Property".to_string()],
104+
),
108105
..settings::LinterSettings::for_rule(rule_code)
109106
},
110107
)?;
@@ -129,11 +126,7 @@ mod tests {
129126
&settings::LinterSettings {
130127
// When inferring the convention, we'll see a few false negatives.
131128
// See: https://github.com/PyCQA/pydocstyle/issues/459.
132-
pydocstyle: Settings {
133-
convention: None,
134-
ignore_decorators: BTreeSet::new(),
135-
property_decorators: BTreeSet::new(),
136-
},
129+
pydocstyle: Settings::default(),
137130
..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
138131
},
139132
)?;
@@ -147,11 +140,7 @@ mod tests {
147140
Path::new("pydocstyle/D417.py"),
148141
&settings::LinterSettings {
149142
// With explicit Google convention, we should flag every function.
150-
pydocstyle: Settings {
151-
convention: Some(Convention::Google),
152-
ignore_decorators: BTreeSet::new(),
153-
property_decorators: BTreeSet::new(),
154-
},
143+
pydocstyle: Settings::new(Some(Convention::Google), [], []),
155144
..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
156145
},
157146
)?;
@@ -164,12 +153,8 @@ mod tests {
164153
let diagnostics = test_path(
165154
Path::new("pydocstyle/D417.py"),
166155
&settings::LinterSettings {
167-
// With explicit Google convention, we shouldn't flag anything.
168-
pydocstyle: Settings {
169-
convention: Some(Convention::Numpy),
170-
ignore_decorators: BTreeSet::new(),
171-
property_decorators: BTreeSet::new(),
172-
},
156+
// With explicit numpy convention, we shouldn't flag anything.
157+
pydocstyle: Settings::new(Some(Convention::Numpy), [], []),
173158
..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
174159
},
175160
)?;

crates/ruff_linter/src/rules/pydocstyle/rules/non_imperative_mood.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
use std::collections::BTreeSet;
2-
31
use imperative::Mood;
42
use once_cell::sync::Lazy;
53

64
use ruff_diagnostics::{Diagnostic, Violation};
75
use ruff_macros::{derive_message_formats, violation};
8-
use ruff_python_ast::name::QualifiedName;
96
use ruff_python_semantic::analyze::visibility::{is_property, is_test};
107
use ruff_source_file::UniversalNewlines;
118
use ruff_text_size::Ranged;
129

1310
use crate::checkers::ast::Checker;
1411
use crate::docstrings::Docstring;
1512
use crate::rules::pydocstyle::helpers::normalize_word;
13+
use crate::rules::pydocstyle::settings::Settings;
1614

1715
static MOOD: Lazy<Mood> = Lazy::new(Mood::new);
1816

@@ -66,24 +64,21 @@ impl Violation for NonImperativeMood {
6664
pub(crate) fn non_imperative_mood(
6765
checker: &mut Checker,
6866
docstring: &Docstring,
69-
property_decorators: &BTreeSet<String>,
67+
settings: &Settings,
7068
) {
7169
let Some(function) = docstring.definition.as_function_def() else {
7270
return;
7371
};
7472

75-
let property_decorators = property_decorators
76-
.iter()
77-
.map(|decorator| QualifiedName::from_dotted_name(decorator))
78-
.collect::<Vec<QualifiedName>>();
73+
if is_test(&function.name) {
74+
return;
75+
}
7976

80-
if is_test(&function.name)
81-
|| is_property(
82-
&function.decorator_list,
83-
&property_decorators,
84-
checker.semantic(),
85-
)
86-
{
77+
if is_property(
78+
&function.decorator_list,
79+
settings.property_decorators(),
80+
checker.semantic(),
81+
) {
8782
return;
8883
}
8984

crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,7 @@ pub(crate) fn sections(
13251325
checker: &mut Checker,
13261326
docstring: &Docstring,
13271327
section_contexts: &SectionContexts,
1328-
convention: Option<&Convention>,
1328+
convention: Option<Convention>,
13291329
) {
13301330
match convention {
13311331
Some(Convention::Google) => parse_google_sections(checker, docstring, section_contexts),

0 commit comments

Comments
 (0)