diff --git a/crates/ruff/src/codes.rs b/crates/ruff/src/codes.rs index 09ee3d8b06bc1..8e4fade8a5b82 100644 --- a/crates/ruff/src/codes.rs +++ b/crates/ruff/src/codes.rs @@ -12,7 +12,7 @@ impl std::fmt::Debug for NoqaCode { } impl std::fmt::Display for NoqaCode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { write!(f, "{}{}", self.0, self.1) } } @@ -26,709 +26,719 @@ impl PartialEq<&str> for NoqaCode { } } +#[derive(Debug, Copy, Clone)] +pub enum RuleGroup { + /// The rule has not been assigned to any specific group. + Unspecified, + /// The rule is still under development, and must be enabled explicitly. + Nursery, +} + #[ruff_macros::map_codes] -pub fn code_to_rule(linter: Linter, code: &str) -> Option { +pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { #[allow(clippy::enum_glob_use)] use Linter::*; + #[rustfmt::skip] Some(match (linter, code) { // pycodestyle errors - (Pycodestyle, "E101") => Rule::MixedSpacesAndTabs, - (Pycodestyle, "E111") => Rule::IndentationWithInvalidMultiple, - (Pycodestyle, "E112") => Rule::NoIndentedBlock, - (Pycodestyle, "E113") => Rule::UnexpectedIndentation, - (Pycodestyle, "E114") => Rule::IndentationWithInvalidMultipleComment, - (Pycodestyle, "E115") => Rule::NoIndentedBlockComment, - (Pycodestyle, "E116") => Rule::UnexpectedIndentationComment, - (Pycodestyle, "E117") => Rule::OverIndented, - (Pycodestyle, "E201") => Rule::WhitespaceAfterOpenBracket, - (Pycodestyle, "E202") => Rule::WhitespaceBeforeCloseBracket, - (Pycodestyle, "E203") => Rule::WhitespaceBeforePunctuation, - (Pycodestyle, "E211") => Rule::WhitespaceBeforeParameters, - (Pycodestyle, "E221") => Rule::MultipleSpacesBeforeOperator, - (Pycodestyle, "E222") => Rule::MultipleSpacesAfterOperator, - (Pycodestyle, "E223") => Rule::TabBeforeOperator, - (Pycodestyle, "E224") => Rule::TabAfterOperator, - (Pycodestyle, "E225") => Rule::MissingWhitespaceAroundOperator, - (Pycodestyle, "E226") => Rule::MissingWhitespaceAroundArithmeticOperator, - (Pycodestyle, "E227") => Rule::MissingWhitespaceAroundBitwiseOrShiftOperator, - (Pycodestyle, "E228") => Rule::MissingWhitespaceAroundModuloOperator, - (Pycodestyle, "E231") => Rule::MissingWhitespace, - (Pycodestyle, "E251") => Rule::UnexpectedSpacesAroundKeywordParameterEquals, - (Pycodestyle, "E252") => Rule::MissingWhitespaceAroundParameterEquals, - (Pycodestyle, "E261") => Rule::TooFewSpacesBeforeInlineComment, - (Pycodestyle, "E262") => Rule::NoSpaceAfterInlineComment, - (Pycodestyle, "E265") => Rule::NoSpaceAfterBlockComment, - (Pycodestyle, "E266") => Rule::MultipleLeadingHashesForBlockComment, - (Pycodestyle, "E271") => Rule::MultipleSpacesAfterKeyword, - (Pycodestyle, "E272") => Rule::MultipleSpacesBeforeKeyword, - (Pycodestyle, "E273") => Rule::TabAfterKeyword, - (Pycodestyle, "E274") => Rule::TabBeforeKeyword, - (Pycodestyle, "E275") => Rule::MissingWhitespaceAfterKeyword, - (Pycodestyle, "E401") => Rule::MultipleImportsOnOneLine, - (Pycodestyle, "E402") => Rule::ModuleImportNotAtTopOfFile, - (Pycodestyle, "E501") => Rule::LineTooLong, - (Pycodestyle, "E701") => Rule::MultipleStatementsOnOneLineColon, - (Pycodestyle, "E702") => Rule::MultipleStatementsOnOneLineSemicolon, - (Pycodestyle, "E703") => Rule::UselessSemicolon, - (Pycodestyle, "E711") => Rule::NoneComparison, - (Pycodestyle, "E712") => Rule::TrueFalseComparison, - (Pycodestyle, "E713") => Rule::NotInTest, - (Pycodestyle, "E714") => Rule::NotIsTest, - (Pycodestyle, "E721") => Rule::TypeComparison, - (Pycodestyle, "E722") => Rule::BareExcept, - (Pycodestyle, "E731") => Rule::LambdaAssignment, - (Pycodestyle, "E741") => Rule::AmbiguousVariableName, - (Pycodestyle, "E742") => Rule::AmbiguousClassName, - (Pycodestyle, "E743") => Rule::AmbiguousFunctionName, - (Pycodestyle, "E902") => Rule::IOError, - (Pycodestyle, "E999") => Rule::SyntaxError, + (Pycodestyle, "E101") => (RuleGroup::Unspecified, Rule::MixedSpacesAndTabs), + (Pycodestyle, "E111") => (RuleGroup::Nursery, Rule::IndentationWithInvalidMultiple), + (Pycodestyle, "E112") => (RuleGroup::Nursery, Rule::NoIndentedBlock), + (Pycodestyle, "E113") => (RuleGroup::Nursery, Rule::UnexpectedIndentation), + (Pycodestyle, "E114") => (RuleGroup::Nursery, Rule::IndentationWithInvalidMultipleComment), + (Pycodestyle, "E115") => (RuleGroup::Nursery, Rule::NoIndentedBlockComment), + (Pycodestyle, "E116") => (RuleGroup::Nursery, Rule::UnexpectedIndentationComment), + (Pycodestyle, "E117") => (RuleGroup::Nursery, Rule::OverIndented), + (Pycodestyle, "E201") => (RuleGroup::Nursery, Rule::WhitespaceAfterOpenBracket), + (Pycodestyle, "E202") => (RuleGroup::Nursery, Rule::WhitespaceBeforeCloseBracket), + (Pycodestyle, "E203") => (RuleGroup::Nursery, Rule::WhitespaceBeforePunctuation), + (Pycodestyle, "E211") => (RuleGroup::Nursery, Rule::WhitespaceBeforeParameters), + (Pycodestyle, "E221") => (RuleGroup::Nursery, Rule::MultipleSpacesBeforeOperator), + (Pycodestyle, "E222") => (RuleGroup::Nursery, Rule::MultipleSpacesAfterOperator), + (Pycodestyle, "E223") => (RuleGroup::Nursery, Rule::TabBeforeOperator), + (Pycodestyle, "E224") => (RuleGroup::Nursery, Rule::TabAfterOperator), + (Pycodestyle, "E225") => (RuleGroup::Nursery, Rule::MissingWhitespaceAroundOperator), + (Pycodestyle, "E226") => (RuleGroup::Nursery, Rule::MissingWhitespaceAroundArithmeticOperator), + (Pycodestyle, "E227") => (RuleGroup::Nursery, Rule::MissingWhitespaceAroundBitwiseOrShiftOperator), + (Pycodestyle, "E228") => (RuleGroup::Nursery, Rule::MissingWhitespaceAroundModuloOperator), + (Pycodestyle, "E231") => (RuleGroup::Nursery, Rule::MissingWhitespace), + (Pycodestyle, "E251") => (RuleGroup::Nursery, Rule::UnexpectedSpacesAroundKeywordParameterEquals), + (Pycodestyle, "E252") => (RuleGroup::Nursery, Rule::MissingWhitespaceAroundParameterEquals), + (Pycodestyle, "E261") => (RuleGroup::Nursery, Rule::TooFewSpacesBeforeInlineComment), + (Pycodestyle, "E262") => (RuleGroup::Nursery, Rule::NoSpaceAfterInlineComment), + (Pycodestyle, "E265") => (RuleGroup::Nursery, Rule::NoSpaceAfterBlockComment), + (Pycodestyle, "E266") => (RuleGroup::Nursery, Rule::MultipleLeadingHashesForBlockComment), + (Pycodestyle, "E271") => (RuleGroup::Nursery, Rule::MultipleSpacesAfterKeyword), + (Pycodestyle, "E272") => (RuleGroup::Nursery, Rule::MultipleSpacesBeforeKeyword), + (Pycodestyle, "E273") => (RuleGroup::Nursery, Rule::TabAfterKeyword), + (Pycodestyle, "E274") => (RuleGroup::Nursery, Rule::TabBeforeKeyword), + (Pycodestyle, "E275") => (RuleGroup::Nursery, Rule::MissingWhitespaceAfterKeyword), + (Pycodestyle, "E401") => (RuleGroup::Unspecified, Rule::MultipleImportsOnOneLine), + (Pycodestyle, "E402") => (RuleGroup::Unspecified, Rule::ModuleImportNotAtTopOfFile), + (Pycodestyle, "E501") => (RuleGroup::Unspecified, Rule::LineTooLong), + (Pycodestyle, "E701") => (RuleGroup::Unspecified, Rule::MultipleStatementsOnOneLineColon), + (Pycodestyle, "E702") => (RuleGroup::Unspecified, Rule::MultipleStatementsOnOneLineSemicolon), + (Pycodestyle, "E703") => (RuleGroup::Unspecified, Rule::UselessSemicolon), + (Pycodestyle, "E711") => (RuleGroup::Unspecified, Rule::NoneComparison), + (Pycodestyle, "E712") => (RuleGroup::Unspecified, Rule::TrueFalseComparison), + (Pycodestyle, "E713") => (RuleGroup::Unspecified, Rule::NotInTest), + (Pycodestyle, "E714") => (RuleGroup::Unspecified, Rule::NotIsTest), + (Pycodestyle, "E721") => (RuleGroup::Unspecified, Rule::TypeComparison), + (Pycodestyle, "E722") => (RuleGroup::Unspecified, Rule::BareExcept), + (Pycodestyle, "E731") => (RuleGroup::Unspecified, Rule::LambdaAssignment), + (Pycodestyle, "E741") => (RuleGroup::Unspecified, Rule::AmbiguousVariableName), + (Pycodestyle, "E742") => (RuleGroup::Unspecified, Rule::AmbiguousClassName), + (Pycodestyle, "E743") => (RuleGroup::Unspecified, Rule::AmbiguousFunctionName), + (Pycodestyle, "E902") => (RuleGroup::Unspecified, Rule::IOError), + (Pycodestyle, "E999") => (RuleGroup::Unspecified, Rule::SyntaxError), // pycodestyle warnings - (Pycodestyle, "W191") => Rule::TabIndentation, - (Pycodestyle, "W291") => Rule::TrailingWhitespace, - (Pycodestyle, "W292") => Rule::MissingNewlineAtEndOfFile, - (Pycodestyle, "W293") => Rule::BlankLineWithWhitespace, - (Pycodestyle, "W505") => Rule::DocLineTooLong, - (Pycodestyle, "W605") => Rule::InvalidEscapeSequence, + (Pycodestyle, "W191") => (RuleGroup::Unspecified, Rule::TabIndentation), + (Pycodestyle, "W291") => (RuleGroup::Unspecified, Rule::TrailingWhitespace), + (Pycodestyle, "W292") => (RuleGroup::Unspecified, Rule::MissingNewlineAtEndOfFile), + (Pycodestyle, "W293") => (RuleGroup::Unspecified, Rule::BlankLineWithWhitespace), + (Pycodestyle, "W505") => (RuleGroup::Unspecified, Rule::DocLineTooLong), + (Pycodestyle, "W605") => (RuleGroup::Unspecified, Rule::InvalidEscapeSequence), // pyflakes - (Pyflakes, "401") => Rule::UnusedImport, - (Pyflakes, "402") => Rule::ImportShadowedByLoopVar, - (Pyflakes, "403") => Rule::UndefinedLocalWithImportStar, - (Pyflakes, "404") => Rule::LateFutureImport, - (Pyflakes, "405") => Rule::UndefinedLocalWithImportStarUsage, - (Pyflakes, "406") => Rule::UndefinedLocalWithNestedImportStarUsage, - (Pyflakes, "407") => Rule::FutureFeatureNotDefined, - (Pyflakes, "501") => Rule::PercentFormatInvalidFormat, - (Pyflakes, "502") => Rule::PercentFormatExpectedMapping, - (Pyflakes, "503") => Rule::PercentFormatExpectedSequence, - (Pyflakes, "504") => Rule::PercentFormatExtraNamedArguments, - (Pyflakes, "505") => Rule::PercentFormatMissingArgument, - (Pyflakes, "506") => Rule::PercentFormatMixedPositionalAndNamed, - (Pyflakes, "507") => Rule::PercentFormatPositionalCountMismatch, - (Pyflakes, "508") => Rule::PercentFormatStarRequiresSequence, - (Pyflakes, "509") => Rule::PercentFormatUnsupportedFormatCharacter, - (Pyflakes, "521") => Rule::StringDotFormatInvalidFormat, - (Pyflakes, "522") => Rule::StringDotFormatExtraNamedArguments, - (Pyflakes, "523") => Rule::StringDotFormatExtraPositionalArguments, - (Pyflakes, "524") => Rule::StringDotFormatMissingArguments, - (Pyflakes, "525") => Rule::StringDotFormatMixingAutomatic, - (Pyflakes, "541") => Rule::FStringMissingPlaceholders, - (Pyflakes, "601") => Rule::MultiValueRepeatedKeyLiteral, - (Pyflakes, "602") => Rule::MultiValueRepeatedKeyVariable, - (Pyflakes, "621") => Rule::ExpressionsInStarAssignment, - (Pyflakes, "622") => Rule::MultipleStarredExpressions, - (Pyflakes, "631") => Rule::AssertTuple, - (Pyflakes, "632") => Rule::IsLiteral, - (Pyflakes, "633") => Rule::InvalidPrintSyntax, - (Pyflakes, "634") => Rule::IfTuple, - (Pyflakes, "701") => Rule::BreakOutsideLoop, - (Pyflakes, "702") => Rule::ContinueOutsideLoop, - (Pyflakes, "704") => Rule::YieldOutsideFunction, - (Pyflakes, "706") => Rule::ReturnOutsideFunction, - (Pyflakes, "707") => Rule::DefaultExceptNotLast, - (Pyflakes, "722") => Rule::ForwardAnnotationSyntaxError, - (Pyflakes, "811") => Rule::RedefinedWhileUnused, - (Pyflakes, "821") => Rule::UndefinedName, - (Pyflakes, "822") => Rule::UndefinedExport, - (Pyflakes, "823") => Rule::UndefinedLocal, - (Pyflakes, "841") => Rule::UnusedVariable, - (Pyflakes, "842") => Rule::UnusedAnnotation, - (Pyflakes, "901") => Rule::RaiseNotImplemented, + (Pyflakes, "401") => (RuleGroup::Unspecified, Rule::UnusedImport), + (Pyflakes, "402") => (RuleGroup::Unspecified, Rule::ImportShadowedByLoopVar), + (Pyflakes, "403") => (RuleGroup::Unspecified, Rule::UndefinedLocalWithImportStar), + (Pyflakes, "404") => (RuleGroup::Unspecified, Rule::LateFutureImport), + (Pyflakes, "405") => (RuleGroup::Unspecified, Rule::UndefinedLocalWithImportStarUsage), + (Pyflakes, "406") => (RuleGroup::Unspecified, Rule::UndefinedLocalWithNestedImportStarUsage), + (Pyflakes, "407") => (RuleGroup::Unspecified, Rule::FutureFeatureNotDefined), + (Pyflakes, "501") => (RuleGroup::Unspecified, Rule::PercentFormatInvalidFormat), + (Pyflakes, "502") => (RuleGroup::Unspecified, Rule::PercentFormatExpectedMapping), + (Pyflakes, "503") => (RuleGroup::Unspecified, Rule::PercentFormatExpectedSequence), + (Pyflakes, "504") => (RuleGroup::Unspecified, Rule::PercentFormatExtraNamedArguments), + (Pyflakes, "505") => (RuleGroup::Unspecified, Rule::PercentFormatMissingArgument), + (Pyflakes, "506") => (RuleGroup::Unspecified, Rule::PercentFormatMixedPositionalAndNamed), + (Pyflakes, "507") => (RuleGroup::Unspecified, Rule::PercentFormatPositionalCountMismatch), + (Pyflakes, "508") => (RuleGroup::Unspecified, Rule::PercentFormatStarRequiresSequence), + (Pyflakes, "509") => (RuleGroup::Unspecified, Rule::PercentFormatUnsupportedFormatCharacter), + (Pyflakes, "521") => (RuleGroup::Unspecified, Rule::StringDotFormatInvalidFormat), + (Pyflakes, "522") => (RuleGroup::Unspecified, Rule::StringDotFormatExtraNamedArguments), + (Pyflakes, "523") => (RuleGroup::Unspecified, Rule::StringDotFormatExtraPositionalArguments), + (Pyflakes, "524") => (RuleGroup::Unspecified, Rule::StringDotFormatMissingArguments), + (Pyflakes, "525") => (RuleGroup::Unspecified, Rule::StringDotFormatMixingAutomatic), + (Pyflakes, "541") => (RuleGroup::Unspecified, Rule::FStringMissingPlaceholders), + (Pyflakes, "601") => (RuleGroup::Unspecified, Rule::MultiValueRepeatedKeyLiteral), + (Pyflakes, "602") => (RuleGroup::Unspecified, Rule::MultiValueRepeatedKeyVariable), + (Pyflakes, "621") => (RuleGroup::Unspecified, Rule::ExpressionsInStarAssignment), + (Pyflakes, "622") => (RuleGroup::Unspecified, Rule::MultipleStarredExpressions), + (Pyflakes, "631") => (RuleGroup::Unspecified, Rule::AssertTuple), + (Pyflakes, "632") => (RuleGroup::Unspecified, Rule::IsLiteral), + (Pyflakes, "633") => (RuleGroup::Unspecified, Rule::InvalidPrintSyntax), + (Pyflakes, "634") => (RuleGroup::Unspecified, Rule::IfTuple), + (Pyflakes, "701") => (RuleGroup::Unspecified, Rule::BreakOutsideLoop), + (Pyflakes, "702") => (RuleGroup::Unspecified, Rule::ContinueOutsideLoop), + (Pyflakes, "704") => (RuleGroup::Unspecified, Rule::YieldOutsideFunction), + (Pyflakes, "706") => (RuleGroup::Unspecified, Rule::ReturnOutsideFunction), + (Pyflakes, "707") => (RuleGroup::Unspecified, Rule::DefaultExceptNotLast), + (Pyflakes, "722") => (RuleGroup::Unspecified, Rule::ForwardAnnotationSyntaxError), + (Pyflakes, "811") => (RuleGroup::Unspecified, Rule::RedefinedWhileUnused), + (Pyflakes, "821") => (RuleGroup::Unspecified, Rule::UndefinedName), + (Pyflakes, "822") => (RuleGroup::Unspecified, Rule::UndefinedExport), + (Pyflakes, "823") => (RuleGroup::Unspecified, Rule::UndefinedLocal), + (Pyflakes, "841") => (RuleGroup::Unspecified, Rule::UnusedVariable), + (Pyflakes, "842") => (RuleGroup::Unspecified, Rule::UnusedAnnotation), + (Pyflakes, "901") => (RuleGroup::Unspecified, Rule::RaiseNotImplemented), // pylint - (Pylint, "C0414") => Rule::UselessImportAlias, - (Pylint, "C1901") => Rule::CompareToEmptyString, - (Pylint, "C3002") => Rule::UnnecessaryDirectLambdaCall, - (Pylint, "E0100") => Rule::YieldInInit, - (Pylint, "E0101") => Rule::ReturnInInit, - (Pylint, "E0116") => Rule::ContinueInFinally, - (Pylint, "E0117") => Rule::NonlocalWithoutBinding, - (Pylint, "E0118") => Rule::LoadBeforeGlobalDeclaration, - (Pylint, "E0604") => Rule::InvalidAllObject, - (Pylint, "E0605") => Rule::InvalidAllFormat, - (Pylint, "E1142") => Rule::AwaitOutsideAsync, - (Pylint, "E1205") => Rule::LoggingTooManyArgs, - (Pylint, "E1206") => Rule::LoggingTooFewArgs, - (Pylint, "E1307") => Rule::BadStringFormatType, - (Pylint, "E1310") => Rule::BadStrStripCall, - (Pylint, "E1507") => Rule::InvalidEnvvarValue, - (Pylint, "E2502") => Rule::BidirectionalUnicode, - (Pylint, "E2510") => Rule::InvalidCharacterBackspace, - (Pylint, "E2512") => Rule::InvalidCharacterSub, - (Pylint, "E2513") => Rule::InvalidCharacterEsc, - (Pylint, "E2514") => Rule::InvalidCharacterNul, - (Pylint, "E2515") => Rule::InvalidCharacterZeroWidthSpace, - (Pylint, "R0133") => Rule::ComparisonOfConstant, - (Pylint, "R0206") => Rule::PropertyWithParameters, - (Pylint, "R0402") => Rule::ManualFromImport, - (Pylint, "R0911") => Rule::TooManyReturnStatements, - (Pylint, "R0912") => Rule::TooManyBranches, - (Pylint, "R0913") => Rule::TooManyArguments, - (Pylint, "R0915") => Rule::TooManyStatements, - (Pylint, "R1701") => Rule::RepeatedIsinstanceCalls, - (Pylint, "R1711") => Rule::UselessReturn, - (Pylint, "R1722") => Rule::SysExitAlias, - (Pylint, "R2004") => Rule::MagicValueComparison, - (Pylint, "R5501") => Rule::CollapsibleElseIf, - (Pylint, "W0120") => Rule::UselessElseOnLoop, - (Pylint, "W0129") => Rule::AssertOnStringLiteral, - (Pylint, "W0406") => Rule::ImportSelf, - (Pylint, "W0602") => Rule::GlobalVariableNotAssigned, - (Pylint, "W0603") => Rule::GlobalStatement, - (Pylint, "W0711") => Rule::BinaryOpException, - (Pylint, "W1508") => Rule::InvalidEnvvarDefault, - (Pylint, "W2901") => Rule::RedefinedLoopName, - (Pylint, "E0302") => Rule::UnexpectedSpecialMethodSignature, - (Pylint, "W3301") => Rule::NestedMinMax, - (Pylint, "E0241") => Rule::DuplicateBases, + (Pylint, "C0414") => (RuleGroup::Unspecified, Rule::UselessImportAlias), + (Pylint, "C1901") => (RuleGroup::Unspecified, Rule::CompareToEmptyString), + (Pylint, "C3002") => (RuleGroup::Unspecified, Rule::UnnecessaryDirectLambdaCall), + (Pylint, "E0100") => (RuleGroup::Unspecified, Rule::YieldInInit), + (Pylint, "E0101") => (RuleGroup::Unspecified, Rule::ReturnInInit), + (Pylint, "E0116") => (RuleGroup::Unspecified, Rule::ContinueInFinally), + (Pylint, "E0117") => (RuleGroup::Unspecified, Rule::NonlocalWithoutBinding), + (Pylint, "E0118") => (RuleGroup::Unspecified, Rule::LoadBeforeGlobalDeclaration), + (Pylint, "E0241") => (RuleGroup::Unspecified, Rule::DuplicateBases), + (Pylint, "E0302") => (RuleGroup::Unspecified, Rule::UnexpectedSpecialMethodSignature), + (Pylint, "E0604") => (RuleGroup::Unspecified, Rule::InvalidAllObject), + (Pylint, "E0605") => (RuleGroup::Unspecified, Rule::InvalidAllFormat), + (Pylint, "E1142") => (RuleGroup::Unspecified, Rule::AwaitOutsideAsync), + (Pylint, "E1205") => (RuleGroup::Unspecified, Rule::LoggingTooManyArgs), + (Pylint, "E1206") => (RuleGroup::Unspecified, Rule::LoggingTooFewArgs), + (Pylint, "E1307") => (RuleGroup::Unspecified, Rule::BadStringFormatType), + (Pylint, "E1310") => (RuleGroup::Unspecified, Rule::BadStrStripCall), + (Pylint, "E1507") => (RuleGroup::Unspecified, Rule::InvalidEnvvarValue), + (Pylint, "E2502") => (RuleGroup::Unspecified, Rule::BidirectionalUnicode), + (Pylint, "E2510") => (RuleGroup::Unspecified, Rule::InvalidCharacterBackspace), + (Pylint, "E2512") => (RuleGroup::Unspecified, Rule::InvalidCharacterSub), + (Pylint, "E2513") => (RuleGroup::Unspecified, Rule::InvalidCharacterEsc), + (Pylint, "E2514") => (RuleGroup::Unspecified, Rule::InvalidCharacterNul), + (Pylint, "E2515") => (RuleGroup::Unspecified, Rule::InvalidCharacterZeroWidthSpace), + (Pylint, "R0133") => (RuleGroup::Unspecified, Rule::ComparisonOfConstant), + (Pylint, "R0206") => (RuleGroup::Unspecified, Rule::PropertyWithParameters), + (Pylint, "R0402") => (RuleGroup::Unspecified, Rule::ManualFromImport), + (Pylint, "R0911") => (RuleGroup::Unspecified, Rule::TooManyReturnStatements), + (Pylint, "R0912") => (RuleGroup::Unspecified, Rule::TooManyBranches), + (Pylint, "R0913") => (RuleGroup::Unspecified, Rule::TooManyArguments), + (Pylint, "R0915") => (RuleGroup::Unspecified, Rule::TooManyStatements), + (Pylint, "R1701") => (RuleGroup::Unspecified, Rule::RepeatedIsinstanceCalls), + (Pylint, "R1711") => (RuleGroup::Unspecified, Rule::UselessReturn), + (Pylint, "R1722") => (RuleGroup::Unspecified, Rule::SysExitAlias), + (Pylint, "R2004") => (RuleGroup::Unspecified, Rule::MagicValueComparison), + (Pylint, "R5501") => (RuleGroup::Unspecified, Rule::CollapsibleElseIf), + (Pylint, "W0120") => (RuleGroup::Unspecified, Rule::UselessElseOnLoop), + (Pylint, "W0129") => (RuleGroup::Unspecified, Rule::AssertOnStringLiteral), + (Pylint, "W0406") => (RuleGroup::Unspecified, Rule::ImportSelf), + (Pylint, "W0602") => (RuleGroup::Unspecified, Rule::GlobalVariableNotAssigned), + (Pylint, "W0603") => (RuleGroup::Unspecified, Rule::GlobalStatement), + (Pylint, "W0711") => (RuleGroup::Unspecified, Rule::BinaryOpException), + (Pylint, "W1508") => (RuleGroup::Unspecified, Rule::InvalidEnvvarDefault), + (Pylint, "W2901") => (RuleGroup::Unspecified, Rule::RedefinedLoopName), + (Pylint, "W3301") => (RuleGroup::Unspecified, Rule::NestedMinMax), // flake8-async - (Flake8Async, "100") => Rule::BlockingHttpCallInAsyncFunction, - (Flake8Async, "101") => Rule::OpenSleepOrSubprocessInAsyncFunction, - (Flake8Async, "102") => Rule::BlockingOsCallInAsyncFunction, + (Flake8Async, "100") => (RuleGroup::Unspecified, Rule::BlockingHttpCallInAsyncFunction), + (Flake8Async, "101") => (RuleGroup::Unspecified, Rule::OpenSleepOrSubprocessInAsyncFunction), + (Flake8Async, "102") => (RuleGroup::Unspecified, Rule::BlockingOsCallInAsyncFunction), // flake8-builtins - (Flake8Builtins, "001") => Rule::BuiltinVariableShadowing, - (Flake8Builtins, "002") => Rule::BuiltinArgumentShadowing, - (Flake8Builtins, "003") => Rule::BuiltinAttributeShadowing, + (Flake8Builtins, "001") => (RuleGroup::Unspecified, Rule::BuiltinVariableShadowing), + (Flake8Builtins, "002") => (RuleGroup::Unspecified, Rule::BuiltinArgumentShadowing), + (Flake8Builtins, "003") => (RuleGroup::Unspecified, Rule::BuiltinAttributeShadowing), // flake8-bugbear - (Flake8Bugbear, "002") => Rule::UnaryPrefixIncrement, - (Flake8Bugbear, "003") => Rule::AssignmentToOsEnviron, - (Flake8Bugbear, "004") => Rule::UnreliableCallableCheck, - (Flake8Bugbear, "005") => Rule::StripWithMultiCharacters, - (Flake8Bugbear, "006") => Rule::MutableArgumentDefault, - (Flake8Bugbear, "007") => Rule::UnusedLoopControlVariable, - (Flake8Bugbear, "008") => Rule::FunctionCallInDefaultArgument, - (Flake8Bugbear, "009") => Rule::GetAttrWithConstant, - (Flake8Bugbear, "010") => Rule::SetAttrWithConstant, - (Flake8Bugbear, "011") => Rule::AssertFalse, - (Flake8Bugbear, "012") => Rule::JumpStatementInFinally, - (Flake8Bugbear, "013") => Rule::RedundantTupleInExceptionHandler, - (Flake8Bugbear, "014") => Rule::DuplicateHandlerException, - (Flake8Bugbear, "015") => Rule::UselessComparison, - (Flake8Bugbear, "016") => Rule::CannotRaiseLiteral, - (Flake8Bugbear, "017") => Rule::AssertRaisesException, - (Flake8Bugbear, "018") => Rule::UselessExpression, - (Flake8Bugbear, "019") => Rule::CachedInstanceMethod, - (Flake8Bugbear, "020") => Rule::LoopVariableOverridesIterator, - (Flake8Bugbear, "021") => Rule::FStringDocstring, - (Flake8Bugbear, "022") => Rule::UselessContextlibSuppress, - (Flake8Bugbear, "023") => Rule::FunctionUsesLoopVariable, - (Flake8Bugbear, "024") => Rule::AbstractBaseClassWithoutAbstractMethod, - (Flake8Bugbear, "025") => Rule::DuplicateTryBlockException, - (Flake8Bugbear, "026") => Rule::StarArgUnpackingAfterKeywordArg, - (Flake8Bugbear, "027") => Rule::EmptyMethodWithoutAbstractDecorator, - (Flake8Bugbear, "028") => Rule::NoExplicitStacklevel, - (Flake8Bugbear, "029") => Rule::ExceptWithEmptyTuple, - (Flake8Bugbear, "030") => Rule::ExceptWithNonExceptionClasses, - (Flake8Bugbear, "031") => Rule::ReuseOfGroupbyGenerator, - (Flake8Bugbear, "032") => Rule::UnintentionalTypeAnnotation, - (Flake8Bugbear, "904") => Rule::RaiseWithoutFromInsideExcept, - (Flake8Bugbear, "905") => Rule::ZipWithoutExplicitStrict, + (Flake8Bugbear, "002") => (RuleGroup::Unspecified, Rule::UnaryPrefixIncrement), + (Flake8Bugbear, "003") => (RuleGroup::Unspecified, Rule::AssignmentToOsEnviron), + (Flake8Bugbear, "004") => (RuleGroup::Unspecified, Rule::UnreliableCallableCheck), + (Flake8Bugbear, "005") => (RuleGroup::Unspecified, Rule::StripWithMultiCharacters), + (Flake8Bugbear, "006") => (RuleGroup::Unspecified, Rule::MutableArgumentDefault), + (Flake8Bugbear, "007") => (RuleGroup::Unspecified, Rule::UnusedLoopControlVariable), + (Flake8Bugbear, "008") => (RuleGroup::Unspecified, Rule::FunctionCallInDefaultArgument), + (Flake8Bugbear, "009") => (RuleGroup::Unspecified, Rule::GetAttrWithConstant), + (Flake8Bugbear, "010") => (RuleGroup::Unspecified, Rule::SetAttrWithConstant), + (Flake8Bugbear, "011") => (RuleGroup::Unspecified, Rule::AssertFalse), + (Flake8Bugbear, "012") => (RuleGroup::Unspecified, Rule::JumpStatementInFinally), + (Flake8Bugbear, "013") => (RuleGroup::Unspecified, Rule::RedundantTupleInExceptionHandler), + (Flake8Bugbear, "014") => (RuleGroup::Unspecified, Rule::DuplicateHandlerException), + (Flake8Bugbear, "015") => (RuleGroup::Unspecified, Rule::UselessComparison), + (Flake8Bugbear, "016") => (RuleGroup::Unspecified, Rule::CannotRaiseLiteral), + (Flake8Bugbear, "017") => (RuleGroup::Unspecified, Rule::AssertRaisesException), + (Flake8Bugbear, "018") => (RuleGroup::Unspecified, Rule::UselessExpression), + (Flake8Bugbear, "019") => (RuleGroup::Unspecified, Rule::CachedInstanceMethod), + (Flake8Bugbear, "020") => (RuleGroup::Unspecified, Rule::LoopVariableOverridesIterator), + (Flake8Bugbear, "021") => (RuleGroup::Unspecified, Rule::FStringDocstring), + (Flake8Bugbear, "022") => (RuleGroup::Unspecified, Rule::UselessContextlibSuppress), + (Flake8Bugbear, "023") => (RuleGroup::Unspecified, Rule::FunctionUsesLoopVariable), + (Flake8Bugbear, "024") => (RuleGroup::Unspecified, Rule::AbstractBaseClassWithoutAbstractMethod), + (Flake8Bugbear, "025") => (RuleGroup::Unspecified, Rule::DuplicateTryBlockException), + (Flake8Bugbear, "026") => (RuleGroup::Unspecified, Rule::StarArgUnpackingAfterKeywordArg), + (Flake8Bugbear, "027") => (RuleGroup::Unspecified, Rule::EmptyMethodWithoutAbstractDecorator), + (Flake8Bugbear, "028") => (RuleGroup::Unspecified, Rule::NoExplicitStacklevel), + (Flake8Bugbear, "029") => (RuleGroup::Unspecified, Rule::ExceptWithEmptyTuple), + (Flake8Bugbear, "030") => (RuleGroup::Unspecified, Rule::ExceptWithNonExceptionClasses), + (Flake8Bugbear, "031") => (RuleGroup::Unspecified, Rule::ReuseOfGroupbyGenerator), + (Flake8Bugbear, "032") => (RuleGroup::Unspecified, Rule::UnintentionalTypeAnnotation), + (Flake8Bugbear, "904") => (RuleGroup::Unspecified, Rule::RaiseWithoutFromInsideExcept), + (Flake8Bugbear, "905") => (RuleGroup::Unspecified, Rule::ZipWithoutExplicitStrict), // flake8-blind-except - (Flake8BlindExcept, "001") => Rule::BlindExcept, + (Flake8BlindExcept, "001") => (RuleGroup::Unspecified, Rule::BlindExcept), // flake8-comprehensions - (Flake8Comprehensions, "00") => Rule::UnnecessaryGeneratorList, - (Flake8Comprehensions, "01") => Rule::UnnecessaryGeneratorSet, - (Flake8Comprehensions, "02") => Rule::UnnecessaryGeneratorDict, - (Flake8Comprehensions, "03") => Rule::UnnecessaryListComprehensionSet, - (Flake8Comprehensions, "04") => Rule::UnnecessaryListComprehensionDict, - (Flake8Comprehensions, "05") => Rule::UnnecessaryLiteralSet, - (Flake8Comprehensions, "06") => Rule::UnnecessaryLiteralDict, - (Flake8Comprehensions, "08") => Rule::UnnecessaryCollectionCall, - (Flake8Comprehensions, "09") => Rule::UnnecessaryLiteralWithinTupleCall, - (Flake8Comprehensions, "10") => Rule::UnnecessaryLiteralWithinListCall, - (Flake8Comprehensions, "11") => Rule::UnnecessaryListCall, - (Flake8Comprehensions, "13") => Rule::UnnecessaryCallAroundSorted, - (Flake8Comprehensions, "14") => Rule::UnnecessaryDoubleCastOrProcess, - (Flake8Comprehensions, "15") => Rule::UnnecessarySubscriptReversal, - (Flake8Comprehensions, "16") => Rule::UnnecessaryComprehension, - (Flake8Comprehensions, "17") => Rule::UnnecessaryMap, - (Flake8Comprehensions, "18") => Rule::UnnecessaryLiteralWithinDictCall, - (Flake8Comprehensions, "19") => Rule::UnnecessaryComprehensionAnyAll, + (Flake8Comprehensions, "00") => (RuleGroup::Unspecified, Rule::UnnecessaryGeneratorList), + (Flake8Comprehensions, "01") => (RuleGroup::Unspecified, Rule::UnnecessaryGeneratorSet), + (Flake8Comprehensions, "02") => (RuleGroup::Unspecified, Rule::UnnecessaryGeneratorDict), + (Flake8Comprehensions, "03") => (RuleGroup::Unspecified, Rule::UnnecessaryListComprehensionSet), + (Flake8Comprehensions, "04") => (RuleGroup::Unspecified, Rule::UnnecessaryListComprehensionDict), + (Flake8Comprehensions, "05") => (RuleGroup::Unspecified, Rule::UnnecessaryLiteralSet), + (Flake8Comprehensions, "06") => (RuleGroup::Unspecified, Rule::UnnecessaryLiteralDict), + (Flake8Comprehensions, "08") => (RuleGroup::Unspecified, Rule::UnnecessaryCollectionCall), + (Flake8Comprehensions, "09") => (RuleGroup::Unspecified, Rule::UnnecessaryLiteralWithinTupleCall), + (Flake8Comprehensions, "10") => (RuleGroup::Unspecified, Rule::UnnecessaryLiteralWithinListCall), + (Flake8Comprehensions, "11") => (RuleGroup::Unspecified, Rule::UnnecessaryListCall), + (Flake8Comprehensions, "13") => (RuleGroup::Unspecified, Rule::UnnecessaryCallAroundSorted), + (Flake8Comprehensions, "14") => (RuleGroup::Unspecified, Rule::UnnecessaryDoubleCastOrProcess), + (Flake8Comprehensions, "15") => (RuleGroup::Unspecified, Rule::UnnecessarySubscriptReversal), + (Flake8Comprehensions, "16") => (RuleGroup::Unspecified, Rule::UnnecessaryComprehension), + (Flake8Comprehensions, "17") => (RuleGroup::Unspecified, Rule::UnnecessaryMap), + (Flake8Comprehensions, "18") => (RuleGroup::Unspecified, Rule::UnnecessaryLiteralWithinDictCall), + (Flake8Comprehensions, "19") => (RuleGroup::Unspecified, Rule::UnnecessaryComprehensionAnyAll), // flake8-debugger - (Flake8Debugger, "0") => Rule::Debugger, + (Flake8Debugger, "0") => (RuleGroup::Unspecified, Rule::Debugger), // mccabe - (McCabe, "1") => Rule::ComplexStructure, + (McCabe, "1") => (RuleGroup::Unspecified, Rule::ComplexStructure), // flake8-tidy-imports - (Flake8TidyImports, "251") => Rule::BannedApi, - (Flake8TidyImports, "252") => Rule::RelativeImports, + (Flake8TidyImports, "251") => (RuleGroup::Unspecified, Rule::BannedApi), + (Flake8TidyImports, "252") => (RuleGroup::Unspecified, Rule::RelativeImports), // flake8-return - (Flake8Return, "501") => Rule::UnnecessaryReturnNone, - (Flake8Return, "502") => Rule::ImplicitReturnValue, - (Flake8Return, "503") => Rule::ImplicitReturn, - (Flake8Return, "504") => Rule::UnnecessaryAssign, - (Flake8Return, "505") => Rule::SuperfluousElseReturn, - (Flake8Return, "506") => Rule::SuperfluousElseRaise, - (Flake8Return, "507") => Rule::SuperfluousElseContinue, - (Flake8Return, "508") => Rule::SuperfluousElseBreak, + (Flake8Return, "501") => (RuleGroup::Unspecified, Rule::UnnecessaryReturnNone), + (Flake8Return, "502") => (RuleGroup::Unspecified, Rule::ImplicitReturnValue), + (Flake8Return, "503") => (RuleGroup::Unspecified, Rule::ImplicitReturn), + (Flake8Return, "504") => (RuleGroup::Unspecified, Rule::UnnecessaryAssign), + (Flake8Return, "505") => (RuleGroup::Unspecified, Rule::SuperfluousElseReturn), + (Flake8Return, "506") => (RuleGroup::Unspecified, Rule::SuperfluousElseRaise), + (Flake8Return, "507") => (RuleGroup::Unspecified, Rule::SuperfluousElseContinue), + (Flake8Return, "508") => (RuleGroup::Unspecified, Rule::SuperfluousElseBreak), // flake8-gettext - (Flake8GetText, "001") => Rule::FStringInGetTextFuncCall, - (Flake8GetText, "002") => Rule::FormatInGetTextFuncCall, - (Flake8GetText, "003") => Rule::PrintfInGetTextFuncCall, + (Flake8GetText, "001") => (RuleGroup::Unspecified, Rule::FStringInGetTextFuncCall), + (Flake8GetText, "002") => (RuleGroup::Unspecified, Rule::FormatInGetTextFuncCall), + (Flake8GetText, "003") => (RuleGroup::Unspecified, Rule::PrintfInGetTextFuncCall), // flake8-implicit-str-concat - (Flake8ImplicitStrConcat, "001") => Rule::SingleLineImplicitStringConcatenation, - (Flake8ImplicitStrConcat, "002") => Rule::MultiLineImplicitStringConcatenation, - (Flake8ImplicitStrConcat, "003") => Rule::ExplicitStringConcatenation, + (Flake8ImplicitStrConcat, "001") => (RuleGroup::Unspecified, Rule::SingleLineImplicitStringConcatenation), + (Flake8ImplicitStrConcat, "002") => (RuleGroup::Unspecified, Rule::MultiLineImplicitStringConcatenation), + (Flake8ImplicitStrConcat, "003") => (RuleGroup::Unspecified, Rule::ExplicitStringConcatenation), // flake8-print - (Flake8Print, "1") => Rule::Print, - (Flake8Print, "3") => Rule::PPrint, + (Flake8Print, "1") => (RuleGroup::Unspecified, Rule::Print), + (Flake8Print, "3") => (RuleGroup::Unspecified, Rule::PPrint), // flake8-quotes - (Flake8Quotes, "000") => Rule::BadQuotesInlineString, - (Flake8Quotes, "001") => Rule::BadQuotesMultilineString, - (Flake8Quotes, "002") => Rule::BadQuotesDocstring, - (Flake8Quotes, "003") => Rule::AvoidableEscapedQuote, + (Flake8Quotes, "000") => (RuleGroup::Unspecified, Rule::BadQuotesInlineString), + (Flake8Quotes, "001") => (RuleGroup::Unspecified, Rule::BadQuotesMultilineString), + (Flake8Quotes, "002") => (RuleGroup::Unspecified, Rule::BadQuotesDocstring), + (Flake8Quotes, "003") => (RuleGroup::Unspecified, Rule::AvoidableEscapedQuote), // flake8-annotations - (Flake8Annotations, "001") => Rule::MissingTypeFunctionArgument, - (Flake8Annotations, "002") => Rule::MissingTypeArgs, - (Flake8Annotations, "003") => Rule::MissingTypeKwargs, - (Flake8Annotations, "101") => Rule::MissingTypeSelf, - (Flake8Annotations, "102") => Rule::MissingTypeCls, - (Flake8Annotations, "201") => Rule::MissingReturnTypeUndocumentedPublicFunction, - (Flake8Annotations, "202") => Rule::MissingReturnTypePrivateFunction, - (Flake8Annotations, "204") => Rule::MissingReturnTypeSpecialMethod, - (Flake8Annotations, "205") => Rule::MissingReturnTypeStaticMethod, - (Flake8Annotations, "206") => Rule::MissingReturnTypeClassMethod, - (Flake8Annotations, "401") => Rule::AnyType, + (Flake8Annotations, "001") => (RuleGroup::Unspecified, Rule::MissingTypeFunctionArgument), + (Flake8Annotations, "002") => (RuleGroup::Unspecified, Rule::MissingTypeArgs), + (Flake8Annotations, "003") => (RuleGroup::Unspecified, Rule::MissingTypeKwargs), + (Flake8Annotations, "101") => (RuleGroup::Unspecified, Rule::MissingTypeSelf), + (Flake8Annotations, "102") => (RuleGroup::Unspecified, Rule::MissingTypeCls), + (Flake8Annotations, "201") => (RuleGroup::Unspecified, Rule::MissingReturnTypeUndocumentedPublicFunction), + (Flake8Annotations, "202") => (RuleGroup::Unspecified, Rule::MissingReturnTypePrivateFunction), + (Flake8Annotations, "204") => (RuleGroup::Unspecified, Rule::MissingReturnTypeSpecialMethod), + (Flake8Annotations, "205") => (RuleGroup::Unspecified, Rule::MissingReturnTypeStaticMethod), + (Flake8Annotations, "206") => (RuleGroup::Unspecified, Rule::MissingReturnTypeClassMethod), + (Flake8Annotations, "401") => (RuleGroup::Unspecified, Rule::AnyType), // flake8-future-annotations - (Flake8FutureAnnotations, "100") => Rule::MissingFutureAnnotationsImport, + (Flake8FutureAnnotations, "100") => (RuleGroup::Unspecified, Rule::MissingFutureAnnotationsImport), // flake8-2020 - (Flake82020, "101") => Rule::SysVersionSlice3, - (Flake82020, "102") => Rule::SysVersion2, - (Flake82020, "103") => Rule::SysVersionCmpStr3, - (Flake82020, "201") => Rule::SysVersionInfo0Eq3, - (Flake82020, "202") => Rule::SixPY3, - (Flake82020, "203") => Rule::SysVersionInfo1CmpInt, - (Flake82020, "204") => Rule::SysVersionInfoMinorCmpInt, - (Flake82020, "301") => Rule::SysVersion0, - (Flake82020, "302") => Rule::SysVersionCmpStr10, - (Flake82020, "303") => Rule::SysVersionSlice1, + (Flake82020, "101") => (RuleGroup::Unspecified, Rule::SysVersionSlice3), + (Flake82020, "102") => (RuleGroup::Unspecified, Rule::SysVersion2), + (Flake82020, "103") => (RuleGroup::Unspecified, Rule::SysVersionCmpStr3), + (Flake82020, "201") => (RuleGroup::Unspecified, Rule::SysVersionInfo0Eq3), + (Flake82020, "202") => (RuleGroup::Unspecified, Rule::SixPY3), + (Flake82020, "203") => (RuleGroup::Unspecified, Rule::SysVersionInfo1CmpInt), + (Flake82020, "204") => (RuleGroup::Unspecified, Rule::SysVersionInfoMinorCmpInt), + (Flake82020, "301") => (RuleGroup::Unspecified, Rule::SysVersion0), + (Flake82020, "302") => (RuleGroup::Unspecified, Rule::SysVersionCmpStr10), + (Flake82020, "303") => (RuleGroup::Unspecified, Rule::SysVersionSlice1), // flake8-simplify - (Flake8Simplify, "101") => Rule::DuplicateIsinstanceCall, - (Flake8Simplify, "102") => Rule::CollapsibleIf, - (Flake8Simplify, "103") => Rule::NeedlessBool, - (Flake8Simplify, "105") => Rule::SuppressibleException, - (Flake8Simplify, "107") => Rule::ReturnInTryExceptFinally, - (Flake8Simplify, "108") => Rule::IfElseBlockInsteadOfIfExp, - (Flake8Simplify, "109") => Rule::CompareWithTuple, - (Flake8Simplify, "110") => Rule::ReimplementedBuiltin, - (Flake8Simplify, "112") => Rule::UncapitalizedEnvironmentVariables, - (Flake8Simplify, "114") => Rule::IfWithSameArms, - (Flake8Simplify, "115") => Rule::OpenFileWithContextHandler, - (Flake8Simplify, "116") => Rule::IfElseBlockInsteadOfDictLookup, - (Flake8Simplify, "117") => Rule::MultipleWithStatements, - (Flake8Simplify, "118") => Rule::InDictKeys, - (Flake8Simplify, "201") => Rule::NegateEqualOp, - (Flake8Simplify, "202") => Rule::NegateNotEqualOp, - (Flake8Simplify, "208") => Rule::DoubleNegation, - (Flake8Simplify, "210") => Rule::IfExprWithTrueFalse, - (Flake8Simplify, "211") => Rule::IfExprWithFalseTrue, - (Flake8Simplify, "212") => Rule::IfExprWithTwistedArms, - (Flake8Simplify, "220") => Rule::ExprAndNotExpr, - (Flake8Simplify, "221") => Rule::ExprOrNotExpr, - (Flake8Simplify, "222") => Rule::ExprOrTrue, - (Flake8Simplify, "223") => Rule::ExprAndFalse, - (Flake8Simplify, "300") => Rule::YodaConditions, - (Flake8Simplify, "401") => Rule::IfElseBlockInsteadOfDictGet, - (Flake8Simplify, "910") => Rule::DictGetWithNoneDefault, + (Flake8Simplify, "101") => (RuleGroup::Unspecified, Rule::DuplicateIsinstanceCall), + (Flake8Simplify, "102") => (RuleGroup::Unspecified, Rule::CollapsibleIf), + (Flake8Simplify, "103") => (RuleGroup::Unspecified, Rule::NeedlessBool), + (Flake8Simplify, "105") => (RuleGroup::Unspecified, Rule::SuppressibleException), + (Flake8Simplify, "107") => (RuleGroup::Unspecified, Rule::ReturnInTryExceptFinally), + (Flake8Simplify, "108") => (RuleGroup::Unspecified, Rule::IfElseBlockInsteadOfIfExp), + (Flake8Simplify, "109") => (RuleGroup::Unspecified, Rule::CompareWithTuple), + (Flake8Simplify, "110") => (RuleGroup::Unspecified, Rule::ReimplementedBuiltin), + (Flake8Simplify, "112") => (RuleGroup::Unspecified, Rule::UncapitalizedEnvironmentVariables), + (Flake8Simplify, "114") => (RuleGroup::Unspecified, Rule::IfWithSameArms), + (Flake8Simplify, "115") => (RuleGroup::Unspecified, Rule::OpenFileWithContextHandler), + (Flake8Simplify, "116") => (RuleGroup::Unspecified, Rule::IfElseBlockInsteadOfDictLookup), + (Flake8Simplify, "117") => (RuleGroup::Unspecified, Rule::MultipleWithStatements), + (Flake8Simplify, "118") => (RuleGroup::Unspecified, Rule::InDictKeys), + (Flake8Simplify, "201") => (RuleGroup::Unspecified, Rule::NegateEqualOp), + (Flake8Simplify, "202") => (RuleGroup::Unspecified, Rule::NegateNotEqualOp), + (Flake8Simplify, "208") => (RuleGroup::Unspecified, Rule::DoubleNegation), + (Flake8Simplify, "210") => (RuleGroup::Unspecified, Rule::IfExprWithTrueFalse), + (Flake8Simplify, "211") => (RuleGroup::Unspecified, Rule::IfExprWithFalseTrue), + (Flake8Simplify, "212") => (RuleGroup::Unspecified, Rule::IfExprWithTwistedArms), + (Flake8Simplify, "220") => (RuleGroup::Unspecified, Rule::ExprAndNotExpr), + (Flake8Simplify, "221") => (RuleGroup::Unspecified, Rule::ExprOrNotExpr), + (Flake8Simplify, "222") => (RuleGroup::Unspecified, Rule::ExprOrTrue), + (Flake8Simplify, "223") => (RuleGroup::Unspecified, Rule::ExprAndFalse), + (Flake8Simplify, "300") => (RuleGroup::Unspecified, Rule::YodaConditions), + (Flake8Simplify, "401") => (RuleGroup::Unspecified, Rule::IfElseBlockInsteadOfDictGet), + (Flake8Simplify, "910") => (RuleGroup::Unspecified, Rule::DictGetWithNoneDefault), // pyupgrade - (Pyupgrade, "001") => Rule::UselessMetaclassType, - (Pyupgrade, "003") => Rule::TypeOfPrimitive, - (Pyupgrade, "004") => Rule::UselessObjectInheritance, - (Pyupgrade, "005") => Rule::DeprecatedUnittestAlias, - (Pyupgrade, "006") => Rule::NonPEP585Annotation, - (Pyupgrade, "007") => Rule::NonPEP604Annotation, - (Pyupgrade, "008") => Rule::SuperCallWithParameters, - (Pyupgrade, "009") => Rule::UTF8EncodingDeclaration, - (Pyupgrade, "010") => Rule::UnnecessaryFutureImport, - (Pyupgrade, "011") => Rule::LRUCacheWithoutParameters, - (Pyupgrade, "012") => Rule::UnnecessaryEncodeUTF8, - (Pyupgrade, "013") => Rule::ConvertTypedDictFunctionalToClass, - (Pyupgrade, "014") => Rule::ConvertNamedTupleFunctionalToClass, - (Pyupgrade, "015") => Rule::RedundantOpenModes, - (Pyupgrade, "017") => Rule::DatetimeTimezoneUTC, - (Pyupgrade, "018") => Rule::NativeLiterals, - (Pyupgrade, "019") => Rule::TypingTextStrAlias, - (Pyupgrade, "020") => Rule::OpenAlias, - (Pyupgrade, "021") => Rule::ReplaceUniversalNewlines, - (Pyupgrade, "022") => Rule::ReplaceStdoutStderr, - (Pyupgrade, "023") => Rule::DeprecatedCElementTree, - (Pyupgrade, "024") => Rule::OSErrorAlias, - (Pyupgrade, "025") => Rule::UnicodeKindPrefix, - (Pyupgrade, "026") => Rule::DeprecatedMockImport, - (Pyupgrade, "027") => Rule::UnpackedListComprehension, - (Pyupgrade, "028") => Rule::YieldInForLoop, - (Pyupgrade, "029") => Rule::UnnecessaryBuiltinImport, - (Pyupgrade, "030") => Rule::FormatLiterals, - (Pyupgrade, "031") => Rule::PrintfStringFormatting, - (Pyupgrade, "032") => Rule::FString, - (Pyupgrade, "033") => Rule::LRUCacheWithMaxsizeNone, - (Pyupgrade, "034") => Rule::ExtraneousParentheses, - (Pyupgrade, "035") => Rule::DeprecatedImport, - (Pyupgrade, "036") => Rule::OutdatedVersionBlock, - (Pyupgrade, "037") => Rule::QuotedAnnotation, - (Pyupgrade, "038") => Rule::NonPEP604Isinstance, + (Pyupgrade, "001") => (RuleGroup::Unspecified, Rule::UselessMetaclassType), + (Pyupgrade, "003") => (RuleGroup::Unspecified, Rule::TypeOfPrimitive), + (Pyupgrade, "004") => (RuleGroup::Unspecified, Rule::UselessObjectInheritance), + (Pyupgrade, "005") => (RuleGroup::Unspecified, Rule::DeprecatedUnittestAlias), + (Pyupgrade, "006") => (RuleGroup::Unspecified, Rule::NonPEP585Annotation), + (Pyupgrade, "007") => (RuleGroup::Unspecified, Rule::NonPEP604Annotation), + (Pyupgrade, "008") => (RuleGroup::Unspecified, Rule::SuperCallWithParameters), + (Pyupgrade, "009") => (RuleGroup::Unspecified, Rule::UTF8EncodingDeclaration), + (Pyupgrade, "010") => (RuleGroup::Unspecified, Rule::UnnecessaryFutureImport), + (Pyupgrade, "011") => (RuleGroup::Unspecified, Rule::LRUCacheWithoutParameters), + (Pyupgrade, "012") => (RuleGroup::Unspecified, Rule::UnnecessaryEncodeUTF8), + (Pyupgrade, "013") => (RuleGroup::Unspecified, Rule::ConvertTypedDictFunctionalToClass), + (Pyupgrade, "014") => (RuleGroup::Unspecified, Rule::ConvertNamedTupleFunctionalToClass), + (Pyupgrade, "015") => (RuleGroup::Unspecified, Rule::RedundantOpenModes), + (Pyupgrade, "017") => (RuleGroup::Unspecified, Rule::DatetimeTimezoneUTC), + (Pyupgrade, "018") => (RuleGroup::Unspecified, Rule::NativeLiterals), + (Pyupgrade, "019") => (RuleGroup::Unspecified, Rule::TypingTextStrAlias), + (Pyupgrade, "020") => (RuleGroup::Unspecified, Rule::OpenAlias), + (Pyupgrade, "021") => (RuleGroup::Unspecified, Rule::ReplaceUniversalNewlines), + (Pyupgrade, "022") => (RuleGroup::Unspecified, Rule::ReplaceStdoutStderr), + (Pyupgrade, "023") => (RuleGroup::Unspecified, Rule::DeprecatedCElementTree), + (Pyupgrade, "024") => (RuleGroup::Unspecified, Rule::OSErrorAlias), + (Pyupgrade, "025") => (RuleGroup::Unspecified, Rule::UnicodeKindPrefix), + (Pyupgrade, "026") => (RuleGroup::Unspecified, Rule::DeprecatedMockImport), + (Pyupgrade, "027") => (RuleGroup::Unspecified, Rule::UnpackedListComprehension), + (Pyupgrade, "028") => (RuleGroup::Unspecified, Rule::YieldInForLoop), + (Pyupgrade, "029") => (RuleGroup::Unspecified, Rule::UnnecessaryBuiltinImport), + (Pyupgrade, "030") => (RuleGroup::Unspecified, Rule::FormatLiterals), + (Pyupgrade, "031") => (RuleGroup::Unspecified, Rule::PrintfStringFormatting), + (Pyupgrade, "032") => (RuleGroup::Unspecified, Rule::FString), + (Pyupgrade, "033") => (RuleGroup::Unspecified, Rule::LRUCacheWithMaxsizeNone), + (Pyupgrade, "034") => (RuleGroup::Unspecified, Rule::ExtraneousParentheses), + (Pyupgrade, "035") => (RuleGroup::Unspecified, Rule::DeprecatedImport), + (Pyupgrade, "036") => (RuleGroup::Unspecified, Rule::OutdatedVersionBlock), + (Pyupgrade, "037") => (RuleGroup::Unspecified, Rule::QuotedAnnotation), + (Pyupgrade, "038") => (RuleGroup::Unspecified, Rule::NonPEP604Isinstance), // pydocstyle - (Pydocstyle, "100") => Rule::UndocumentedPublicModule, - (Pydocstyle, "101") => Rule::UndocumentedPublicClass, - (Pydocstyle, "102") => Rule::UndocumentedPublicMethod, - (Pydocstyle, "103") => Rule::UndocumentedPublicFunction, - (Pydocstyle, "104") => Rule::UndocumentedPublicPackage, - (Pydocstyle, "105") => Rule::UndocumentedMagicMethod, - (Pydocstyle, "106") => Rule::UndocumentedPublicNestedClass, - (Pydocstyle, "107") => Rule::UndocumentedPublicInit, - (Pydocstyle, "200") => Rule::FitsOnOneLine, - (Pydocstyle, "201") => Rule::NoBlankLineBeforeFunction, - (Pydocstyle, "202") => Rule::NoBlankLineAfterFunction, - (Pydocstyle, "203") => Rule::OneBlankLineBeforeClass, - (Pydocstyle, "204") => Rule::OneBlankLineAfterClass, - (Pydocstyle, "205") => Rule::BlankLineAfterSummary, - (Pydocstyle, "206") => Rule::IndentWithSpaces, - (Pydocstyle, "207") => Rule::UnderIndentation, - (Pydocstyle, "208") => Rule::OverIndentation, - (Pydocstyle, "209") => Rule::NewLineAfterLastParagraph, - (Pydocstyle, "210") => Rule::SurroundingWhitespace, - (Pydocstyle, "211") => Rule::BlankLineBeforeClass, - (Pydocstyle, "212") => Rule::MultiLineSummaryFirstLine, - (Pydocstyle, "213") => Rule::MultiLineSummarySecondLine, - (Pydocstyle, "214") => Rule::SectionNotOverIndented, - (Pydocstyle, "215") => Rule::SectionUnderlineNotOverIndented, - (Pydocstyle, "300") => Rule::TripleSingleQuotes, - (Pydocstyle, "301") => Rule::EscapeSequenceInDocstring, - (Pydocstyle, "400") => Rule::EndsInPeriod, - (Pydocstyle, "401") => Rule::NonImperativeMood, - (Pydocstyle, "402") => Rule::NoSignature, - (Pydocstyle, "403") => Rule::FirstLineCapitalized, - (Pydocstyle, "404") => Rule::DocstringStartsWithThis, - (Pydocstyle, "405") => Rule::CapitalizeSectionName, - (Pydocstyle, "406") => Rule::NewLineAfterSectionName, - (Pydocstyle, "407") => Rule::DashedUnderlineAfterSection, - (Pydocstyle, "408") => Rule::SectionUnderlineAfterName, - (Pydocstyle, "409") => Rule::SectionUnderlineMatchesSectionLength, - (Pydocstyle, "410") => Rule::NoBlankLineAfterSection, - (Pydocstyle, "411") => Rule::NoBlankLineBeforeSection, - (Pydocstyle, "412") => Rule::BlankLinesBetweenHeaderAndContent, - (Pydocstyle, "413") => Rule::BlankLineAfterLastSection, - (Pydocstyle, "414") => Rule::EmptyDocstringSection, - (Pydocstyle, "415") => Rule::EndsInPunctuation, - (Pydocstyle, "416") => Rule::SectionNameEndsInColon, - (Pydocstyle, "417") => Rule::UndocumentedParam, - (Pydocstyle, "418") => Rule::OverloadWithDocstring, - (Pydocstyle, "419") => Rule::EmptyDocstring, + (Pydocstyle, "100") => (RuleGroup::Unspecified, Rule::UndocumentedPublicModule), + (Pydocstyle, "101") => (RuleGroup::Unspecified, Rule::UndocumentedPublicClass), + (Pydocstyle, "102") => (RuleGroup::Unspecified, Rule::UndocumentedPublicMethod), + (Pydocstyle, "103") => (RuleGroup::Unspecified, Rule::UndocumentedPublicFunction), + (Pydocstyle, "104") => (RuleGroup::Unspecified, Rule::UndocumentedPublicPackage), + (Pydocstyle, "105") => (RuleGroup::Unspecified, Rule::UndocumentedMagicMethod), + (Pydocstyle, "106") => (RuleGroup::Unspecified, Rule::UndocumentedPublicNestedClass), + (Pydocstyle, "107") => (RuleGroup::Unspecified, Rule::UndocumentedPublicInit), + (Pydocstyle, "200") => (RuleGroup::Unspecified, Rule::FitsOnOneLine), + (Pydocstyle, "201") => (RuleGroup::Unspecified, Rule::NoBlankLineBeforeFunction), + (Pydocstyle, "202") => (RuleGroup::Unspecified, Rule::NoBlankLineAfterFunction), + (Pydocstyle, "203") => (RuleGroup::Unspecified, Rule::OneBlankLineBeforeClass), + (Pydocstyle, "204") => (RuleGroup::Unspecified, Rule::OneBlankLineAfterClass), + (Pydocstyle, "205") => (RuleGroup::Unspecified, Rule::BlankLineAfterSummary), + (Pydocstyle, "206") => (RuleGroup::Unspecified, Rule::IndentWithSpaces), + (Pydocstyle, "207") => (RuleGroup::Unspecified, Rule::UnderIndentation), + (Pydocstyle, "208") => (RuleGroup::Unspecified, Rule::OverIndentation), + (Pydocstyle, "209") => (RuleGroup::Unspecified, Rule::NewLineAfterLastParagraph), + (Pydocstyle, "210") => (RuleGroup::Unspecified, Rule::SurroundingWhitespace), + (Pydocstyle, "211") => (RuleGroup::Unspecified, Rule::BlankLineBeforeClass), + (Pydocstyle, "212") => (RuleGroup::Unspecified, Rule::MultiLineSummaryFirstLine), + (Pydocstyle, "213") => (RuleGroup::Unspecified, Rule::MultiLineSummarySecondLine), + (Pydocstyle, "214") => (RuleGroup::Unspecified, Rule::SectionNotOverIndented), + (Pydocstyle, "215") => (RuleGroup::Unspecified, Rule::SectionUnderlineNotOverIndented), + (Pydocstyle, "300") => (RuleGroup::Unspecified, Rule::TripleSingleQuotes), + (Pydocstyle, "301") => (RuleGroup::Unspecified, Rule::EscapeSequenceInDocstring), + (Pydocstyle, "400") => (RuleGroup::Unspecified, Rule::EndsInPeriod), + (Pydocstyle, "401") => (RuleGroup::Unspecified, Rule::NonImperativeMood), + (Pydocstyle, "402") => (RuleGroup::Unspecified, Rule::NoSignature), + (Pydocstyle, "403") => (RuleGroup::Unspecified, Rule::FirstLineCapitalized), + (Pydocstyle, "404") => (RuleGroup::Unspecified, Rule::DocstringStartsWithThis), + (Pydocstyle, "405") => (RuleGroup::Unspecified, Rule::CapitalizeSectionName), + (Pydocstyle, "406") => (RuleGroup::Unspecified, Rule::NewLineAfterSectionName), + (Pydocstyle, "407") => (RuleGroup::Unspecified, Rule::DashedUnderlineAfterSection), + (Pydocstyle, "408") => (RuleGroup::Unspecified, Rule::SectionUnderlineAfterName), + (Pydocstyle, "409") => (RuleGroup::Unspecified, Rule::SectionUnderlineMatchesSectionLength), + (Pydocstyle, "410") => (RuleGroup::Unspecified, Rule::NoBlankLineAfterSection), + (Pydocstyle, "411") => (RuleGroup::Unspecified, Rule::NoBlankLineBeforeSection), + (Pydocstyle, "412") => (RuleGroup::Unspecified, Rule::BlankLinesBetweenHeaderAndContent), + (Pydocstyle, "413") => (RuleGroup::Unspecified, Rule::BlankLineAfterLastSection), + (Pydocstyle, "414") => (RuleGroup::Unspecified, Rule::EmptyDocstringSection), + (Pydocstyle, "415") => (RuleGroup::Unspecified, Rule::EndsInPunctuation), + (Pydocstyle, "416") => (RuleGroup::Unspecified, Rule::SectionNameEndsInColon), + (Pydocstyle, "417") => (RuleGroup::Unspecified, Rule::UndocumentedParam), + (Pydocstyle, "418") => (RuleGroup::Unspecified, Rule::OverloadWithDocstring), + (Pydocstyle, "419") => (RuleGroup::Unspecified, Rule::EmptyDocstring), // pep8-naming - (PEP8Naming, "801") => Rule::InvalidClassName, - (PEP8Naming, "802") => Rule::InvalidFunctionName, - (PEP8Naming, "803") => Rule::InvalidArgumentName, - (PEP8Naming, "804") => Rule::InvalidFirstArgumentNameForClassMethod, - (PEP8Naming, "805") => Rule::InvalidFirstArgumentNameForMethod, - (PEP8Naming, "806") => Rule::NonLowercaseVariableInFunction, - (PEP8Naming, "807") => Rule::DunderFunctionName, - (PEP8Naming, "811") => Rule::ConstantImportedAsNonConstant, - (PEP8Naming, "812") => Rule::LowercaseImportedAsNonLowercase, - (PEP8Naming, "813") => Rule::CamelcaseImportedAsLowercase, - (PEP8Naming, "814") => Rule::CamelcaseImportedAsConstant, - (PEP8Naming, "815") => Rule::MixedCaseVariableInClassScope, - (PEP8Naming, "816") => Rule::MixedCaseVariableInGlobalScope, - (PEP8Naming, "817") => Rule::CamelcaseImportedAsAcronym, - (PEP8Naming, "818") => Rule::ErrorSuffixOnExceptionName, - (PEP8Naming, "999") => Rule::InvalidModuleName, + (PEP8Naming, "801") => (RuleGroup::Unspecified, Rule::InvalidClassName), + (PEP8Naming, "802") => (RuleGroup::Unspecified, Rule::InvalidFunctionName), + (PEP8Naming, "803") => (RuleGroup::Unspecified, Rule::InvalidArgumentName), + (PEP8Naming, "804") => (RuleGroup::Unspecified, Rule::InvalidFirstArgumentNameForClassMethod), + (PEP8Naming, "805") => (RuleGroup::Unspecified, Rule::InvalidFirstArgumentNameForMethod), + (PEP8Naming, "806") => (RuleGroup::Unspecified, Rule::NonLowercaseVariableInFunction), + (PEP8Naming, "807") => (RuleGroup::Unspecified, Rule::DunderFunctionName), + (PEP8Naming, "811") => (RuleGroup::Unspecified, Rule::ConstantImportedAsNonConstant), + (PEP8Naming, "812") => (RuleGroup::Unspecified, Rule::LowercaseImportedAsNonLowercase), + (PEP8Naming, "813") => (RuleGroup::Unspecified, Rule::CamelcaseImportedAsLowercase), + (PEP8Naming, "814") => (RuleGroup::Unspecified, Rule::CamelcaseImportedAsConstant), + (PEP8Naming, "815") => (RuleGroup::Unspecified, Rule::MixedCaseVariableInClassScope), + (PEP8Naming, "816") => (RuleGroup::Unspecified, Rule::MixedCaseVariableInGlobalScope), + (PEP8Naming, "817") => (RuleGroup::Unspecified, Rule::CamelcaseImportedAsAcronym), + (PEP8Naming, "818") => (RuleGroup::Unspecified, Rule::ErrorSuffixOnExceptionName), + (PEP8Naming, "999") => (RuleGroup::Unspecified, Rule::InvalidModuleName), // isort - (Isort, "001") => Rule::UnsortedImports, - (Isort, "002") => Rule::MissingRequiredImport, + (Isort, "001") => (RuleGroup::Unspecified, Rule::UnsortedImports), + (Isort, "002") => (RuleGroup::Unspecified, Rule::MissingRequiredImport), // eradicate - (Eradicate, "001") => Rule::CommentedOutCode, + (Eradicate, "001") => (RuleGroup::Unspecified, Rule::CommentedOutCode), // flake8-bandit - (Flake8Bandit, "101") => Rule::Assert, - (Flake8Bandit, "102") => Rule::ExecBuiltin, - (Flake8Bandit, "103") => Rule::BadFilePermissions, - (Flake8Bandit, "104") => Rule::HardcodedBindAllInterfaces, - (Flake8Bandit, "105") => Rule::HardcodedPasswordString, - (Flake8Bandit, "106") => Rule::HardcodedPasswordFuncArg, - (Flake8Bandit, "107") => Rule::HardcodedPasswordDefault, - (Flake8Bandit, "108") => Rule::HardcodedTempFile, - (Flake8Bandit, "110") => Rule::TryExceptPass, - (Flake8Bandit, "112") => Rule::TryExceptContinue, - (Flake8Bandit, "113") => Rule::RequestWithoutTimeout, - (Flake8Bandit, "301") => Rule::SuspiciousPickleUsage, - (Flake8Bandit, "302") => Rule::SuspiciousMarshalUsage, - (Flake8Bandit, "303") => Rule::SuspiciousInsecureHashUsage, - (Flake8Bandit, "304") => Rule::SuspiciousInsecureCipherUsage, - (Flake8Bandit, "305") => Rule::SuspiciousInsecureCipherModeUsage, - (Flake8Bandit, "306") => Rule::SuspiciousMktempUsage, - (Flake8Bandit, "307") => Rule::SuspiciousEvalUsage, - (Flake8Bandit, "308") => Rule::SuspiciousMarkSafeUsage, - (Flake8Bandit, "310") => Rule::SuspiciousURLOpenUsage, - (Flake8Bandit, "311") => Rule::SuspiciousNonCryptographicRandomUsage, - (Flake8Bandit, "312") => Rule::SuspiciousTelnetUsage, - (Flake8Bandit, "313") => Rule::SuspiciousXMLCElementTreeUsage, - (Flake8Bandit, "314") => Rule::SuspiciousXMLElementTreeUsage, - (Flake8Bandit, "315") => Rule::SuspiciousXMLExpatReaderUsage, - (Flake8Bandit, "316") => Rule::SuspiciousXMLExpatBuilderUsage, - (Flake8Bandit, "317") => Rule::SuspiciousXMLSaxUsage, - (Flake8Bandit, "318") => Rule::SuspiciousXMLMiniDOMUsage, - (Flake8Bandit, "319") => Rule::SuspiciousXMLPullDOMUsage, - (Flake8Bandit, "320") => Rule::SuspiciousXMLETreeUsage, - (Flake8Bandit, "321") => Rule::SuspiciousFTPLibUsage, - (Flake8Bandit, "323") => Rule::SuspiciousUnverifiedContextUsage, - (Flake8Bandit, "324") => Rule::HashlibInsecureHashFunction, - (Flake8Bandit, "501") => Rule::RequestWithNoCertValidation, - (Flake8Bandit, "506") => Rule::UnsafeYAMLLoad, - (Flake8Bandit, "508") => Rule::SnmpInsecureVersion, - (Flake8Bandit, "509") => Rule::SnmpWeakCryptography, - (Flake8Bandit, "602") => Rule::SubprocessPopenWithShellEqualsTrue, - (Flake8Bandit, "603") => Rule::SubprocessWithoutShellEqualsTrue, - (Flake8Bandit, "604") => Rule::CallWithShellEqualsTrue, - (Flake8Bandit, "605") => Rule::StartProcessWithAShell, - (Flake8Bandit, "606") => Rule::StartProcessWithNoShell, - (Flake8Bandit, "607") => Rule::StartProcessWithPartialPath, - (Flake8Bandit, "608") => Rule::HardcodedSQLExpression, - (Flake8Bandit, "612") => Rule::LoggingConfigInsecureListen, - (Flake8Bandit, "701") => Rule::Jinja2AutoescapeFalse, + (Flake8Bandit, "101") => (RuleGroup::Unspecified, Rule::Assert), + (Flake8Bandit, "102") => (RuleGroup::Unspecified, Rule::ExecBuiltin), + (Flake8Bandit, "103") => (RuleGroup::Unspecified, Rule::BadFilePermissions), + (Flake8Bandit, "104") => (RuleGroup::Unspecified, Rule::HardcodedBindAllInterfaces), + (Flake8Bandit, "105") => (RuleGroup::Unspecified, Rule::HardcodedPasswordString), + (Flake8Bandit, "106") => (RuleGroup::Unspecified, Rule::HardcodedPasswordFuncArg), + (Flake8Bandit, "107") => (RuleGroup::Unspecified, Rule::HardcodedPasswordDefault), + (Flake8Bandit, "108") => (RuleGroup::Unspecified, Rule::HardcodedTempFile), + (Flake8Bandit, "110") => (RuleGroup::Unspecified, Rule::TryExceptPass), + (Flake8Bandit, "112") => (RuleGroup::Unspecified, Rule::TryExceptContinue), + (Flake8Bandit, "113") => (RuleGroup::Unspecified, Rule::RequestWithoutTimeout), + (Flake8Bandit, "301") => (RuleGroup::Unspecified, Rule::SuspiciousPickleUsage), + (Flake8Bandit, "302") => (RuleGroup::Unspecified, Rule::SuspiciousMarshalUsage), + (Flake8Bandit, "303") => (RuleGroup::Unspecified, Rule::SuspiciousInsecureHashUsage), + (Flake8Bandit, "304") => (RuleGroup::Unspecified, Rule::SuspiciousInsecureCipherUsage), + (Flake8Bandit, "305") => (RuleGroup::Unspecified, Rule::SuspiciousInsecureCipherModeUsage), + (Flake8Bandit, "306") => (RuleGroup::Unspecified, Rule::SuspiciousMktempUsage), + (Flake8Bandit, "307") => (RuleGroup::Unspecified, Rule::SuspiciousEvalUsage), + (Flake8Bandit, "308") => (RuleGroup::Unspecified, Rule::SuspiciousMarkSafeUsage), + (Flake8Bandit, "310") => (RuleGroup::Unspecified, Rule::SuspiciousURLOpenUsage), + (Flake8Bandit, "311") => (RuleGroup::Unspecified, Rule::SuspiciousNonCryptographicRandomUsage), + (Flake8Bandit, "312") => (RuleGroup::Unspecified, Rule::SuspiciousTelnetUsage), + (Flake8Bandit, "313") => (RuleGroup::Unspecified, Rule::SuspiciousXMLCElementTreeUsage), + (Flake8Bandit, "314") => (RuleGroup::Unspecified, Rule::SuspiciousXMLElementTreeUsage), + (Flake8Bandit, "315") => (RuleGroup::Unspecified, Rule::SuspiciousXMLExpatReaderUsage), + (Flake8Bandit, "316") => (RuleGroup::Unspecified, Rule::SuspiciousXMLExpatBuilderUsage), + (Flake8Bandit, "317") => (RuleGroup::Unspecified, Rule::SuspiciousXMLSaxUsage), + (Flake8Bandit, "318") => (RuleGroup::Unspecified, Rule::SuspiciousXMLMiniDOMUsage), + (Flake8Bandit, "319") => (RuleGroup::Unspecified, Rule::SuspiciousXMLPullDOMUsage), + (Flake8Bandit, "320") => (RuleGroup::Unspecified, Rule::SuspiciousXMLETreeUsage), + (Flake8Bandit, "321") => (RuleGroup::Unspecified, Rule::SuspiciousFTPLibUsage), + (Flake8Bandit, "323") => (RuleGroup::Unspecified, Rule::SuspiciousUnverifiedContextUsage), + (Flake8Bandit, "324") => (RuleGroup::Unspecified, Rule::HashlibInsecureHashFunction), + (Flake8Bandit, "501") => (RuleGroup::Unspecified, Rule::RequestWithNoCertValidation), + (Flake8Bandit, "506") => (RuleGroup::Unspecified, Rule::UnsafeYAMLLoad), + (Flake8Bandit, "508") => (RuleGroup::Unspecified, Rule::SnmpInsecureVersion), + (Flake8Bandit, "509") => (RuleGroup::Unspecified, Rule::SnmpWeakCryptography), + (Flake8Bandit, "602") => (RuleGroup::Unspecified, Rule::SubprocessPopenWithShellEqualsTrue), + (Flake8Bandit, "603") => (RuleGroup::Unspecified, Rule::SubprocessWithoutShellEqualsTrue), + (Flake8Bandit, "604") => (RuleGroup::Unspecified, Rule::CallWithShellEqualsTrue), + (Flake8Bandit, "605") => (RuleGroup::Unspecified, Rule::StartProcessWithAShell), + (Flake8Bandit, "606") => (RuleGroup::Unspecified, Rule::StartProcessWithNoShell), + (Flake8Bandit, "607") => (RuleGroup::Unspecified, Rule::StartProcessWithPartialPath), + (Flake8Bandit, "608") => (RuleGroup::Unspecified, Rule::HardcodedSQLExpression), + (Flake8Bandit, "612") => (RuleGroup::Unspecified, Rule::LoggingConfigInsecureListen), + (Flake8Bandit, "701") => (RuleGroup::Unspecified, Rule::Jinja2AutoescapeFalse), // flake8-boolean-trap - (Flake8BooleanTrap, "001") => Rule::BooleanPositionalArgInFunctionDefinition, - (Flake8BooleanTrap, "002") => Rule::BooleanDefaultValueInFunctionDefinition, - (Flake8BooleanTrap, "003") => Rule::BooleanPositionalValueInFunctionCall, + (Flake8BooleanTrap, "001") => (RuleGroup::Unspecified, Rule::BooleanPositionalArgInFunctionDefinition), + (Flake8BooleanTrap, "002") => (RuleGroup::Unspecified, Rule::BooleanDefaultValueInFunctionDefinition), + (Flake8BooleanTrap, "003") => (RuleGroup::Unspecified, Rule::BooleanPositionalValueInFunctionCall), // flake8-unused-arguments - (Flake8UnusedArguments, "001") => Rule::UnusedFunctionArgument, - (Flake8UnusedArguments, "002") => Rule::UnusedMethodArgument, - (Flake8UnusedArguments, "003") => Rule::UnusedClassMethodArgument, - (Flake8UnusedArguments, "004") => Rule::UnusedStaticMethodArgument, - (Flake8UnusedArguments, "005") => Rule::UnusedLambdaArgument, + (Flake8UnusedArguments, "001") => (RuleGroup::Unspecified, Rule::UnusedFunctionArgument), + (Flake8UnusedArguments, "002") => (RuleGroup::Unspecified, Rule::UnusedMethodArgument), + (Flake8UnusedArguments, "003") => (RuleGroup::Unspecified, Rule::UnusedClassMethodArgument), + (Flake8UnusedArguments, "004") => (RuleGroup::Unspecified, Rule::UnusedStaticMethodArgument), + (Flake8UnusedArguments, "005") => (RuleGroup::Unspecified, Rule::UnusedLambdaArgument), // flake8-import-conventions - (Flake8ImportConventions, "001") => Rule::UnconventionalImportAlias, - (Flake8ImportConventions, "002") => Rule::BannedImportAlias, - (Flake8ImportConventions, "003") => Rule::BannedImportFrom, + (Flake8ImportConventions, "001") => (RuleGroup::Unspecified, Rule::UnconventionalImportAlias), + (Flake8ImportConventions, "002") => (RuleGroup::Unspecified, Rule::BannedImportAlias), + (Flake8ImportConventions, "003") => (RuleGroup::Unspecified, Rule::BannedImportFrom), // flake8-datetimez - (Flake8Datetimez, "001") => Rule::CallDatetimeWithoutTzinfo, - (Flake8Datetimez, "002") => Rule::CallDatetimeToday, - (Flake8Datetimez, "003") => Rule::CallDatetimeUtcnow, - (Flake8Datetimez, "004") => Rule::CallDatetimeUtcfromtimestamp, - (Flake8Datetimez, "005") => Rule::CallDatetimeNowWithoutTzinfo, - (Flake8Datetimez, "006") => Rule::CallDatetimeFromtimestamp, - (Flake8Datetimez, "007") => Rule::CallDatetimeStrptimeWithoutZone, - (Flake8Datetimez, "011") => Rule::CallDateToday, - (Flake8Datetimez, "012") => Rule::CallDateFromtimestamp, + (Flake8Datetimez, "001") => (RuleGroup::Unspecified, Rule::CallDatetimeWithoutTzinfo), + (Flake8Datetimez, "002") => (RuleGroup::Unspecified, Rule::CallDatetimeToday), + (Flake8Datetimez, "003") => (RuleGroup::Unspecified, Rule::CallDatetimeUtcnow), + (Flake8Datetimez, "004") => (RuleGroup::Unspecified, Rule::CallDatetimeUtcfromtimestamp), + (Flake8Datetimez, "005") => (RuleGroup::Unspecified, Rule::CallDatetimeNowWithoutTzinfo), + (Flake8Datetimez, "006") => (RuleGroup::Unspecified, Rule::CallDatetimeFromtimestamp), + (Flake8Datetimez, "007") => (RuleGroup::Unspecified, Rule::CallDatetimeStrptimeWithoutZone), + (Flake8Datetimez, "011") => (RuleGroup::Unspecified, Rule::CallDateToday), + (Flake8Datetimez, "012") => (RuleGroup::Unspecified, Rule::CallDateFromtimestamp), // pygrep-hooks - (PygrepHooks, "001") => Rule::Eval, - (PygrepHooks, "002") => Rule::DeprecatedLogWarn, - (PygrepHooks, "003") => Rule::BlanketTypeIgnore, - (PygrepHooks, "004") => Rule::BlanketNOQA, - (PygrepHooks, "005") => Rule::InvalidMockAccess, + (PygrepHooks, "001") => (RuleGroup::Unspecified, Rule::Eval), + (PygrepHooks, "002") => (RuleGroup::Unspecified, Rule::DeprecatedLogWarn), + (PygrepHooks, "003") => (RuleGroup::Unspecified, Rule::BlanketTypeIgnore), + (PygrepHooks, "004") => (RuleGroup::Unspecified, Rule::BlanketNOQA), + (PygrepHooks, "005") => (RuleGroup::Unspecified, Rule::InvalidMockAccess), // pandas-vet - (PandasVet, "002") => Rule::PandasUseOfInplaceArgument, - (PandasVet, "003") => Rule::PandasUseOfDotIsNull, - (PandasVet, "004") => Rule::PandasUseOfDotNotNull, - (PandasVet, "007") => Rule::PandasUseOfDotIx, - (PandasVet, "008") => Rule::PandasUseOfDotAt, - (PandasVet, "009") => Rule::PandasUseOfDotIat, - (PandasVet, "010") => Rule::PandasUseOfDotPivotOrUnstack, - (PandasVet, "011") => Rule::PandasUseOfDotValues, - (PandasVet, "012") => Rule::PandasUseOfDotReadTable, - (PandasVet, "013") => Rule::PandasUseOfDotStack, - (PandasVet, "015") => Rule::PandasUseOfPdMerge, - (PandasVet, "901") => Rule::PandasDfVariableName, + (PandasVet, "002") => (RuleGroup::Unspecified, Rule::PandasUseOfInplaceArgument), + (PandasVet, "003") => (RuleGroup::Unspecified, Rule::PandasUseOfDotIsNull), + (PandasVet, "004") => (RuleGroup::Unspecified, Rule::PandasUseOfDotNotNull), + (PandasVet, "007") => (RuleGroup::Unspecified, Rule::PandasUseOfDotIx), + (PandasVet, "008") => (RuleGroup::Unspecified, Rule::PandasUseOfDotAt), + (PandasVet, "009") => (RuleGroup::Unspecified, Rule::PandasUseOfDotIat), + (PandasVet, "010") => (RuleGroup::Unspecified, Rule::PandasUseOfDotPivotOrUnstack), + (PandasVet, "011") => (RuleGroup::Unspecified, Rule::PandasUseOfDotValues), + (PandasVet, "012") => (RuleGroup::Unspecified, Rule::PandasUseOfDotReadTable), + (PandasVet, "013") => (RuleGroup::Unspecified, Rule::PandasUseOfDotStack), + (PandasVet, "015") => (RuleGroup::Unspecified, Rule::PandasUseOfPdMerge), + (PandasVet, "901") => (RuleGroup::Unspecified, Rule::PandasDfVariableName), // flake8-errmsg - (Flake8ErrMsg, "101") => Rule::RawStringInException, - (Flake8ErrMsg, "102") => Rule::FStringInException, - (Flake8ErrMsg, "103") => Rule::DotFormatInException, + (Flake8ErrMsg, "101") => (RuleGroup::Unspecified, Rule::RawStringInException), + (Flake8ErrMsg, "102") => (RuleGroup::Unspecified, Rule::FStringInException), + (Flake8ErrMsg, "103") => (RuleGroup::Unspecified, Rule::DotFormatInException), // flake8-pyi - (Flake8Pyi, "001") => Rule::UnprefixedTypeParam, - (Flake8Pyi, "006") => Rule::BadVersionInfoComparison, - (Flake8Pyi, "007") => Rule::UnrecognizedPlatformCheck, - (Flake8Pyi, "008") => Rule::UnrecognizedPlatformName, - (Flake8Pyi, "009") => Rule::PassStatementStubBody, - (Flake8Pyi, "010") => Rule::NonEmptyStubBody, - (Flake8Pyi, "011") => Rule::TypedArgumentDefaultInStub, - (Flake8Pyi, "012") => Rule::PassInClassBody, - (Flake8Pyi, "014") => Rule::ArgumentDefaultInStub, - (Flake8Pyi, "015") => Rule::AssignmentDefaultInStub, - (Flake8Pyi, "016") => Rule::DuplicateUnionMember, - (Flake8Pyi, "020") => Rule::QuotedAnnotationInStub, - (Flake8Pyi, "021") => Rule::DocstringInStub, - (Flake8Pyi, "033") => Rule::TypeCommentInStub, - (Flake8Pyi, "042") => Rule::SnakeCaseTypeAlias, - (Flake8Pyi, "043") => Rule::TSuffixedTypeAlias, + (Flake8Pyi, "001") => (RuleGroup::Unspecified, Rule::UnprefixedTypeParam), + (Flake8Pyi, "006") => (RuleGroup::Unspecified, Rule::BadVersionInfoComparison), + (Flake8Pyi, "007") => (RuleGroup::Unspecified, Rule::UnrecognizedPlatformCheck), + (Flake8Pyi, "008") => (RuleGroup::Unspecified, Rule::UnrecognizedPlatformName), + (Flake8Pyi, "009") => (RuleGroup::Unspecified, Rule::PassStatementStubBody), + (Flake8Pyi, "010") => (RuleGroup::Unspecified, Rule::NonEmptyStubBody), + (Flake8Pyi, "011") => (RuleGroup::Unspecified, Rule::TypedArgumentDefaultInStub), + (Flake8Pyi, "012") => (RuleGroup::Unspecified, Rule::PassInClassBody), + (Flake8Pyi, "014") => (RuleGroup::Unspecified, Rule::ArgumentDefaultInStub), + (Flake8Pyi, "015") => (RuleGroup::Unspecified, Rule::AssignmentDefaultInStub), + (Flake8Pyi, "016") => (RuleGroup::Unspecified, Rule::DuplicateUnionMember), + (Flake8Pyi, "020") => (RuleGroup::Unspecified, Rule::QuotedAnnotationInStub), + (Flake8Pyi, "021") => (RuleGroup::Unspecified, Rule::DocstringInStub), + (Flake8Pyi, "033") => (RuleGroup::Unspecified, Rule::TypeCommentInStub), + (Flake8Pyi, "042") => (RuleGroup::Unspecified, Rule::SnakeCaseTypeAlias), + (Flake8Pyi, "043") => (RuleGroup::Unspecified, Rule::TSuffixedTypeAlias), // flake8-pytest-style - (Flake8PytestStyle, "001") => Rule::PytestFixtureIncorrectParenthesesStyle, - (Flake8PytestStyle, "002") => Rule::PytestFixturePositionalArgs, - (Flake8PytestStyle, "003") => Rule::PytestExtraneousScopeFunction, - (Flake8PytestStyle, "004") => Rule::PytestMissingFixtureNameUnderscore, - (Flake8PytestStyle, "005") => Rule::PytestIncorrectFixtureNameUnderscore, - (Flake8PytestStyle, "006") => Rule::PytestParametrizeNamesWrongType, - (Flake8PytestStyle, "007") => Rule::PytestParametrizeValuesWrongType, - (Flake8PytestStyle, "008") => Rule::PytestPatchWithLambda, - (Flake8PytestStyle, "009") => Rule::PytestUnittestAssertion, - (Flake8PytestStyle, "010") => Rule::PytestRaisesWithoutException, - (Flake8PytestStyle, "011") => Rule::PytestRaisesTooBroad, - (Flake8PytestStyle, "012") => Rule::PytestRaisesWithMultipleStatements, - (Flake8PytestStyle, "013") => Rule::PytestIncorrectPytestImport, - (Flake8PytestStyle, "015") => Rule::PytestAssertAlwaysFalse, - (Flake8PytestStyle, "016") => Rule::PytestFailWithoutMessage, - (Flake8PytestStyle, "017") => Rule::PytestAssertInExcept, - (Flake8PytestStyle, "018") => Rule::PytestCompositeAssertion, - (Flake8PytestStyle, "019") => Rule::PytestFixtureParamWithoutValue, - (Flake8PytestStyle, "020") => Rule::PytestDeprecatedYieldFixture, - (Flake8PytestStyle, "021") => Rule::PytestFixtureFinalizerCallback, - (Flake8PytestStyle, "022") => Rule::PytestUselessYieldFixture, - (Flake8PytestStyle, "023") => Rule::PytestIncorrectMarkParenthesesStyle, - (Flake8PytestStyle, "024") => Rule::PytestUnnecessaryAsyncioMarkOnFixture, - (Flake8PytestStyle, "025") => Rule::PytestErroneousUseFixturesOnFixture, - (Flake8PytestStyle, "026") => Rule::PytestUseFixturesWithoutParameters, + (Flake8PytestStyle, "001") => (RuleGroup::Unspecified, Rule::PytestFixtureIncorrectParenthesesStyle), + (Flake8PytestStyle, "002") => (RuleGroup::Unspecified, Rule::PytestFixturePositionalArgs), + (Flake8PytestStyle, "003") => (RuleGroup::Unspecified, Rule::PytestExtraneousScopeFunction), + (Flake8PytestStyle, "004") => (RuleGroup::Unspecified, Rule::PytestMissingFixtureNameUnderscore), + (Flake8PytestStyle, "005") => (RuleGroup::Unspecified, Rule::PytestIncorrectFixtureNameUnderscore), + (Flake8PytestStyle, "006") => (RuleGroup::Unspecified, Rule::PytestParametrizeNamesWrongType), + (Flake8PytestStyle, "007") => (RuleGroup::Unspecified, Rule::PytestParametrizeValuesWrongType), + (Flake8PytestStyle, "008") => (RuleGroup::Unspecified, Rule::PytestPatchWithLambda), + (Flake8PytestStyle, "009") => (RuleGroup::Unspecified, Rule::PytestUnittestAssertion), + (Flake8PytestStyle, "010") => (RuleGroup::Unspecified, Rule::PytestRaisesWithoutException), + (Flake8PytestStyle, "011") => (RuleGroup::Unspecified, Rule::PytestRaisesTooBroad), + (Flake8PytestStyle, "012") => (RuleGroup::Unspecified, Rule::PytestRaisesWithMultipleStatements), + (Flake8PytestStyle, "013") => (RuleGroup::Unspecified, Rule::PytestIncorrectPytestImport), + (Flake8PytestStyle, "015") => (RuleGroup::Unspecified, Rule::PytestAssertAlwaysFalse), + (Flake8PytestStyle, "016") => (RuleGroup::Unspecified, Rule::PytestFailWithoutMessage), + (Flake8PytestStyle, "017") => (RuleGroup::Unspecified, Rule::PytestAssertInExcept), + (Flake8PytestStyle, "018") => (RuleGroup::Unspecified, Rule::PytestCompositeAssertion), + (Flake8PytestStyle, "019") => (RuleGroup::Unspecified, Rule::PytestFixtureParamWithoutValue), + (Flake8PytestStyle, "020") => (RuleGroup::Unspecified, Rule::PytestDeprecatedYieldFixture), + (Flake8PytestStyle, "021") => (RuleGroup::Unspecified, Rule::PytestFixtureFinalizerCallback), + (Flake8PytestStyle, "022") => (RuleGroup::Unspecified, Rule::PytestUselessYieldFixture), + (Flake8PytestStyle, "023") => (RuleGroup::Unspecified, Rule::PytestIncorrectMarkParenthesesStyle), + (Flake8PytestStyle, "024") => (RuleGroup::Unspecified, Rule::PytestUnnecessaryAsyncioMarkOnFixture), + (Flake8PytestStyle, "025") => (RuleGroup::Unspecified, Rule::PytestErroneousUseFixturesOnFixture), + (Flake8PytestStyle, "026") => (RuleGroup::Unspecified, Rule::PytestUseFixturesWithoutParameters), // flake8-pie - (Flake8Pie, "790") => Rule::UnnecessaryPass, - (Flake8Pie, "794") => Rule::DuplicateClassFieldDefinition, - (Flake8Pie, "796") => Rule::NonUniqueEnums, - (Flake8Pie, "800") => Rule::UnnecessarySpread, - (Flake8Pie, "804") => Rule::UnnecessaryDictKwargs, - (Flake8Pie, "807") => Rule::ReimplementedListBuiltin, - (Flake8Pie, "810") => Rule::MultipleStartsEndsWith, + (Flake8Pie, "790") => (RuleGroup::Unspecified, Rule::UnnecessaryPass), + (Flake8Pie, "794") => (RuleGroup::Unspecified, Rule::DuplicateClassFieldDefinition), + (Flake8Pie, "796") => (RuleGroup::Unspecified, Rule::NonUniqueEnums), + (Flake8Pie, "800") => (RuleGroup::Unspecified, Rule::UnnecessarySpread), + (Flake8Pie, "804") => (RuleGroup::Unspecified, Rule::UnnecessaryDictKwargs), + (Flake8Pie, "807") => (RuleGroup::Unspecified, Rule::ReimplementedListBuiltin), + (Flake8Pie, "810") => (RuleGroup::Unspecified, Rule::MultipleStartsEndsWith), // flake8-commas - (Flake8Commas, "812") => Rule::MissingTrailingComma, - (Flake8Commas, "818") => Rule::TrailingCommaOnBareTuple, - (Flake8Commas, "819") => Rule::ProhibitedTrailingComma, + (Flake8Commas, "812") => (RuleGroup::Unspecified, Rule::MissingTrailingComma), + (Flake8Commas, "818") => (RuleGroup::Unspecified, Rule::TrailingCommaOnBareTuple), + (Flake8Commas, "819") => (RuleGroup::Unspecified, Rule::ProhibitedTrailingComma), // flake8-no-pep420 - (Flake8NoPep420, "001") => Rule::ImplicitNamespacePackage, + (Flake8NoPep420, "001") => (RuleGroup::Unspecified, Rule::ImplicitNamespacePackage), // flake8-executable - (Flake8Executable, "001") => Rule::ShebangNotExecutable, - (Flake8Executable, "002") => Rule::ShebangMissingExecutableFile, - (Flake8Executable, "003") => Rule::ShebangMissingPython, - (Flake8Executable, "004") => Rule::ShebangLeadingWhitespace, - (Flake8Executable, "005") => Rule::ShebangNotFirstLine, + (Flake8Executable, "001") => (RuleGroup::Unspecified, Rule::ShebangNotExecutable), + (Flake8Executable, "002") => (RuleGroup::Unspecified, Rule::ShebangMissingExecutableFile), + (Flake8Executable, "003") => (RuleGroup::Unspecified, Rule::ShebangMissingPython), + (Flake8Executable, "004") => (RuleGroup::Unspecified, Rule::ShebangLeadingWhitespace), + (Flake8Executable, "005") => (RuleGroup::Unspecified, Rule::ShebangNotFirstLine), // flake8-type-checking - (Flake8TypeChecking, "001") => Rule::TypingOnlyFirstPartyImport, - (Flake8TypeChecking, "002") => Rule::TypingOnlyThirdPartyImport, - (Flake8TypeChecking, "003") => Rule::TypingOnlyStandardLibraryImport, - (Flake8TypeChecking, "004") => Rule::RuntimeImportInTypeCheckingBlock, - (Flake8TypeChecking, "005") => Rule::EmptyTypeCheckingBlock, + (Flake8TypeChecking, "001") => (RuleGroup::Unspecified, Rule::TypingOnlyFirstPartyImport), + (Flake8TypeChecking, "002") => (RuleGroup::Unspecified, Rule::TypingOnlyThirdPartyImport), + (Flake8TypeChecking, "003") => (RuleGroup::Unspecified, Rule::TypingOnlyStandardLibraryImport), + (Flake8TypeChecking, "004") => (RuleGroup::Unspecified, Rule::RuntimeImportInTypeCheckingBlock), + (Flake8TypeChecking, "005") => (RuleGroup::Unspecified, Rule::EmptyTypeCheckingBlock), // tryceratops - (Tryceratops, "002") => Rule::RaiseVanillaClass, - (Tryceratops, "003") => Rule::RaiseVanillaArgs, - (Tryceratops, "004") => Rule::TypeCheckWithoutTypeError, - (Tryceratops, "200") => Rule::ReraiseNoCause, - (Tryceratops, "201") => Rule::VerboseRaise, - (Tryceratops, "300") => Rule::TryConsiderElse, - (Tryceratops, "301") => Rule::RaiseWithinTry, - (Tryceratops, "400") => Rule::ErrorInsteadOfException, - (Tryceratops, "401") => Rule::VerboseLogMessage, + (Tryceratops, "002") => (RuleGroup::Unspecified, Rule::RaiseVanillaClass), + (Tryceratops, "003") => (RuleGroup::Unspecified, Rule::RaiseVanillaArgs), + (Tryceratops, "004") => (RuleGroup::Unspecified, Rule::TypeCheckWithoutTypeError), + (Tryceratops, "200") => (RuleGroup::Unspecified, Rule::ReraiseNoCause), + (Tryceratops, "201") => (RuleGroup::Unspecified, Rule::VerboseRaise), + (Tryceratops, "300") => (RuleGroup::Unspecified, Rule::TryConsiderElse), + (Tryceratops, "301") => (RuleGroup::Unspecified, Rule::RaiseWithinTry), + (Tryceratops, "400") => (RuleGroup::Unspecified, Rule::ErrorInsteadOfException), + (Tryceratops, "401") => (RuleGroup::Unspecified, Rule::VerboseLogMessage), // flake8-use-pathlib - (Flake8UsePathlib, "100") => Rule::OsPathAbspath, - (Flake8UsePathlib, "101") => Rule::OsChmod, - (Flake8UsePathlib, "102") => Rule::OsMkdir, - (Flake8UsePathlib, "103") => Rule::OsMakedirs, - (Flake8UsePathlib, "104") => Rule::OsRename, - (Flake8UsePathlib, "105") => Rule::PathlibReplace, - (Flake8UsePathlib, "106") => Rule::OsRmdir, - (Flake8UsePathlib, "107") => Rule::OsRemove, - (Flake8UsePathlib, "108") => Rule::OsUnlink, - (Flake8UsePathlib, "109") => Rule::OsGetcwd, - (Flake8UsePathlib, "110") => Rule::OsPathExists, - (Flake8UsePathlib, "111") => Rule::OsPathExpanduser, - (Flake8UsePathlib, "112") => Rule::OsPathIsdir, - (Flake8UsePathlib, "113") => Rule::OsPathIsfile, - (Flake8UsePathlib, "114") => Rule::OsPathIslink, - (Flake8UsePathlib, "115") => Rule::OsReadlink, - (Flake8UsePathlib, "116") => Rule::OsStat, - (Flake8UsePathlib, "117") => Rule::OsPathIsabs, - (Flake8UsePathlib, "118") => Rule::OsPathJoin, - (Flake8UsePathlib, "119") => Rule::OsPathBasename, - (Flake8UsePathlib, "120") => Rule::OsPathDirname, - (Flake8UsePathlib, "121") => Rule::OsPathSamefile, - (Flake8UsePathlib, "122") => Rule::OsPathSplitext, - (Flake8UsePathlib, "123") => Rule::BuiltinOpen, - (Flake8UsePathlib, "124") => Rule::PyPath, + (Flake8UsePathlib, "100") => (RuleGroup::Unspecified, Rule::OsPathAbspath), + (Flake8UsePathlib, "101") => (RuleGroup::Unspecified, Rule::OsChmod), + (Flake8UsePathlib, "102") => (RuleGroup::Unspecified, Rule::OsMkdir), + (Flake8UsePathlib, "103") => (RuleGroup::Unspecified, Rule::OsMakedirs), + (Flake8UsePathlib, "104") => (RuleGroup::Unspecified, Rule::OsRename), + (Flake8UsePathlib, "105") => (RuleGroup::Unspecified, Rule::PathlibReplace), + (Flake8UsePathlib, "106") => (RuleGroup::Unspecified, Rule::OsRmdir), + (Flake8UsePathlib, "107") => (RuleGroup::Unspecified, Rule::OsRemove), + (Flake8UsePathlib, "108") => (RuleGroup::Unspecified, Rule::OsUnlink), + (Flake8UsePathlib, "109") => (RuleGroup::Unspecified, Rule::OsGetcwd), + (Flake8UsePathlib, "110") => (RuleGroup::Unspecified, Rule::OsPathExists), + (Flake8UsePathlib, "111") => (RuleGroup::Unspecified, Rule::OsPathExpanduser), + (Flake8UsePathlib, "112") => (RuleGroup::Unspecified, Rule::OsPathIsdir), + (Flake8UsePathlib, "113") => (RuleGroup::Unspecified, Rule::OsPathIsfile), + (Flake8UsePathlib, "114") => (RuleGroup::Unspecified, Rule::OsPathIslink), + (Flake8UsePathlib, "115") => (RuleGroup::Unspecified, Rule::OsReadlink), + (Flake8UsePathlib, "116") => (RuleGroup::Unspecified, Rule::OsStat), + (Flake8UsePathlib, "117") => (RuleGroup::Unspecified, Rule::OsPathIsabs), + (Flake8UsePathlib, "118") => (RuleGroup::Unspecified, Rule::OsPathJoin), + (Flake8UsePathlib, "119") => (RuleGroup::Unspecified, Rule::OsPathBasename), + (Flake8UsePathlib, "120") => (RuleGroup::Unspecified, Rule::OsPathDirname), + (Flake8UsePathlib, "121") => (RuleGroup::Unspecified, Rule::OsPathSamefile), + (Flake8UsePathlib, "122") => (RuleGroup::Unspecified, Rule::OsPathSplitext), + (Flake8UsePathlib, "123") => (RuleGroup::Unspecified, Rule::BuiltinOpen), + (Flake8UsePathlib, "124") => (RuleGroup::Unspecified, Rule::PyPath), // flake8-logging-format - (Flake8LoggingFormat, "001") => Rule::LoggingStringFormat, - (Flake8LoggingFormat, "002") => Rule::LoggingPercentFormat, - (Flake8LoggingFormat, "003") => Rule::LoggingStringConcat, - (Flake8LoggingFormat, "004") => Rule::LoggingFString, - (Flake8LoggingFormat, "010") => Rule::LoggingWarn, - (Flake8LoggingFormat, "101") => Rule::LoggingExtraAttrClash, - (Flake8LoggingFormat, "201") => Rule::LoggingExcInfo, - (Flake8LoggingFormat, "202") => Rule::LoggingRedundantExcInfo, + (Flake8LoggingFormat, "001") => (RuleGroup::Unspecified, Rule::LoggingStringFormat), + (Flake8LoggingFormat, "002") => (RuleGroup::Unspecified, Rule::LoggingPercentFormat), + (Flake8LoggingFormat, "003") => (RuleGroup::Unspecified, Rule::LoggingStringConcat), + (Flake8LoggingFormat, "004") => (RuleGroup::Unspecified, Rule::LoggingFString), + (Flake8LoggingFormat, "010") => (RuleGroup::Unspecified, Rule::LoggingWarn), + (Flake8LoggingFormat, "101") => (RuleGroup::Unspecified, Rule::LoggingExtraAttrClash), + (Flake8LoggingFormat, "201") => (RuleGroup::Unspecified, Rule::LoggingExcInfo), + (Flake8LoggingFormat, "202") => (RuleGroup::Unspecified, Rule::LoggingRedundantExcInfo), // flake8-raise - (Flake8Raise, "102") => Rule::UnnecessaryParenOnRaiseException, + (Flake8Raise, "102") => (RuleGroup::Unspecified, Rule::UnnecessaryParenOnRaiseException), // flake8-self - (Flake8Self, "001") => Rule::PrivateMemberAccess, + (Flake8Self, "001") => (RuleGroup::Unspecified, Rule::PrivateMemberAccess), // numpy - (Numpy, "001") => Rule::NumpyDeprecatedTypeAlias, - (Numpy, "002") => Rule::NumpyLegacyRandom, + (Numpy, "001") => (RuleGroup::Unspecified, Rule::NumpyDeprecatedTypeAlias), + (Numpy, "002") => (RuleGroup::Unspecified, Rule::NumpyLegacyRandom), // ruff - (Ruff, "001") => Rule::AmbiguousUnicodeCharacterString, - (Ruff, "002") => Rule::AmbiguousUnicodeCharacterDocstring, - (Ruff, "003") => Rule::AmbiguousUnicodeCharacterComment, - (Ruff, "005") => Rule::CollectionLiteralConcatenation, - (Ruff, "006") => Rule::AsyncioDanglingTask, - (Ruff, "007") => Rule::PairwiseOverZipped, - (Ruff, "008") => Rule::MutableDataclassDefault, - (Ruff, "009") => Rule::FunctionCallInDataclassDefaultArgument, - (Ruff, "010") => Rule::ExplicitFStringTypeConversion, - (Ruff, "100") => Rule::UnusedNOQA, + (Ruff, "001") => (RuleGroup::Unspecified, Rule::AmbiguousUnicodeCharacterString), + (Ruff, "002") => (RuleGroup::Unspecified, Rule::AmbiguousUnicodeCharacterDocstring), + (Ruff, "003") => (RuleGroup::Unspecified, Rule::AmbiguousUnicodeCharacterComment), + (Ruff, "005") => (RuleGroup::Unspecified, Rule::CollectionLiteralConcatenation), + (Ruff, "006") => (RuleGroup::Unspecified, Rule::AsyncioDanglingTask), + (Ruff, "007") => (RuleGroup::Unspecified, Rule::PairwiseOverZipped), + (Ruff, "008") => (RuleGroup::Unspecified, Rule::MutableDataclassDefault), + (Ruff, "009") => (RuleGroup::Unspecified, Rule::FunctionCallInDataclassDefaultArgument), + (Ruff, "010") => (RuleGroup::Unspecified, Rule::ExplicitFStringTypeConversion), + (Ruff, "100") => (RuleGroup::Unspecified, Rule::UnusedNOQA), // flake8-django - (Flake8Django, "001") => Rule::DjangoNullableModelStringField, - (Flake8Django, "003") => Rule::DjangoLocalsInRenderFunction, - (Flake8Django, "006") => Rule::DjangoExcludeWithModelForm, - (Flake8Django, "007") => Rule::DjangoAllWithModelForm, - (Flake8Django, "008") => Rule::DjangoModelWithoutDunderStr, - (Flake8Django, "012") => Rule::DjangoUnorderedBodyContentInModel, - (Flake8Django, "013") => Rule::DjangoNonLeadingReceiverDecorator, + (Flake8Django, "001") => (RuleGroup::Unspecified, Rule::DjangoNullableModelStringField), + (Flake8Django, "003") => (RuleGroup::Unspecified, Rule::DjangoLocalsInRenderFunction), + (Flake8Django, "006") => (RuleGroup::Unspecified, Rule::DjangoExcludeWithModelForm), + (Flake8Django, "007") => (RuleGroup::Unspecified, Rule::DjangoAllWithModelForm), + (Flake8Django, "008") => (RuleGroup::Unspecified, Rule::DjangoModelWithoutDunderStr), + (Flake8Django, "012") => (RuleGroup::Unspecified, Rule::DjangoUnorderedBodyContentInModel), + (Flake8Django, "013") => (RuleGroup::Unspecified, Rule::DjangoNonLeadingReceiverDecorator), // flynt - // Reserved: (Flynt, "001") => Rule::StringConcatenationToFString, - (Flynt, "002") => Rule::StaticJoinToFString, - - // flake8-todo - (Flake8Todo, "001") => Rule::InvalidTodoTag, - (Flake8Todo, "002") => Rule::MissingTodoAuthor, - (Flake8Todo, "003") => Rule::MissingTodoLink, - (Flake8Todo, "004") => Rule::MissingTodoColon, - (Flake8Todo, "005") => Rule::MissingTodoDescription, - (Flake8Todo, "006") => Rule::InvalidTodoCapitalization, - (Flake8Todo, "007") => Rule::MissingSpaceAfterTodoColon, + // Reserved: (Flynt, "001") => (RuleGroup::Unspecified, Rule::StringConcatenationToFString), + (Flynt, "002") => (RuleGroup::Unspecified, Rule::StaticJoinToFString), + + // flake8-todos + (Flake8Todo, "001") => (RuleGroup::Unspecified, Rule::InvalidTodoTag), + (Flake8Todo, "002") => (RuleGroup::Unspecified, Rule::MissingTodoAuthor), + (Flake8Todo, "003") => (RuleGroup::Unspecified, Rule::MissingTodoLink), + (Flake8Todo, "004") => (RuleGroup::Unspecified, Rule::MissingTodoColon), + (Flake8Todo, "005") => (RuleGroup::Unspecified, Rule::MissingTodoDescription), + (Flake8Todo, "006") => (RuleGroup::Unspecified, Rule::InvalidTodoCapitalization), + (Flake8Todo, "007") => (RuleGroup::Unspecified, Rule::MissingSpaceAfterTodoColon), + _ => return None, }) } diff --git a/crates/ruff/src/rule_selector.rs b/crates/ruff/src/rule_selector.rs index f6ea3de4e14e9..b9a135f7d7cc5 100644 --- a/crates/ruff/src/rule_selector.rs +++ b/crates/ruff/src/rule_selector.rs @@ -119,8 +119,7 @@ impl Visitor<'_> for SelectorVisitor { fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str( - "expected a string code identifying a linter or specific rule, or a partial rule code \ - or ALL to refer to all rules", + "expected a string code identifying a linter or specific rule, or a partial rule code or ALL to refer to all rules", ) } @@ -141,13 +140,22 @@ impl From for RuleSelector { } } +/// Returns `true` if the given rule should be selected by the `RuleSelector::All` selector. +fn select_all(rule: Rule) -> bool { + // Nursery rules have to be explicitly selected, so we ignore them when looking at + // prefixes. + !rule.is_nursery() +} + impl IntoIterator for &RuleSelector { - type IntoIter = RuleSelectorIter; type Item = Rule; + type IntoIter = RuleSelectorIter; fn into_iter(self) -> Self::IntoIter { match self { - RuleSelector::All => RuleSelectorIter::All(Rule::iter()), + RuleSelector::All => { + RuleSelectorIter::All(Rule::iter().filter(|rule| select_all(*rule))) + } RuleSelector::C => RuleSelectorIter::Chain( Linter::Flake8Comprehensions .into_iter() @@ -165,7 +173,7 @@ impl IntoIterator for &RuleSelector { } pub enum RuleSelectorIter { - All(RuleIter), + All(std::iter::Filter bool>), Chain(std::iter::Chain, std::vec::IntoIter>), Vec(std::vec::IntoIter), } diff --git a/crates/ruff_cli/src/commands/rule.rs b/crates/ruff_cli/src/commands/rule.rs index b0fc26978b66f..ddb8e4ff21485 100644 --- a/crates/ruff_cli/src/commands/rule.rs +++ b/crates/ruff_cli/src/commands/rule.rs @@ -43,6 +43,17 @@ pub(crate) fn rule(rule: Rule, format: HelpFormat) -> Result<()> { output.push('\n'); } + if rule.is_nursery() { + output.push_str(&format!( + r#"This rule is part of the **nursery**, a collection of newer lints that are +still under development. As such, it must be enabled by explicitly selecting +{}."#, + rule.noqa_code() + )); + output.push('\n'); + output.push('\n'); + } + if let Some(explanation) = rule.explanation() { output.push_str(explanation.trim()); } else { diff --git a/crates/ruff_cli/tests/integration_test.rs b/crates/ruff_cli/tests/integration_test.rs index 18ec7feb8adf5..8b48769c89c08 100644 --- a/crates/ruff_cli/tests/integration_test.rs +++ b/crates/ruff_cli/tests/integration_test.rs @@ -12,7 +12,7 @@ use path_absolutize::path_dedot; const BIN_NAME: &str = "ruff"; #[test] -fn test_stdin_success() -> Result<()> { +fn stdin_success() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; cmd.args(["-", "--format", "text", "--isolated"]) .write_stdin("") @@ -22,7 +22,7 @@ fn test_stdin_success() -> Result<()> { } #[test] -fn test_stdin_error() -> Result<()> { +fn stdin_error() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args(["-", "--format", "text", "--isolated"]) @@ -40,7 +40,7 @@ Found 1 error. } #[test] -fn test_stdin_filename() -> Result<()> { +fn stdin_filename() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args([ @@ -66,7 +66,7 @@ Found 1 error. #[cfg(unix)] #[test] -fn test_stdin_json() -> Result<()> { +fn stdin_json() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args([ @@ -127,7 +127,7 @@ fn test_stdin_json() -> Result<()> { } #[test] -fn test_stdin_autofix() -> Result<()> { +fn stdin_autofix() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args(["-", "--format", "text", "--fix", "--isolated"]) @@ -142,7 +142,7 @@ fn test_stdin_autofix() -> Result<()> { } #[test] -fn test_stdin_autofix_when_not_fixable_should_still_print_contents() -> Result<()> { +fn stdin_autofix_when_not_fixable_should_still_print_contents() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args(["-", "--format", "text", "--fix", "--isolated"]) @@ -157,7 +157,7 @@ fn test_stdin_autofix_when_not_fixable_should_still_print_contents() -> Result<( } #[test] -fn test_stdin_autofix_when_no_issues_should_still_print_contents() -> Result<()> { +fn stdin_autofix_when_no_issues_should_still_print_contents() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args(["-", "--format", "text", "--fix", "--isolated"]) @@ -172,7 +172,7 @@ fn test_stdin_autofix_when_no_issues_should_still_print_contents() -> Result<()> } #[test] -fn test_show_source() -> Result<()> { +fn show_source() -> Result<()> { let mut cmd = Command::cargo_bin(BIN_NAME)?; let output = cmd .args(["-", "--format", "text", "--show-source", "--isolated"]) @@ -217,3 +217,63 @@ fn show_statistics() -> Result<()> { ); Ok(()) } + +#[test] +fn nursery_prefix() -> Result<()> { + let mut cmd = Command::cargo_bin(BIN_NAME)?; + + // `--select E` should detect E741, but not E225, which is in the nursery. + let output = cmd + .args(["-", "--format", "text", "--isolated", "--select", "E"]) + .write_stdin("I=42\n") + .assert() + .failure(); + assert_eq!( + str::from_utf8(&output.get_output().stdout)?, + r#"-:1:1: E741 Ambiguous variable name: `I` +Found 1 error. +"# + ); + + Ok(()) +} + +#[test] +fn nursery_all() -> Result<()> { + let mut cmd = Command::cargo_bin(BIN_NAME)?; + + // `--select ALL` should detect E741, but not E225, which is in the nursery. + let output = cmd + .args(["-", "--format", "text", "--isolated", "--select", "E"]) + .write_stdin("I=42\n") + .assert() + .failure(); + assert_eq!( + str::from_utf8(&output.get_output().stdout)?, + r#"-:1:1: E741 Ambiguous variable name: `I` +Found 1 error. +"# + ); + + Ok(()) +} + +#[test] +fn nursery_direct() -> Result<()> { + let mut cmd = Command::cargo_bin(BIN_NAME)?; + + // `--select E225` should detect E225. + let output = cmd + .args(["-", "--format", "text", "--isolated", "--select", "E225"]) + .write_stdin("I=42\n") + .assert() + .failure(); + assert_eq!( + str::from_utf8(&output.get_output().stdout)?, + r#"-:1:2: E225 Missing whitespace around operator +Found 1 error. +"# + ); + + Ok(()) +} diff --git a/crates/ruff_dev/src/generate_docs.rs b/crates/ruff_dev/src/generate_docs.rs index f191c081f5d4f..d6369051748d6 100644 --- a/crates/ruff_dev/src/generate_docs.rs +++ b/crates/ruff_dev/src/generate_docs.rs @@ -43,6 +43,17 @@ pub(crate) fn main(args: &Args) -> Result<()> { output.push('\n'); } + if rule.is_nursery() { + output.push_str(&format!( + r#"This rule is part of the **nursery**, a collection of newer lints that are +still under development. As such, it must be enabled by explicitly selecting +{}."#, + rule.noqa_code() + )); + output.push('\n'); + output.push('\n'); + } + process_documentation(explanation.trim(), &mut output); let filename = PathBuf::from(ROOT_DIR) @@ -116,7 +127,7 @@ mod tests { #[test] fn test_process_documentation() { - let mut out = String::new(); + let mut output = String::new(); process_documentation( " See also [`mccabe.max-complexity`]. @@ -127,10 +138,10 @@ Something [`else`][other]. - `mccabe.max-complexity` [other]: http://example.com.", - &mut out, + &mut output, ); assert_eq!( - out, + output, " See also [`mccabe.max-complexity`][mccabe.max-complexity]. Something [`else`][other]. diff --git a/crates/ruff_diagnostics/src/violation.rs b/crates/ruff_diagnostics/src/violation.rs index 4c8d19c0a0ac3..d57a1b4e38b1b 100644 --- a/crates/ruff_diagnostics/src/violation.rs +++ b/crates/ruff_diagnostics/src/violation.rs @@ -1,6 +1,6 @@ use std::fmt::{Debug, Display}; -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub enum AutofixKind { Sometimes, Always, @@ -30,7 +30,7 @@ pub trait Violation: Debug + PartialEq + Eq { None } - // TODO micha: Move `autofix_title` to `Fix`, add new `advice` method that is shown as an advice. + // TODO(micha): Move `autofix_title` to `Fix`, add new `advice` method that is shown as an advice. // Change the `Diagnostic` renderer to show the advice, and render the fix message after the `Suggested fix: ` /// Returns the title for the autofix. The message is also shown as an advice as part of the diagnostics. diff --git a/crates/ruff_macros/src/lib.rs b/crates/ruff_macros/src/lib.rs index 3c108bf2bc392..74a84287811d3 100644 --- a/crates/ruff_macros/src/lib.rs +++ b/crates/ruff_macros/src/lib.rs @@ -15,7 +15,7 @@ mod rule_namespace; mod violation; #[proc_macro_derive(ConfigurationOptions, attributes(option, doc, option_group))] -pub fn derive_config(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn derive_config(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); config::derive_impl(input) @@ -43,13 +43,12 @@ pub fn cache_key(input: TokenStream) -> TokenStream { } #[proc_macro] -pub fn register_rules(item: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn register_rules(item: TokenStream) -> TokenStream { let mapping = parse_macro_input!(item as register_rules::Input); register_rules::register_rules(&mapping).into() } -/// Adds an `explanation()` method from the doc comment and -/// `#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]` +/// Adds an `explanation()` method from the doc comment. #[proc_macro_attribute] pub fn violation(_attr: TokenStream, item: TokenStream) -> TokenStream { let violation = parse_macro_input!(item as ItemStruct); @@ -59,7 +58,7 @@ pub fn violation(_attr: TokenStream, item: TokenStream) -> TokenStream { } #[proc_macro_derive(RuleNamespace, attributes(prefix))] -pub fn derive_rule_namespace(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn derive_rule_namespace(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); rule_namespace::derive_impl(input) diff --git a/crates/ruff_macros/src/map_codes.rs b/crates/ruff_macros/src/map_codes.rs index 3a9743e55039c..6891b2b2b6d41 100644 --- a/crates/ruff_macros/src/map_codes.rs +++ b/crates/ruff_macros/src/map_codes.rs @@ -8,21 +8,25 @@ use syn::{ Ident, ItemFn, LitStr, Pat, Path, Stmt, Token, }; -use crate::rule_code_prefix::{get_prefix_ident, if_all_same}; +use crate::rule_code_prefix::{get_prefix_ident, if_all_same, is_nursery}; pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { let Some(last_stmt) = func.block.stmts.last() else { return Err(Error::new(func.block.span(), "expected body to end in an expression")); }; let Stmt::Expr(Expr::Call(ExprCall{args: some_args, ..}), _) = last_stmt else { - return Err(Error::new(last_stmt.span(), "expected last expression to be Some(match (..) { .. })")) + return Err(Error::new(last_stmt.span(), "expected last expression to be `Some(match (..) { .. })`")) }; let mut some_args = some_args.into_iter(); let (Some(Expr::Match(ExprMatch { arms, .. })), None) = (some_args.next(), some_args.next()) else { - return Err(Error::new(last_stmt.span(), "expected last expression to be Some(match (..) { .. })")) + return Err(Error::new(last_stmt.span(), "expected last expression to be `Some(match (..) { .. })`")) }; - let mut linters: BTreeMap)>> = BTreeMap::new(); + // Map from: linter (e.g., `Flake8Bugbear`) to rule code (e.g.,`"002"`) to rule data (e.g., + // `(Rule::UnaryPrefixIncrement, RuleGroup::Unspecified, vec![])`). + #[allow(clippy::type_complexity)] + let mut linter_to_rules: BTreeMap)>> = + BTreeMap::new(); for arm in arms { if matches!(arm.pat, Pat::Wild(..)) { @@ -30,15 +34,15 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { } let entry = syn::parse::(arm.into_token_stream().into())?; - linters + linter_to_rules .entry(entry.linter) .or_default() - .insert(entry.code.value(), (entry.rule, entry.attrs)); + .insert(entry.code.value(), (entry.rule, entry.group, entry.attrs)); } - let linter_idents: Vec<_> = linters.keys().collect(); + let linter_idents: Vec<_> = linter_to_rules.keys().collect(); - let mut out = quote! { + let mut output = quote! { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum RuleCodePrefix { #(#linter_idents(#linter_idents),)* @@ -47,7 +51,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { impl RuleCodePrefix { pub fn linter(&self) -> &'static Linter { match self { - #(Self::#linter_idents(..) => &crate::registry::Linter::#linter_idents,)* + #(Self::#linter_idents(..) => &Linter::#linter_idents,)* } } @@ -59,13 +63,15 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { } }; - for (linter, map) in &linters { - out.extend(super::rule_code_prefix::expand( + for (linter, rules) in &linter_to_rules { + output.extend(super::rule_code_prefix::expand( linter, - map.iter().map(|(k, v)| (k.as_str(), &v.1)), + rules + .iter() + .map(|(code, (.., group, attrs))| (code.as_str(), group, attrs)), )); - out.extend(quote! { + output.extend(quote! { impl From<#linter> for RuleCodePrefix { fn from(linter: #linter) -> Self { Self::#linter(linter) @@ -81,32 +87,44 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { let mut all_codes = Vec::new(); - for (linter, map) in &linters { - let mut full_map: HashMap<_, _> = map - .iter() - .map(|(code, rule)| (code.clone(), vec![rule.clone()])) - .collect(); - for code in map.keys() { + for (linter, rules) in &linter_to_rules { + // Group the rules by their common prefixes. + // TODO(charlie): Why do we do this here _and_ in `rule_code_prefix::expand`? + let mut rules_by_prefix = BTreeMap::new(); + + for (code, (rule, group, attrs)) in rules { + // Nursery rules have to be explicitly selected, so we ignore them when looking at + // prefixes. + if is_nursery(group) { + rules_by_prefix.insert(code.clone(), vec![(rule.clone(), attrs.clone())]); + continue; + } + for i in 1..=code.len() { let prefix = code[..i].to_string(); - let rules: Vec<_> = map + let rules: Vec<_> = rules .iter() - .filter_map(|(code, rules)| { + .filter_map(|(code, (rule, group, attrs))| { + // Nursery rules have to be explicitly selected, so we ignore them when + // looking at prefixes. + if is_nursery(group) { + return None; + } + if code.starts_with(&prefix) { - Some(rules) + Some((rule.clone(), attrs.clone())) } else { None } }) - .cloned() .collect(); - full_map.insert(prefix, rules); + rules_by_prefix.insert(prefix, rules); } } - for (code, names) in &full_map { - let prefix_ident = get_prefix_ident(code); - let attr = match if_all_same(names.iter().map(|(_, attrs)| attrs)) { + for (prefix, rules) in &rules_by_prefix { + let prefix_ident = get_prefix_ident(prefix); + let attr = match if_all_same(rules.iter().map(|(.., attrs)| attrs)) { Some(attr) => quote!(#(#attr)*), None => quote!(), }; @@ -117,10 +135,12 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { let mut prefix_into_iter_match_arms = quote!(); - for (code, rules) in full_map { - let rule_paths = rules.iter().map(|(path, attrs)| quote!(#(#attrs)* #path)); - let prefix_ident = get_prefix_ident(&code); - let attr = match if_all_same(rules.iter().map(|(_, attrs)| attrs)) { + for (prefix, rules) in rules_by_prefix { + let rule_paths = rules + .iter() + .map(|(path, .., attrs)| quote!(#(#attrs)* #path)); + let prefix_ident = get_prefix_ident(&prefix); + let attr = match if_all_same(rules.iter().map(|(.., attrs)| attrs)) { Some(attr) => quote!(#(#attr)*), None => quote!(), }; @@ -129,7 +149,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { }); } - out.extend(quote! { + output.extend(quote! { impl IntoIterator for &#linter { type Item = Rule; type IntoIter = ::std::vec::IntoIter; @@ -141,7 +161,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { }); } - out.extend(quote! { + output.extend(quote! { impl IntoIterator for &RuleCodePrefix { type Item = Rule; type IntoIter = ::std::vec::IntoIter; @@ -154,7 +174,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { } }); - out.extend(quote! { + output.extend(quote! { impl RuleCodePrefix { pub fn parse(linter: &Linter, code: &str) -> Result { use std::str::FromStr; @@ -166,16 +186,22 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { } }); + // Map from rule to codes that can be used to select it. + // This abstraction exists to support a one-to-many mapping, whereby a single rule could map + // to multiple codes (e.g., if it existed in multiple linters, like Pylint and Flake8, under + // different codes). We haven't actually activated this functionality yet, but some work was + // done to support it, so the logic exists here. #[allow(clippy::type_complexity)] - let mut rule_to_codes: HashMap<&Path, Vec<(&Ident, &str, &Vec)>> = HashMap::new(); + let mut rule_to_codes: HashMap<&Path, Vec<(&Ident, &str, &Path, &Vec)>> = + HashMap::new(); let mut linter_code_for_rule_match_arms = quote!(); - for (linter, map) in &linters { - for (code, (rule, attrs)) in map { + for (linter, map) in &linter_to_rules { + for (code, (rule, group, attrs)) in map { rule_to_codes .entry(rule) .or_default() - .push((linter, code, attrs)); + .push((linter, code, group, attrs)); linter_code_for_rule_match_arms.extend(quote! { #(#attrs)* (Self::#linter, #rule) => Some(#code), }); @@ -183,50 +209,66 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { } let mut rule_noqa_code_match_arms = quote!(); + let mut rule_group_match_arms = quote!(); for (rule, codes) in rule_to_codes { - assert!( - codes.len() == 1, + assert_eq!( + codes.len(), + 1, " - The mapping of multiple codes to one rule has been disabled due to UX concerns (it would - be confusing if violations were reported under a different code than the code you selected). +{} is mapped to multiple codes. - We firstly want to allow rules to be selected by their names (and report them by name), - and before we can do that we have to rename all our rules to match our naming convention - (see CONTRIBUTING.md) because after that change every rule rename will be a breaking change. +The mapping of multiple codes to one rule has been disabled due to UX concerns (it would +be confusing if violations were reported under a different code than the code you selected). - See also https://github.com/charliermarsh/ruff/issues/2186. +We firstly want to allow rules to be selected by their names (and report them by name), +and before we can do that we have to rename all our rules to match our naming convention +(see CONTRIBUTING.md) because after that change every rule rename will be a breaking change. - (this was triggered by {} being mapped to multiple codes) - ", +See also https://github.com/charliermarsh/ruff/issues/2186. +", rule.segments.last().unwrap().ident ); - let (linter, code, attrs) = codes + let (linter, code, group, attrs) = codes .iter() - .sorted_by_key(|(l, ..)| *l == "Pylint") // TODO: more sophisticated sorting + .sorted_by_key(|(l, ..)| *l == "Pylint") .next() .unwrap(); rule_noqa_code_match_arms.extend(quote! { #(#attrs)* #rule => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code), }); + + rule_group_match_arms.extend(quote! { + #(#attrs)* #rule => #group, + }); } - out.extend(quote! { - impl crate::registry::Rule { + output.extend(quote! { + impl Rule { pub fn noqa_code(&self) -> NoqaCode { use crate::registry::RuleNamespace; match self { #rule_noqa_code_match_arms - // TODO: support rules without codes - // rule => rule.as_ref() } } + + pub fn group(&self) -> RuleGroup { + use crate::registry::RuleNamespace; + + match self { + #rule_group_match_arms + } + } + + pub fn is_nursery(&self) -> bool { + matches!(self.group(), RuleGroup::Nursery) + } } - impl crate::registry::Linter { + impl Linter { pub fn code_for_rule(&self, rule: Rule) -> Option<&'static str> { match (self, rule) { #linter_code_for_rule_match_arms @@ -237,16 +279,17 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { }); let mut linter_into_iter_match_arms = quote!(); - for (linter, map) in &linters { - let rule_paths = map.values().map(|(path, attrs)| quote!(#(#attrs)* #path)); + for (linter, map) in &linter_to_rules { + let rule_paths = map + .values() + .map(|(path, .., attrs)| quote!(#(#attrs)* #path)); linter_into_iter_match_arms.extend(quote! { - crate::registry::Linter::#linter => vec![#(#rule_paths,)*].into_iter(), + Linter::#linter => vec![#(#rule_paths,)*].into_iter(), }); } - out.extend(quote! { - - impl IntoIterator for &crate::registry::Linter { + output.extend(quote! { + impl IntoIterator for &Linter { type Item = Rule; type IntoIter = ::std::vec::IntoIter; @@ -259,7 +302,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { }); - out.extend(quote! { + output.extend(quote! { impl RuleCodePrefix { pub fn iter() -> ::std::vec::IntoIter { vec![ #(#all_codes,)* ].into_iter() @@ -267,18 +310,19 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { } }); - Ok(out) + Ok(output) } struct Entry { linter: Ident, code: LitStr, + group: Path, rule: Path, attrs: Vec, } impl Parse for Entry { - /// Parses a match arm such as `(Pycodestyle, "E101") => Rule::MixedSpacesAndTabs,` + /// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Nursery, Rule::NoIndentedBlock),` fn parse(input: syn::parse::ParseStream) -> syn::Result { let attrs = Attribute::parse_outer(input)?; let pat_tuple; @@ -287,11 +331,16 @@ impl Parse for Entry { let _: Token!(,) = pat_tuple.parse()?; let code: LitStr = pat_tuple.parse()?; let _: Token!(=>) = input.parse()?; - let rule: Path = input.parse()?; + let pat_tuple; + parenthesized!(pat_tuple in input); + let group: Path = pat_tuple.parse()?; + let _: Token!(,) = pat_tuple.parse()?; + let rule: Path = pat_tuple.parse()?; let _: Token!(,) = input.parse()?; Ok(Entry { linter, code, + group, rule, attrs, }) diff --git a/crates/ruff_macros/src/rule_code_prefix.rs b/crates/ruff_macros/src/rule_code_prefix.rs index 5ec760fae9be7..29379b2cb3610 100644 --- a/crates/ruff_macros/src/rule_code_prefix.rs +++ b/crates/ruff_macros/src/rule_code_prefix.rs @@ -2,35 +2,34 @@ use std::collections::{BTreeMap, BTreeSet}; use proc_macro2::Span; use quote::quote; -use syn::{Attribute, Ident}; - -pub(crate) fn get_prefix_ident(prefix: &str) -> Ident { - let prefix = if prefix.as_bytes()[0].is_ascii_digit() { - // Identifiers in Rust may not start with a number. - format!("_{prefix}") - } else { - prefix.to_string() - }; - Ident::new(&prefix, Span::call_site()) -} +use syn::{Attribute, Ident, Path}; pub(crate) fn expand<'a>( prefix_ident: &Ident, - variants: impl Iterator)>, + variants: impl Iterator)>, ) -> proc_macro2::TokenStream { // Build up a map from prefix to matching RuleCodes. let mut prefix_to_codes: BTreeMap> = BTreeMap::default(); let mut code_to_attributes: BTreeMap = BTreeMap::default(); - for (variant, attr) in variants { + for (variant, group, attr) in variants { let code_str = variant.to_string(); - for i in 1..=code_str.len() { - let prefix = code_str[..i].to_string(); + // Nursery rules have to be explicitly selected, so we ignore them when looking at prefixes. + if is_nursery(group) { prefix_to_codes - .entry(prefix) + .entry(code_str.clone()) .or_default() .insert(code_str.clone()); + } else { + for i in 1..=code_str.len() { + let prefix = code_str[..i].to_string(); + prefix_to_codes + .entry(prefix) + .or_default() + .insert(code_str.clone()); + } } + code_to_attributes.insert(code_str, attr); } @@ -115,3 +114,25 @@ pub(crate) fn if_all_same(iter: impl Iterator) -> Option None } } + +/// Returns an identifier for the given prefix. +pub(crate) fn get_prefix_ident(prefix: &str) -> Ident { + let prefix = if prefix.as_bytes()[0].is_ascii_digit() { + // Identifiers in Rust may not start with a number. + format!("_{prefix}") + } else { + prefix.to_string() + }; + Ident::new(&prefix, Span::call_site()) +} + +/// Returns true if the given group is the "nursery" group. +pub(crate) fn is_nursery(group: &Path) -> bool { + let group = group + .segments + .iter() + .map(|segment| segment.ident.to_string()) + .collect::>() + .join("::"); + group == "RuleGroup::Nursery" +} diff --git a/ruff.schema.json b/ruff.schema.json index 8588e62880d91..41b84d42bdc0b 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -1688,6 +1688,37 @@ "E1", "E10", "E101", + "E111", + "E112", + "E113", + "E114", + "E115", + "E116", + "E117", + "E201", + "E202", + "E203", + "E211", + "E221", + "E222", + "E223", + "E224", + "E225", + "E226", + "E227", + "E228", + "E231", + "E251", + "E252", + "E261", + "E262", + "E265", + "E266", + "E271", + "E272", + "E273", + "E274", + "E275", "E4", "E40", "E401",