From 490277981d92b7ac61434b6052d9b9ebe638a406 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 3 Jan 2023 20:31:13 -0500 Subject: [PATCH] Treat convention as setting ignore, rather than select --- README.md | 47 ++-------- src/pydocstyle/settings.rs | 182 +++++++++---------------------------- src/settings/mod.rs | 38 ++++---- 3 files changed, 69 insertions(+), 198 deletions(-) diff --git a/README.md b/README.md index 018c947c2946b7..78b2dabc4611cf 100644 --- a/README.md +++ b/README.md @@ -1493,51 +1493,18 @@ For example, if you're coming from `flake8-docstrings`, and your originating con `--docstring-convention=numpy`, you'd instead set `convention = "numpy"` in your `pyproject.toml`, as above. -Note that setting a `convention` is equivalent to adding that convention's specific set of codes to -your `select`. For example, `convention = "numpy"` is equivalent to: +Setting a `convention` force-disables any rules that are incompatible with that convention, no +matter how they're provided. As such, alongside `convention`, you'll want to explicitly enable the +`D` error code class, like so: ```toml [tool.ruff] -# Enable all `D` errors except `D107`, `D203`, `D212`, `D213`, `D402`, `D413`, `D415`, `D416`, -# and `D417`. select = [ - "D100", - "D101", - "D102", - "D103", - "D104", - "D105", - "D106", - "D200", - "D201", - "D202", - "D204", - "D205", - "D206", - "D207", - "D208", - "D209", - "D210", - "D211", - "D214", - "D215", - "D300", - "D301", - "D400", - "D403", - "D404", - "D405", - "D406", - "D407", - "D408", - "D409", - "D410", - "D411", - "D412", - "D414", - "D418", - "D419", + "D", ] + +[tool.ruff.pydocstyle] +convention = "google" ``` ### How can I tell what settings Ruff is using to check my code? diff --git a/src/pydocstyle/settings.rs b/src/pydocstyle/settings.rs index f09a73f696485b..48745a3207572f 100644 --- a/src/pydocstyle/settings.rs +++ b/src/pydocstyle/settings.rs @@ -4,7 +4,7 @@ use ruff_macros::ConfigurationOptions; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::registry::CheckCode; +use crate::registry_gen::CheckCodePrefix; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, JsonSchema)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] @@ -18,153 +18,55 @@ pub enum Convention { } impl Convention { - pub fn codes(&self) -> Vec { + pub fn codes(&self) -> &'static [CheckCodePrefix] { match self { - Convention::Google => vec![ + Convention::Google => &[ // All errors except D203, D204, D213, D215, D400, D401, D404, D406, D407, D408, // D409 and D413. - CheckCode::D100, - CheckCode::D101, - CheckCode::D102, - CheckCode::D103, - CheckCode::D104, - CheckCode::D105, - CheckCode::D106, - CheckCode::D107, - CheckCode::D200, - CheckCode::D201, - CheckCode::D202, - // CheckCode::D203, - // CheckCode::D204, - CheckCode::D205, - CheckCode::D206, - CheckCode::D207, - CheckCode::D208, - CheckCode::D209, - CheckCode::D210, - CheckCode::D211, - CheckCode::D212, - // CheckCode::D213, - CheckCode::D214, - // CheckCode::D215, - CheckCode::D300, - CheckCode::D301, - // CheckCode::D400, - CheckCode::D402, - CheckCode::D403, - // CheckCode::D404, - CheckCode::D405, - // CheckCode::D406, - // CheckCode::D407, - // CheckCode::D408, - // CheckCode::D409, - CheckCode::D410, - CheckCode::D411, - CheckCode::D412, - // CheckCode::D413, - CheckCode::D414, - CheckCode::D415, - CheckCode::D416, - CheckCode::D417, - CheckCode::D418, - CheckCode::D419, + CheckCodePrefix::D203, + CheckCodePrefix::D204, + CheckCodePrefix::D213, + CheckCodePrefix::D215, + CheckCodePrefix::D400, + CheckCodePrefix::D404, + CheckCodePrefix::D406, + CheckCodePrefix::D407, + CheckCodePrefix::D408, + CheckCodePrefix::D409, + CheckCodePrefix::D413, ], - Convention::Numpy => vec![ + Convention::Numpy => &[ // All errors except D107, D203, D212, D213, D402, D413, D415, D416, and D417. - CheckCode::D100, - CheckCode::D101, - CheckCode::D102, - CheckCode::D103, - CheckCode::D104, - CheckCode::D105, - CheckCode::D106, - // CheckCode::D107, - CheckCode::D200, - CheckCode::D201, - CheckCode::D202, - // CheckCode::D203, - CheckCode::D204, - CheckCode::D205, - CheckCode::D206, - CheckCode::D207, - CheckCode::D208, - CheckCode::D209, - CheckCode::D210, - CheckCode::D211, - // CheckCode::D212, - // CheckCode::D213, - CheckCode::D214, - CheckCode::D215, - CheckCode::D300, - CheckCode::D301, - CheckCode::D400, - // CheckCode::D402, - CheckCode::D403, - CheckCode::D404, - CheckCode::D405, - CheckCode::D406, - CheckCode::D407, - CheckCode::D408, - CheckCode::D409, - CheckCode::D410, - CheckCode::D411, - CheckCode::D412, - // CheckCode::D413, - CheckCode::D414, - // CheckCode::D415, - // CheckCode::D416, - // CheckCode::D417, - CheckCode::D418, - CheckCode::D419, + CheckCodePrefix::D107, + CheckCodePrefix::D203, + CheckCodePrefix::D212, + CheckCodePrefix::D213, + CheckCodePrefix::D402, + CheckCodePrefix::D413, + CheckCodePrefix::D415, + CheckCodePrefix::D416, + CheckCodePrefix::D417, ], - Convention::Pep257 => vec![ + Convention::Pep257 => &[ // All errors except D203, D212, D213, D214, D215, D404, D405, D406, D407, D408, // D409, D410, D411, D413, D415, D416 and D417. - CheckCode::D100, - CheckCode::D101, - CheckCode::D102, - CheckCode::D103, - CheckCode::D104, - CheckCode::D105, - CheckCode::D106, - CheckCode::D107, - CheckCode::D200, - CheckCode::D201, - CheckCode::D202, - // CheckCode::D203, - CheckCode::D204, - CheckCode::D205, - CheckCode::D206, - CheckCode::D207, - CheckCode::D208, - CheckCode::D209, - CheckCode::D210, - CheckCode::D211, - // CheckCode::D212, - // CheckCode::D213, - // CheckCode::D214, - // CheckCode::D215, - CheckCode::D300, - CheckCode::D301, - CheckCode::D400, - CheckCode::D402, - CheckCode::D403, - // CheckCode::D404, - // CheckCode::D405, - // CheckCode::D406, - // CheckCode::D407, - // CheckCode::D408, - // CheckCode::D409, - // CheckCode::D410, - // CheckCode::D411, - CheckCode::D412, - // CheckCode::D413, - CheckCode::D414, - // CheckCode::D415, - // CheckCode::D416, - // CheckCode::D417, - CheckCode::D418, - CheckCode::D419, + CheckCodePrefix::D203, + CheckCodePrefix::D212, + CheckCodePrefix::D213, + CheckCodePrefix::D214, + CheckCodePrefix::D215, + CheckCodePrefix::D404, + CheckCodePrefix::D405, + CheckCodePrefix::D406, + CheckCodePrefix::D407, + CheckCodePrefix::D408, + CheckCodePrefix::D409, + CheckCodePrefix::D410, + CheckCodePrefix::D411, + CheckCodePrefix::D413, + CheckCodePrefix::D415, + CheckCodePrefix::D416, + CheckCodePrefix::D417, ], } } diff --git a/src/settings/mod.rs b/src/settings/mod.rs index da11fd883f6622..ce10aa0fa2d155 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -3,11 +3,13 @@ //! to external visibility or parsing. use std::hash::{Hash, Hasher}; +use std::iter; use std::path::{Path, PathBuf}; use anyhow::{anyhow, Result}; use colored::Colorize; use globset::{Glob, GlobMatcher, GlobSet}; +use itertools::Either::{Left, Right}; use itertools::Itertools; use once_cell::sync::Lazy; use path_absolutize::path_dedot; @@ -114,12 +116,6 @@ impl Settings { .dummy_variable_rgx .unwrap_or_else(|| DEFAULT_DUMMY_VARIABLE_RGX.clone()), enabled: validate_enabled(resolve_codes( - config - .pydocstyle - .as_ref() - .and_then(|pydocstyle| pydocstyle.convention) - .map(|convention| convention.codes()) - .unwrap_or_default(), [CheckCodeSpec { select: &config .select @@ -133,6 +129,22 @@ impl Settings { .iter() .zip(config.extend_ignore.iter()) .map(|(select, ignore)| CheckCodeSpec { select, ignore }), + ) + .chain( + // If a docstring convention is specified, force-disable any incompatible error + // codes. + if let Some(convention) = config + .pydocstyle + .as_ref() + .and_then(|pydocstyle| pydocstyle.convention) + { + Left(iter::once(CheckCodeSpec { + select: &[], + ignore: convention.codes(), + })) + } else { + Right(iter::empty()) + }, ), )), exclude: resolve_globset(config.exclude.unwrap_or_else(|| DEFAULT_EXCLUDE.clone()))?, @@ -141,7 +153,6 @@ impl Settings { fix: config.fix.unwrap_or(false), fix_only: config.fix_only.unwrap_or(false), fixable: resolve_codes( - vec![], [CheckCodeSpec { select: &config.fixable.unwrap_or_else(|| CATEGORIES.to_vec()), ignore: &config.unfixable.unwrap_or_default(), @@ -392,11 +403,8 @@ struct CheckCodeSpec<'a> { /// Given a set of selected and ignored prefixes, resolve the set of enabled /// error codes. -fn resolve_codes<'a>( - baseline: Vec, - specs: impl Iterator>, -) -> FxHashSet { - let mut codes: FxHashSet = FxHashSet::from_iter(baseline); +fn resolve_codes<'a>(specs: impl Iterator>) -> FxHashSet { + let mut codes: FxHashSet = FxHashSet::default(); for spec in specs { for specificity in [ SuffixLength::None, @@ -449,7 +457,6 @@ mod tests { #[test] fn check_codes() { let actual = resolve_codes( - vec![], [CheckCodeSpec { select: &[CheckCodePrefix::W], ignore: &[], @@ -460,7 +467,6 @@ mod tests { assert_eq!(actual, expected); let actual = resolve_codes( - vec![], [CheckCodeSpec { select: &[CheckCodePrefix::W6], ignore: &[], @@ -471,7 +477,6 @@ mod tests { assert_eq!(actual, expected); let actual = resolve_codes( - vec![], [CheckCodeSpec { select: &[CheckCodePrefix::W], ignore: &[CheckCodePrefix::W292], @@ -482,7 +487,6 @@ mod tests { assert_eq!(actual, expected); let actual = resolve_codes( - vec![], [CheckCodeSpec { select: &[CheckCodePrefix::W605], ignore: &[CheckCodePrefix::W605], @@ -493,7 +497,6 @@ mod tests { assert_eq!(actual, expected); let actual = resolve_codes( - vec![], [ CheckCodeSpec { select: &[CheckCodePrefix::W], @@ -510,7 +513,6 @@ mod tests { assert_eq!(actual, expected); let actual = resolve_codes( - vec![], [ CheckCodeSpec { select: &[CheckCodePrefix::W],