Skip to content

Commit

Permalink
Make setting and retrieving pydocstyle settings less tedious (#12582)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood authored Jul 31, 2024
1 parent 138e70b commit 83b1c48
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 134 deletions.
10 changes: 5 additions & 5 deletions crates/ruff_linter/src/checkers/ast/analyze/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
if enforce_docstrings || enforce_pydoclint {
if pydocstyle::helpers::should_ignore_definition(
definition,
&checker.settings.pydocstyle.ignore_decorators,
&checker.settings.pydocstyle,
&checker.semantic,
) {
continue;
Expand Down Expand Up @@ -271,7 +271,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
pydocstyle::rules::non_imperative_mood(
checker,
&docstring,
&checker.settings.pydocstyle.property_decorators,
&checker.settings.pydocstyle,
);
}
if checker.enabled(Rule::NoSignature) {
Expand Down Expand Up @@ -310,15 +310,15 @@ pub(crate) fn definitions(checker: &mut Checker) {
if enforce_sections || enforce_pydoclint {
let section_contexts = pydocstyle::helpers::get_section_contexts(
&docstring,
checker.settings.pydocstyle.convention.as_ref(),
checker.settings.pydocstyle.convention(),
);

if enforce_sections {
pydocstyle::rules::sections(
checker,
&docstring,
&section_contexts,
checker.settings.pydocstyle.convention.as_ref(),
checker.settings.pydocstyle.convention(),
);
}

Expand All @@ -327,7 +327,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
checker,
definition,
&section_contexts,
checker.settings.pydocstyle.convention.as_ref(),
checker.settings.pydocstyle.convention(),
);
}
}
Expand Down
11 changes: 1 addition & 10 deletions crates/ruff_linter/src/rules/flake8_return/rules/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use ruff_diagnostics::{AlwaysFixableViolation, FixAvailability, Violation};
use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::{is_const_false, is_const_true};
use ruff_python_ast::name::QualifiedName;
use ruff_python_ast::stmt_if::elif_else_range;
use ruff_python_ast::visitor::Visitor;
use ruff_python_ast::whitespace::indentation;
Expand Down Expand Up @@ -375,18 +374,10 @@ fn unnecessary_return_none(checker: &mut Checker, decorator_list: &[Decorator],
continue;
}

let extra_property_decorators = checker
.settings
.pydocstyle
.property_decorators
.iter()
.map(|decorator| QualifiedName::from_dotted_name(decorator))
.collect::<Vec<QualifiedName>>();

// Skip property functions
if is_property(
decorator_list,
&extra_property_decorators,
checker.settings.pydocstyle.property_decorators(),
checker.semantic(),
) {
return;
Expand Down
16 changes: 4 additions & 12 deletions crates/ruff_linter/src/rules/pydoclint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ pub(crate) mod rules;

#[cfg(test)]
mod tests {
use std::collections::BTreeSet;
use std::convert::AsRef;
use std::path::Path;

use anyhow::Result;
use test_case::test_case;

use crate::registry::Rule;
use crate::rules::pydocstyle::settings::{Convention, Settings};
use crate::rules::pydocstyle;
use crate::rules::pydocstyle::settings::Convention;
use crate::test::test_path;
use crate::{assert_messages, settings};

Expand All @@ -35,11 +35,7 @@ mod tests {
let diagnostics = test_path(
Path::new("pydoclint").join(path).as_path(),
&settings::LinterSettings {
pydocstyle: Settings {
convention: Some(Convention::Google),
ignore_decorators: BTreeSet::new(),
property_decorators: BTreeSet::new(),
},
pydocstyle: pydocstyle::settings::Settings::new(Some(Convention::Google), [], []),
..settings::LinterSettings::for_rule(rule_code)
},
)?;
Expand All @@ -56,11 +52,7 @@ mod tests {
let diagnostics = test_path(
Path::new("pydoclint").join(path).as_path(),
&settings::LinterSettings {
pydocstyle: Settings {
convention: Some(Convention::Numpy),
ignore_decorators: BTreeSet::new(),
property_decorators: BTreeSet::new(),
},
pydocstyle: pydocstyle::settings::Settings::new(Some(Convention::Numpy), [], []),
..settings::LinterSettings::for_rule(rule_code)
},
)?;
Expand Down
12 changes: 3 additions & 9 deletions crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ pub(crate) fn check_docstring(
checker: &mut Checker,
definition: &Definition,
section_contexts: &SectionContexts,
convention: Option<&Convention>,
convention: Option<Convention>,
) {
let mut diagnostics = Vec::new();
let Definition::Member(member) = definition else {
Expand Down Expand Up @@ -478,14 +478,8 @@ pub(crate) fn check_docstring(

// DOC201
if checker.enabled(Rule::DocstringMissingReturns) && docstring_sections.returns.is_none() {
let extra_property_decorators = checker
.settings
.pydocstyle
.property_decorators
.iter()
.map(|decorator| QualifiedName::from_dotted_name(decorator))
.collect::<Vec<QualifiedName>>();
if !definition.is_property(&extra_property_decorators, checker.semantic()) {
let extra_property_decorators = checker.settings.pydocstyle.property_decorators();
if !definition.is_property(extra_property_decorators, checker.semantic()) {
if let Some(body_return) = body_entries.returns.first() {
let diagnostic = Diagnostic::new(DocstringMissingReturns, body_return.range());
diagnostics.push(diagnostic);
Expand Down
17 changes: 8 additions & 9 deletions crates/ruff_linter/src/rules/pydocstyle/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use std::collections::BTreeSet;

use ruff_python_ast::helpers::map_callable;
use ruff_python_ast::name::QualifiedName;
use ruff_python_semantic::{Definition, SemanticModel};
use ruff_source_file::UniversalNewlines;

use crate::docstrings::sections::{SectionContexts, SectionKind};
use crate::docstrings::styles::SectionStyle;
use crate::docstrings::Docstring;
use crate::rules::pydocstyle::settings::Convention;
use crate::rules::pydocstyle::settings::{Convention, Settings};

/// Return the index of the first logical line in a string.
pub(super) fn logical_line(content: &str) -> Option<usize> {
Expand Down Expand Up @@ -45,10 +42,12 @@ pub(super) fn ends_with_backslash(line: &str) -> bool {
/// Check decorator list to see if function should be ignored.
pub(crate) fn should_ignore_definition(
definition: &Definition,
ignore_decorators: &BTreeSet<String>,
settings: &Settings,
semantic: &SemanticModel,
) -> bool {
if ignore_decorators.is_empty() {
let ignore_decorators = settings.ignore_decorators();

if ignore_decorators.len() == 0 {
return false;
}

Expand All @@ -61,15 +60,15 @@ pub(crate) fn should_ignore_definition(
.resolve_qualified_name(map_callable(&decorator.expression))
.is_some_and(|qualified_name| {
ignore_decorators
.iter()
.any(|decorator| QualifiedName::from_dotted_name(decorator) == qualified_name)
.clone()
.any(|decorator| decorator == qualified_name)
})
})
}

pub(crate) fn get_section_contexts<'a>(
docstring: &'a Docstring<'a>,
convention: Option<&'a Convention>,
convention: Option<Convention>,
) -> SectionContexts<'a> {
match convention {
Some(Convention::Google) => {
Expand Down
33 changes: 9 additions & 24 deletions crates/ruff_linter/src/rules/pydocstyle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ pub mod settings;

#[cfg(test)]
mod tests {
use std::collections::BTreeSet;
use std::path::Path;

use anyhow::Result;
Expand Down Expand Up @@ -98,13 +97,11 @@ mod tests {
let diagnostics = test_path(
Path::new("pydocstyle").join(path).as_path(),
&settings::LinterSettings {
pydocstyle: Settings {
convention: None,
ignore_decorators: BTreeSet::from_iter(["functools.wraps".to_string()]),
property_decorators: BTreeSet::from_iter([
"gi.repository.GObject.Property".to_string()
]),
},
pydocstyle: Settings::new(
None,
["functools.wraps".to_string()],
["gi.repository.GObject.Property".to_string()],
),
..settings::LinterSettings::for_rule(rule_code)
},
)?;
Expand All @@ -129,11 +126,7 @@ mod tests {
&settings::LinterSettings {
// When inferring the convention, we'll see a few false negatives.
// See: https://github.com/PyCQA/pydocstyle/issues/459.
pydocstyle: Settings {
convention: None,
ignore_decorators: BTreeSet::new(),
property_decorators: BTreeSet::new(),
},
pydocstyle: Settings::default(),
..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
},
)?;
Expand All @@ -147,11 +140,7 @@ mod tests {
Path::new("pydocstyle/D417.py"),
&settings::LinterSettings {
// With explicit Google convention, we should flag every function.
pydocstyle: Settings {
convention: Some(Convention::Google),
ignore_decorators: BTreeSet::new(),
property_decorators: BTreeSet::new(),
},
pydocstyle: Settings::new(Some(Convention::Google), [], []),
..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
},
)?;
Expand All @@ -164,12 +153,8 @@ mod tests {
let diagnostics = test_path(
Path::new("pydocstyle/D417.py"),
&settings::LinterSettings {
// With explicit Google convention, we shouldn't flag anything.
pydocstyle: Settings {
convention: Some(Convention::Numpy),
ignore_decorators: BTreeSet::new(),
property_decorators: BTreeSet::new(),
},
// With explicit numpy convention, we shouldn't flag anything.
pydocstyle: Settings::new(Some(Convention::Numpy), [], []),
..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
},
)?;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
use std::collections::BTreeSet;

use imperative::Mood;
use once_cell::sync::Lazy;

use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::name::QualifiedName;
use ruff_python_semantic::analyze::visibility::{is_property, is_test};
use ruff_source_file::UniversalNewlines;
use ruff_text_size::Ranged;

use crate::checkers::ast::Checker;
use crate::docstrings::Docstring;
use crate::rules::pydocstyle::helpers::normalize_word;
use crate::rules::pydocstyle::settings::Settings;

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

Expand Down Expand Up @@ -66,24 +64,21 @@ impl Violation for NonImperativeMood {
pub(crate) fn non_imperative_mood(
checker: &mut Checker,
docstring: &Docstring,
property_decorators: &BTreeSet<String>,
settings: &Settings,
) {
let Some(function) = docstring.definition.as_function_def() else {
return;
};

let property_decorators = property_decorators
.iter()
.map(|decorator| QualifiedName::from_dotted_name(decorator))
.collect::<Vec<QualifiedName>>();
if is_test(&function.name) {
return;
}

if is_test(&function.name)
|| is_property(
&function.decorator_list,
&property_decorators,
checker.semantic(),
)
{
if is_property(
&function.decorator_list,
settings.property_decorators(),
checker.semantic(),
) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,7 @@ pub(crate) fn sections(
checker: &mut Checker,
docstring: &Docstring,
section_contexts: &SectionContexts,
convention: Option<&Convention>,
convention: Option<Convention>,
) {
match convention {
Some(Convention::Google) => parse_google_sections(checker, docstring, section_contexts),
Expand Down
Loading

0 comments on commit 83b1c48

Please sign in to comment.