diff --git a/src/registry.rs b/src/registry.rs index b7f4fc98b5..46bd936de6 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -3798,6 +3798,14 @@ impl Check { } } +/// Pairs of checks that shouldn't be enabled together. +pub const INCOMPATIBLE_CODES: &[(CheckCode, CheckCode, &str)] = &[( + CheckCode::D203, + CheckCode::D211, + "`D203` (OneBlankLineBeforeClass) and `D211` (NoBlankLinesBeforeClass) are incompatible. \ + Consider adding `D203` to `ignore`.", +)]; + /// A hash map from deprecated `CheckCodePrefix` to latest `CheckCodePrefix`. pub static PREFIX_REDIRECTS: Lazy> = Lazy::new(|| { FxHashMap::from_iter([ diff --git a/src/settings/mod.rs b/src/settings/mod.rs index f1640037b6..612059daa2 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -6,6 +6,7 @@ use std::hash::{Hash, Hasher}; use std::path::{Path, PathBuf}; use anyhow::{anyhow, Result}; +use colored::Colorize; use globset::{Glob, GlobMatcher, GlobSet}; use itertools::Itertools; use once_cell::sync::Lazy; @@ -14,7 +15,7 @@ use regex::Regex; use rustc_hash::FxHashSet; use crate::cache::cache_dir; -use crate::registry::CheckCode; +use crate::registry::{CheckCode, INCOMPATIBLE_CODES}; use crate::registry_gen::{CheckCodePrefix, SuffixLength, CATEGORIES}; use crate::settings::configuration::Configuration; use crate::settings::types::{ @@ -23,7 +24,7 @@ use crate::settings::types::{ use crate::{ flake8_annotations, flake8_bugbear, flake8_errmsg, flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, isort, - mccabe, pep8_naming, pydocstyle, pyupgrade, + mccabe, one_time_warning, pep8_naming, pydocstyle, pyupgrade, }; pub mod configuration; @@ -32,7 +33,6 @@ pub mod options; pub mod options_base; pub mod pyproject; pub mod types; - const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); #[derive(Debug)] @@ -113,7 +113,7 @@ impl Settings { dummy_variable_rgx: config .dummy_variable_rgx .unwrap_or_else(|| DEFAULT_DUMMY_VARIABLE_RGX.clone()), - enabled: resolve_codes( + enabled: validate_enabled(resolve_codes( config .pydocstyle .as_ref() @@ -134,7 +134,7 @@ impl Settings { .zip(config.extend_ignore.iter()) .map(|(select, ignore)| CheckCodeSpec { select, ignore }), ), - ), + )), exclude: resolve_globset(config.exclude.unwrap_or_else(|| DEFAULT_EXCLUDE.clone()))?, extend_exclude: resolve_globset(config.extend_exclude)?, external: FxHashSet::from_iter(config.external.unwrap_or_default()), @@ -422,6 +422,21 @@ fn resolve_codes<'a>( codes } +/// Warn if the set of enabled codes contains any incompatibilities. +fn validate_enabled(enabled: FxHashSet) -> FxHashSet { + for (a, b, message) in INCOMPATIBLE_CODES { + if enabled.contains(a) && enabled.contains(b) { + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + message.bold() + ); + } + } + enabled +} + #[cfg(test)] mod tests { use rustc_hash::FxHashSet;