mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:49:50 +00:00
Merge registry into codes (#4651)
* Document codes.rs * Refactor codes.rs before merging Helper script: ```python # %% from pathlib import Path codes = Path("crates/ruff/src/codes.rs").read_text().splitlines() rules = Path("a.txt").read_text().strip().splitlines() rule_map = {i.split("::")[-1]: i for i in rules} # %% codes_new = [] for line in codes: if ", Rule::" in line: left, right = line.split(", Rule::") right = right[:-2] line = left + ", " + rule_map[right] + ")," codes_new.append(line) # %% Path("crates/ruff/src/codes.rs").write_text("\n".join(codes_new)) ``` Co-authored-by: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com>
This commit is contained in:
parent
c4fdbf8903
commit
602b4b3519
9 changed files with 847 additions and 1610 deletions
|
@ -111,7 +111,7 @@ At a high level, the steps involved in adding a new lint rule are as follows:
|
|||
|
||||
1. In that file, define a violation struct. You can grep for `#[violation]` to see examples.
|
||||
|
||||
1. Map the violation struct to a rule code in `crates/ruff/src/registry.rs` (e.g., `E402`).
|
||||
1. Map the violation struct to a rule code in `crates/ruff/src/codes.rs` (e.g., `E402`).
|
||||
|
||||
1. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast/mod.rs` (for
|
||||
AST-based checks), `crates/ruff/src/checkers/tokens.rs` (for token-based checks),
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,690 +1,16 @@
|
|||
//! Registry of all [`Rule`] implementations.
|
||||
//! Remnant of the registry of all [`Rule`] implementations, now it's reexporting from codes.rs
|
||||
//! with some helper symbols
|
||||
|
||||
use strum_macros::{AsRefStr, EnumIter};
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
use ruff_diagnostics::Violation;
|
||||
pub use codes::Rule;
|
||||
use ruff_macros::RuleNamespace;
|
||||
pub use rule_set::{RuleSet, RuleSetIterator};
|
||||
|
||||
use crate::codes::{self, RuleCodePrefix};
|
||||
use crate::rules;
|
||||
|
||||
mod rule_set;
|
||||
|
||||
ruff_macros::register_rules!(
|
||||
// pycodestyle errors
|
||||
rules::pycodestyle::rules::MixedSpacesAndTabs,
|
||||
rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultiple,
|
||||
rules::pycodestyle::rules::logical_lines::NoIndentedBlock,
|
||||
rules::pycodestyle::rules::logical_lines::UnexpectedIndentation,
|
||||
rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultipleComment,
|
||||
rules::pycodestyle::rules::logical_lines::NoIndentedBlockComment,
|
||||
rules::pycodestyle::rules::logical_lines::UnexpectedIndentationComment,
|
||||
rules::pycodestyle::rules::logical_lines::OverIndented,
|
||||
rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket,
|
||||
rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket,
|
||||
rules::pycodestyle::rules::logical_lines::WhitespaceBeforePunctuation,
|
||||
rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeOperator,
|
||||
rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterOperator,
|
||||
rules::pycodestyle::rules::logical_lines::TabBeforeOperator,
|
||||
rules::pycodestyle::rules::logical_lines::TabAfterOperator,
|
||||
rules::pycodestyle::rules::logical_lines::TooFewSpacesBeforeInlineComment,
|
||||
rules::pycodestyle::rules::logical_lines::NoSpaceAfterInlineComment,
|
||||
rules::pycodestyle::rules::logical_lines::NoSpaceAfterBlockComment,
|
||||
rules::pycodestyle::rules::logical_lines::MultipleLeadingHashesForBlockComment,
|
||||
rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterKeyword,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespace,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword,
|
||||
rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeKeyword,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundOperator,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundArithmeticOperator,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundBitwiseOrShiftOperator,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundModuloOperator,
|
||||
rules::pycodestyle::rules::logical_lines::TabAfterKeyword,
|
||||
rules::pycodestyle::rules::logical_lines::UnexpectedSpacesAroundKeywordParameterEquals,
|
||||
rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundParameterEquals,
|
||||
rules::pycodestyle::rules::logical_lines::WhitespaceBeforeParameters,
|
||||
rules::pycodestyle::rules::logical_lines::TabBeforeKeyword,
|
||||
rules::pycodestyle::rules::MultipleImportsOnOneLine,
|
||||
rules::pycodestyle::rules::ModuleImportNotAtTopOfFile,
|
||||
rules::pycodestyle::rules::LineTooLong,
|
||||
rules::pycodestyle::rules::MultipleStatementsOnOneLineColon,
|
||||
rules::pycodestyle::rules::MultipleStatementsOnOneLineSemicolon,
|
||||
rules::pycodestyle::rules::UselessSemicolon,
|
||||
rules::pycodestyle::rules::NoneComparison,
|
||||
rules::pycodestyle::rules::TrueFalseComparison,
|
||||
rules::pycodestyle::rules::NotInTest,
|
||||
rules::pycodestyle::rules::NotIsTest,
|
||||
rules::pycodestyle::rules::TypeComparison,
|
||||
rules::pycodestyle::rules::BareExcept,
|
||||
rules::pycodestyle::rules::LambdaAssignment,
|
||||
rules::pycodestyle::rules::AmbiguousVariableName,
|
||||
rules::pycodestyle::rules::AmbiguousClassName,
|
||||
rules::pycodestyle::rules::AmbiguousFunctionName,
|
||||
rules::pycodestyle::rules::IOError,
|
||||
rules::pycodestyle::rules::SyntaxError,
|
||||
// pycodestyle warnings
|
||||
rules::pycodestyle::rules::TabIndentation,
|
||||
rules::pycodestyle::rules::TrailingWhitespace,
|
||||
rules::pycodestyle::rules::MissingNewlineAtEndOfFile,
|
||||
rules::pycodestyle::rules::BlankLineWithWhitespace,
|
||||
rules::pycodestyle::rules::DocLineTooLong,
|
||||
rules::pycodestyle::rules::InvalidEscapeSequence,
|
||||
// pyflakes
|
||||
rules::pyflakes::rules::UnusedImport,
|
||||
rules::pyflakes::rules::ImportShadowedByLoopVar,
|
||||
rules::pyflakes::rules::UndefinedLocalWithImportStar,
|
||||
rules::pyflakes::rules::LateFutureImport,
|
||||
rules::pyflakes::rules::UndefinedLocalWithImportStarUsage,
|
||||
rules::pyflakes::rules::UndefinedLocalWithNestedImportStarUsage,
|
||||
rules::pyflakes::rules::FutureFeatureNotDefined,
|
||||
rules::pyflakes::rules::PercentFormatInvalidFormat,
|
||||
rules::pyflakes::rules::PercentFormatExpectedMapping,
|
||||
rules::pyflakes::rules::PercentFormatExpectedSequence,
|
||||
rules::pyflakes::rules::PercentFormatExtraNamedArguments,
|
||||
rules::pyflakes::rules::PercentFormatMissingArgument,
|
||||
rules::pyflakes::rules::PercentFormatMixedPositionalAndNamed,
|
||||
rules::pyflakes::rules::PercentFormatPositionalCountMismatch,
|
||||
rules::pyflakes::rules::PercentFormatStarRequiresSequence,
|
||||
rules::pyflakes::rules::PercentFormatUnsupportedFormatCharacter,
|
||||
rules::pyflakes::rules::StringDotFormatInvalidFormat,
|
||||
rules::pyflakes::rules::StringDotFormatExtraNamedArguments,
|
||||
rules::pyflakes::rules::StringDotFormatExtraPositionalArguments,
|
||||
rules::pyflakes::rules::StringDotFormatMissingArguments,
|
||||
rules::pyflakes::rules::StringDotFormatMixingAutomatic,
|
||||
rules::pyflakes::rules::FStringMissingPlaceholders,
|
||||
rules::pyflakes::rules::MultiValueRepeatedKeyLiteral,
|
||||
rules::pyflakes::rules::MultiValueRepeatedKeyVariable,
|
||||
rules::pyflakes::rules::ExpressionsInStarAssignment,
|
||||
rules::pyflakes::rules::MultipleStarredExpressions,
|
||||
rules::pyflakes::rules::AssertTuple,
|
||||
rules::pyflakes::rules::IsLiteral,
|
||||
rules::pyflakes::rules::InvalidPrintSyntax,
|
||||
rules::pyflakes::rules::IfTuple,
|
||||
rules::pyflakes::rules::BreakOutsideLoop,
|
||||
rules::pyflakes::rules::ContinueOutsideLoop,
|
||||
rules::pyflakes::rules::YieldOutsideFunction,
|
||||
rules::pyflakes::rules::ReturnOutsideFunction,
|
||||
rules::pyflakes::rules::DefaultExceptNotLast,
|
||||
rules::pyflakes::rules::ForwardAnnotationSyntaxError,
|
||||
rules::pyflakes::rules::RedefinedWhileUnused,
|
||||
rules::pyflakes::rules::UndefinedName,
|
||||
rules::pyflakes::rules::UndefinedExport,
|
||||
rules::pyflakes::rules::UndefinedLocal,
|
||||
rules::pyflakes::rules::UnusedVariable,
|
||||
rules::pyflakes::rules::UnusedAnnotation,
|
||||
rules::pyflakes::rules::RaiseNotImplemented,
|
||||
// pylint
|
||||
rules::pylint::rules::AssertOnStringLiteral,
|
||||
rules::pylint::rules::UselessReturn,
|
||||
rules::pylint::rules::YieldFromInAsyncFunction,
|
||||
rules::pylint::rules::YieldInInit,
|
||||
rules::pylint::rules::InvalidAllObject,
|
||||
rules::pylint::rules::InvalidAllFormat,
|
||||
rules::pylint::rules::InvalidEnvvarDefault,
|
||||
rules::pylint::rules::InvalidEnvvarValue,
|
||||
rules::pylint::rules::BadStringFormatType,
|
||||
rules::pylint::rules::BidirectionalUnicode,
|
||||
rules::pylint::rules::BinaryOpException,
|
||||
rules::pylint::rules::ImportSelf,
|
||||
rules::pylint::rules::InvalidCharacterBackspace,
|
||||
rules::pylint::rules::InvalidCharacterSub,
|
||||
rules::pylint::rules::InvalidCharacterEsc,
|
||||
rules::pylint::rules::InvalidCharacterNul,
|
||||
rules::pylint::rules::InvalidCharacterZeroWidthSpace,
|
||||
rules::pylint::rules::BadStrStripCall,
|
||||
rules::pylint::rules::CollapsibleElseIf,
|
||||
rules::pylint::rules::ContinueInFinally,
|
||||
rules::pylint::rules::UselessImportAlias,
|
||||
rules::pylint::rules::UnnecessaryDirectLambdaCall,
|
||||
rules::pylint::rules::NonlocalWithoutBinding,
|
||||
rules::pylint::rules::LoadBeforeGlobalDeclaration,
|
||||
rules::pylint::rules::AwaitOutsideAsync,
|
||||
rules::pylint::rules::PropertyWithParameters,
|
||||
rules::pylint::rules::ReturnInInit,
|
||||
rules::pylint::rules::ManualFromImport,
|
||||
rules::pylint::rules::CompareToEmptyString,
|
||||
rules::pylint::rules::ComparisonOfConstant,
|
||||
rules::pylint::rules::RepeatedIsinstanceCalls,
|
||||
rules::pylint::rules::SysExitAlias,
|
||||
rules::pylint::rules::MagicValueComparison,
|
||||
rules::pylint::rules::UselessElseOnLoop,
|
||||
rules::pylint::rules::GlobalStatement,
|
||||
rules::pylint::rules::GlobalVariableNotAssigned,
|
||||
rules::pylint::rules::TooManyReturnStatements,
|
||||
rules::pylint::rules::TooManyArguments,
|
||||
rules::pylint::rules::TooManyBranches,
|
||||
rules::pylint::rules::TooManyStatements,
|
||||
rules::pylint::rules::RedefinedLoopName,
|
||||
rules::pylint::rules::LoggingTooFewArgs,
|
||||
rules::pylint::rules::LoggingTooManyArgs,
|
||||
rules::pylint::rules::UnexpectedSpecialMethodSignature,
|
||||
rules::pylint::rules::NestedMinMax,
|
||||
rules::pylint::rules::DuplicateValue,
|
||||
rules::pylint::rules::DuplicateBases,
|
||||
rules::pylint::rules::NamedExprWithoutContext,
|
||||
rules::pylint::rules::IterationOverSet,
|
||||
// flake8-async
|
||||
rules::flake8_async::rules::BlockingHttpCallInAsyncFunction,
|
||||
rules::flake8_async::rules::OpenSleepOrSubprocessInAsyncFunction,
|
||||
rules::flake8_async::rules::BlockingOsCallInAsyncFunction,
|
||||
// flake8-builtins
|
||||
rules::flake8_builtins::rules::BuiltinVariableShadowing,
|
||||
rules::flake8_builtins::rules::BuiltinArgumentShadowing,
|
||||
rules::flake8_builtins::rules::BuiltinAttributeShadowing,
|
||||
// flake8-bugbear
|
||||
rules::flake8_bugbear::rules::UnaryPrefixIncrement,
|
||||
rules::flake8_bugbear::rules::AssignmentToOsEnviron,
|
||||
rules::flake8_bugbear::rules::UnreliableCallableCheck,
|
||||
rules::flake8_bugbear::rules::StripWithMultiCharacters,
|
||||
rules::flake8_bugbear::rules::MutableArgumentDefault,
|
||||
rules::flake8_bugbear::rules::NoExplicitStacklevel,
|
||||
rules::flake8_bugbear::rules::UnusedLoopControlVariable,
|
||||
rules::flake8_bugbear::rules::FunctionCallInDefaultArgument,
|
||||
rules::flake8_bugbear::rules::GetAttrWithConstant,
|
||||
rules::flake8_bugbear::rules::SetAttrWithConstant,
|
||||
rules::flake8_bugbear::rules::AssertFalse,
|
||||
rules::flake8_bugbear::rules::JumpStatementInFinally,
|
||||
rules::flake8_bugbear::rules::RedundantTupleInExceptionHandler,
|
||||
rules::flake8_bugbear::rules::DuplicateHandlerException,
|
||||
rules::flake8_bugbear::rules::UselessComparison,
|
||||
rules::flake8_bugbear::rules::CannotRaiseLiteral,
|
||||
rules::flake8_bugbear::rules::AssertRaisesException,
|
||||
rules::flake8_bugbear::rules::UselessExpression,
|
||||
rules::flake8_bugbear::rules::CachedInstanceMethod,
|
||||
rules::flake8_bugbear::rules::LoopVariableOverridesIterator,
|
||||
rules::flake8_bugbear::rules::FStringDocstring,
|
||||
rules::flake8_bugbear::rules::UselessContextlibSuppress,
|
||||
rules::flake8_bugbear::rules::FunctionUsesLoopVariable,
|
||||
rules::flake8_bugbear::rules::AbstractBaseClassWithoutAbstractMethod,
|
||||
rules::flake8_bugbear::rules::DuplicateTryBlockException,
|
||||
rules::flake8_bugbear::rules::StarArgUnpackingAfterKeywordArg,
|
||||
rules::flake8_bugbear::rules::EmptyMethodWithoutAbstractDecorator,
|
||||
rules::flake8_bugbear::rules::RaiseWithoutFromInsideExcept,
|
||||
rules::flake8_bugbear::rules::ZipWithoutExplicitStrict,
|
||||
rules::flake8_bugbear::rules::ExceptWithEmptyTuple,
|
||||
rules::flake8_bugbear::rules::ExceptWithNonExceptionClasses,
|
||||
rules::flake8_bugbear::rules::ReuseOfGroupbyGenerator,
|
||||
rules::flake8_bugbear::rules::UnintentionalTypeAnnotation,
|
||||
// flake8-blind-except
|
||||
rules::flake8_blind_except::rules::BlindExcept,
|
||||
// flake8-comprehensions
|
||||
rules::flake8_comprehensions::rules::UnnecessaryCallAroundSorted,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryCollectionCall,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryComprehension,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryComprehensionAnyAll,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryDoubleCastOrProcess,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryGeneratorDict,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryGeneratorList,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryGeneratorSet,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryListCall,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryListComprehensionDict,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryListComprehensionSet,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryLiteralDict,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryLiteralSet,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinDictCall,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinListCall,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinTupleCall,
|
||||
rules::flake8_comprehensions::rules::UnnecessaryMap,
|
||||
rules::flake8_comprehensions::rules::UnnecessarySubscriptReversal,
|
||||
// flake8-debugger
|
||||
rules::flake8_debugger::rules::Debugger,
|
||||
// mccabe
|
||||
rules::mccabe::rules::ComplexStructure,
|
||||
// flake8-tidy-imports
|
||||
rules::flake8_tidy_imports::rules::BannedApi,
|
||||
rules::flake8_tidy_imports::rules::RelativeImports,
|
||||
// flake8-return
|
||||
rules::flake8_return::rules::UnnecessaryReturnNone,
|
||||
rules::flake8_return::rules::ImplicitReturnValue,
|
||||
rules::flake8_return::rules::ImplicitReturn,
|
||||
rules::flake8_return::rules::UnnecessaryAssign,
|
||||
rules::flake8_return::rules::SuperfluousElseReturn,
|
||||
rules::flake8_return::rules::SuperfluousElseRaise,
|
||||
rules::flake8_return::rules::SuperfluousElseContinue,
|
||||
rules::flake8_return::rules::SuperfluousElseBreak,
|
||||
// flake8-implicit-str-concat
|
||||
rules::flake8_implicit_str_concat::rules::SingleLineImplicitStringConcatenation,
|
||||
rules::flake8_implicit_str_concat::rules::MultiLineImplicitStringConcatenation,
|
||||
rules::flake8_implicit_str_concat::rules::ExplicitStringConcatenation,
|
||||
// flake8-print
|
||||
rules::flake8_print::rules::Print,
|
||||
rules::flake8_print::rules::PPrint,
|
||||
// flake8-quotes
|
||||
rules::flake8_quotes::rules::BadQuotesInlineString,
|
||||
rules::flake8_quotes::rules::BadQuotesMultilineString,
|
||||
rules::flake8_quotes::rules::BadQuotesDocstring,
|
||||
rules::flake8_quotes::rules::AvoidableEscapedQuote,
|
||||
// flake8-annotations
|
||||
rules::flake8_annotations::rules::MissingTypeFunctionArgument,
|
||||
rules::flake8_annotations::rules::MissingTypeArgs,
|
||||
rules::flake8_annotations::rules::MissingTypeKwargs,
|
||||
rules::flake8_annotations::rules::MissingTypeSelf,
|
||||
rules::flake8_annotations::rules::MissingTypeCls,
|
||||
rules::flake8_annotations::rules::MissingReturnTypeUndocumentedPublicFunction,
|
||||
rules::flake8_annotations::rules::MissingReturnTypePrivateFunction,
|
||||
rules::flake8_annotations::rules::MissingReturnTypeSpecialMethod,
|
||||
rules::flake8_annotations::rules::MissingReturnTypeStaticMethod,
|
||||
rules::flake8_annotations::rules::MissingReturnTypeClassMethod,
|
||||
rules::flake8_annotations::rules::AnyType,
|
||||
// flake8-future-annotations
|
||||
rules::flake8_future_annotations::rules::FutureRewritableTypeAnnotation,
|
||||
rules::flake8_future_annotations::rules::FutureRequiredTypeAnnotation,
|
||||
// flake8-2020
|
||||
rules::flake8_2020::rules::SysVersionSlice3,
|
||||
rules::flake8_2020::rules::SysVersion2,
|
||||
rules::flake8_2020::rules::SysVersionCmpStr3,
|
||||
rules::flake8_2020::rules::SysVersionInfo0Eq3,
|
||||
rules::flake8_2020::rules::SixPY3,
|
||||
rules::flake8_2020::rules::SysVersionInfo1CmpInt,
|
||||
rules::flake8_2020::rules::SysVersionInfoMinorCmpInt,
|
||||
rules::flake8_2020::rules::SysVersion0,
|
||||
rules::flake8_2020::rules::SysVersionCmpStr10,
|
||||
rules::flake8_2020::rules::SysVersionSlice1,
|
||||
// flake8-simplify
|
||||
rules::flake8_simplify::rules::IfElseBlockInsteadOfDictLookup,
|
||||
rules::flake8_simplify::rules::DuplicateIsinstanceCall,
|
||||
rules::flake8_simplify::rules::CollapsibleIf,
|
||||
rules::flake8_simplify::rules::NeedlessBool,
|
||||
rules::flake8_simplify::rules::SuppressibleException,
|
||||
rules::flake8_simplify::rules::ReturnInTryExceptFinally,
|
||||
rules::flake8_simplify::rules::IfElseBlockInsteadOfIfExp,
|
||||
rules::flake8_simplify::rules::CompareWithTuple,
|
||||
rules::flake8_simplify::rules::ReimplementedBuiltin,
|
||||
rules::flake8_simplify::rules::UncapitalizedEnvironmentVariables,
|
||||
rules::flake8_simplify::rules::IfWithSameArms,
|
||||
rules::flake8_simplify::rules::OpenFileWithContextHandler,
|
||||
rules::flake8_simplify::rules::MultipleWithStatements,
|
||||
rules::flake8_simplify::rules::InDictKeys,
|
||||
rules::flake8_simplify::rules::NegateEqualOp,
|
||||
rules::flake8_simplify::rules::NegateNotEqualOp,
|
||||
rules::flake8_simplify::rules::DoubleNegation,
|
||||
rules::flake8_simplify::rules::IfExprWithTrueFalse,
|
||||
rules::flake8_simplify::rules::IfExprWithFalseTrue,
|
||||
rules::flake8_simplify::rules::IfExprWithTwistedArms,
|
||||
rules::flake8_simplify::rules::ExprAndNotExpr,
|
||||
rules::flake8_simplify::rules::ExprOrNotExpr,
|
||||
rules::flake8_simplify::rules::ExprOrTrue,
|
||||
rules::flake8_simplify::rules::ExprAndFalse,
|
||||
rules::flake8_simplify::rules::YodaConditions,
|
||||
rules::flake8_simplify::rules::IfElseBlockInsteadOfDictGet,
|
||||
rules::flake8_simplify::rules::DictGetWithNoneDefault,
|
||||
// pyupgrade
|
||||
rules::pyupgrade::rules::UselessMetaclassType,
|
||||
rules::pyupgrade::rules::TypeOfPrimitive,
|
||||
rules::pyupgrade::rules::UselessObjectInheritance,
|
||||
rules::pyupgrade::rules::DeprecatedUnittestAlias,
|
||||
rules::pyupgrade::rules::NonPEP585Annotation,
|
||||
rules::pyupgrade::rules::NonPEP604Annotation,
|
||||
rules::pyupgrade::rules::SuperCallWithParameters,
|
||||
rules::pyupgrade::rules::UTF8EncodingDeclaration,
|
||||
rules::pyupgrade::rules::UnnecessaryFutureImport,
|
||||
rules::pyupgrade::rules::LRUCacheWithoutParameters,
|
||||
rules::pyupgrade::rules::UnnecessaryEncodeUTF8,
|
||||
rules::pyupgrade::rules::ConvertTypedDictFunctionalToClass,
|
||||
rules::pyupgrade::rules::ConvertNamedTupleFunctionalToClass,
|
||||
rules::pyupgrade::rules::RedundantOpenModes,
|
||||
rules::pyupgrade::rules::DatetimeTimezoneUTC,
|
||||
rules::pyupgrade::rules::NativeLiterals,
|
||||
rules::pyupgrade::rules::TypingTextStrAlias,
|
||||
rules::pyupgrade::rules::OpenAlias,
|
||||
rules::pyupgrade::rules::ReplaceUniversalNewlines,
|
||||
rules::pyupgrade::rules::ReplaceStdoutStderr,
|
||||
rules::pyupgrade::rules::DeprecatedCElementTree,
|
||||
rules::pyupgrade::rules::OSErrorAlias,
|
||||
rules::pyupgrade::rules::UnicodeKindPrefix,
|
||||
rules::pyupgrade::rules::DeprecatedMockImport,
|
||||
rules::pyupgrade::rules::UnpackedListComprehension,
|
||||
rules::pyupgrade::rules::YieldInForLoop,
|
||||
rules::pyupgrade::rules::UnnecessaryBuiltinImport,
|
||||
rules::pyupgrade::rules::FormatLiterals,
|
||||
rules::pyupgrade::rules::PrintfStringFormatting,
|
||||
rules::pyupgrade::rules::FString,
|
||||
rules::pyupgrade::rules::LRUCacheWithMaxsizeNone,
|
||||
rules::pyupgrade::rules::ExtraneousParentheses,
|
||||
rules::pyupgrade::rules::DeprecatedImport,
|
||||
rules::pyupgrade::rules::OutdatedVersionBlock,
|
||||
rules::pyupgrade::rules::QuotedAnnotation,
|
||||
rules::pyupgrade::rules::NonPEP604Isinstance,
|
||||
// pydocstyle
|
||||
rules::pydocstyle::rules::UndocumentedPublicModule,
|
||||
rules::pydocstyle::rules::UndocumentedPublicClass,
|
||||
rules::pydocstyle::rules::UndocumentedPublicMethod,
|
||||
rules::pydocstyle::rules::UndocumentedPublicFunction,
|
||||
rules::pydocstyle::rules::UndocumentedPublicPackage,
|
||||
rules::pydocstyle::rules::UndocumentedMagicMethod,
|
||||
rules::pydocstyle::rules::UndocumentedPublicNestedClass,
|
||||
rules::pydocstyle::rules::UndocumentedPublicInit,
|
||||
rules::pydocstyle::rules::FitsOnOneLine,
|
||||
rules::pydocstyle::rules::NoBlankLineBeforeFunction,
|
||||
rules::pydocstyle::rules::NoBlankLineAfterFunction,
|
||||
rules::pydocstyle::rules::OneBlankLineBeforeClass,
|
||||
rules::pydocstyle::rules::OneBlankLineAfterClass,
|
||||
rules::pydocstyle::rules::BlankLineAfterSummary,
|
||||
rules::pydocstyle::rules::IndentWithSpaces,
|
||||
rules::pydocstyle::rules::UnderIndentation,
|
||||
rules::pydocstyle::rules::OverIndentation,
|
||||
rules::pydocstyle::rules::NewLineAfterLastParagraph,
|
||||
rules::pydocstyle::rules::SurroundingWhitespace,
|
||||
rules::pydocstyle::rules::BlankLineBeforeClass,
|
||||
rules::pydocstyle::rules::MultiLineSummaryFirstLine,
|
||||
rules::pydocstyle::rules::MultiLineSummarySecondLine,
|
||||
rules::pydocstyle::rules::SectionNotOverIndented,
|
||||
rules::pydocstyle::rules::SectionUnderlineNotOverIndented,
|
||||
rules::pydocstyle::rules::TripleSingleQuotes,
|
||||
rules::pydocstyle::rules::EscapeSequenceInDocstring,
|
||||
rules::pydocstyle::rules::EndsInPeriod,
|
||||
rules::pydocstyle::rules::NonImperativeMood,
|
||||
rules::pydocstyle::rules::NoSignature,
|
||||
rules::pydocstyle::rules::FirstLineCapitalized,
|
||||
rules::pydocstyle::rules::DocstringStartsWithThis,
|
||||
rules::pydocstyle::rules::CapitalizeSectionName,
|
||||
rules::pydocstyle::rules::NewLineAfterSectionName,
|
||||
rules::pydocstyle::rules::DashedUnderlineAfterSection,
|
||||
rules::pydocstyle::rules::SectionUnderlineAfterName,
|
||||
rules::pydocstyle::rules::SectionUnderlineMatchesSectionLength,
|
||||
rules::pydocstyle::rules::NoBlankLineAfterSection,
|
||||
rules::pydocstyle::rules::NoBlankLineBeforeSection,
|
||||
rules::pydocstyle::rules::BlankLinesBetweenHeaderAndContent,
|
||||
rules::pydocstyle::rules::BlankLineAfterLastSection,
|
||||
rules::pydocstyle::rules::EmptyDocstringSection,
|
||||
rules::pydocstyle::rules::EndsInPunctuation,
|
||||
rules::pydocstyle::rules::SectionNameEndsInColon,
|
||||
rules::pydocstyle::rules::UndocumentedParam,
|
||||
rules::pydocstyle::rules::OverloadWithDocstring,
|
||||
rules::pydocstyle::rules::EmptyDocstring,
|
||||
// pep8-naming
|
||||
rules::pep8_naming::rules::InvalidClassName,
|
||||
rules::pep8_naming::rules::InvalidFunctionName,
|
||||
rules::pep8_naming::rules::InvalidArgumentName,
|
||||
rules::pep8_naming::rules::InvalidFirstArgumentNameForClassMethod,
|
||||
rules::pep8_naming::rules::InvalidFirstArgumentNameForMethod,
|
||||
rules::pep8_naming::rules::NonLowercaseVariableInFunction,
|
||||
rules::pep8_naming::rules::DunderFunctionName,
|
||||
rules::pep8_naming::rules::ConstantImportedAsNonConstant,
|
||||
rules::pep8_naming::rules::LowercaseImportedAsNonLowercase,
|
||||
rules::pep8_naming::rules::CamelcaseImportedAsLowercase,
|
||||
rules::pep8_naming::rules::CamelcaseImportedAsConstant,
|
||||
rules::pep8_naming::rules::MixedCaseVariableInClassScope,
|
||||
rules::pep8_naming::rules::MixedCaseVariableInGlobalScope,
|
||||
rules::pep8_naming::rules::CamelcaseImportedAsAcronym,
|
||||
rules::pep8_naming::rules::ErrorSuffixOnExceptionName,
|
||||
rules::pep8_naming::rules::InvalidModuleName,
|
||||
// isort
|
||||
rules::isort::rules::UnsortedImports,
|
||||
rules::isort::rules::MissingRequiredImport,
|
||||
// eradicate
|
||||
rules::eradicate::rules::CommentedOutCode,
|
||||
// flake8-bandit
|
||||
rules::flake8_bandit::rules::Assert,
|
||||
rules::flake8_bandit::rules::BadFilePermissions,
|
||||
rules::flake8_bandit::rules::ExecBuiltin,
|
||||
rules::flake8_bandit::rules::HardcodedBindAllInterfaces,
|
||||
rules::flake8_bandit::rules::HardcodedPasswordDefault,
|
||||
rules::flake8_bandit::rules::HardcodedPasswordFuncArg,
|
||||
rules::flake8_bandit::rules::HardcodedPasswordString,
|
||||
rules::flake8_bandit::rules::HardcodedSQLExpression,
|
||||
rules::flake8_bandit::rules::HardcodedTempFile,
|
||||
rules::flake8_bandit::rules::HashlibInsecureHashFunction,
|
||||
rules::flake8_bandit::rules::Jinja2AutoescapeFalse,
|
||||
rules::flake8_bandit::rules::ParamikoCall,
|
||||
rules::flake8_bandit::rules::LoggingConfigInsecureListen,
|
||||
rules::flake8_bandit::rules::RequestWithNoCertValidation,
|
||||
rules::flake8_bandit::rules::RequestWithoutTimeout,
|
||||
rules::flake8_bandit::rules::SnmpInsecureVersion,
|
||||
rules::flake8_bandit::rules::SnmpWeakCryptography,
|
||||
rules::flake8_bandit::rules::SubprocessPopenWithShellEqualsTrue,
|
||||
rules::flake8_bandit::rules::SubprocessWithoutShellEqualsTrue,
|
||||
rules::flake8_bandit::rules::CallWithShellEqualsTrue,
|
||||
rules::flake8_bandit::rules::StartProcessWithAShell,
|
||||
rules::flake8_bandit::rules::StartProcessWithNoShell,
|
||||
rules::flake8_bandit::rules::StartProcessWithPartialPath,
|
||||
rules::flake8_bandit::rules::SuspiciousEvalUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousFTPLibUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousInsecureCipherUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousInsecureCipherModeUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousInsecureHashUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousMarkSafeUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousMarshalUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousMktempUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousNonCryptographicRandomUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousPickleUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousTelnetUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousURLOpenUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousUnverifiedContextUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLCElementTreeUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLETreeUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLElementTreeUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLExpatBuilderUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLExpatReaderUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLMiniDOMUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLPullDOMUsage,
|
||||
rules::flake8_bandit::rules::SuspiciousXMLSaxUsage,
|
||||
rules::flake8_bandit::rules::TryExceptContinue,
|
||||
rules::flake8_bandit::rules::TryExceptPass,
|
||||
rules::flake8_bandit::rules::UnsafeYAMLLoad,
|
||||
// flake8-boolean-trap
|
||||
rules::flake8_boolean_trap::rules::BooleanPositionalArgInFunctionDefinition,
|
||||
rules::flake8_boolean_trap::rules::BooleanDefaultValueInFunctionDefinition,
|
||||
rules::flake8_boolean_trap::rules::BooleanPositionalValueInFunctionCall,
|
||||
// flake8-unused-arguments
|
||||
rules::flake8_unused_arguments::rules::UnusedFunctionArgument,
|
||||
rules::flake8_unused_arguments::rules::UnusedMethodArgument,
|
||||
rules::flake8_unused_arguments::rules::UnusedClassMethodArgument,
|
||||
rules::flake8_unused_arguments::rules::UnusedStaticMethodArgument,
|
||||
rules::flake8_unused_arguments::rules::UnusedLambdaArgument,
|
||||
// flake8-import-conventions
|
||||
rules::flake8_import_conventions::rules::UnconventionalImportAlias,
|
||||
rules::flake8_import_conventions::rules::BannedImportAlias,
|
||||
rules::flake8_import_conventions::rules::BannedImportFrom,
|
||||
// flake8-datetimez
|
||||
rules::flake8_datetimez::rules::CallDatetimeWithoutTzinfo,
|
||||
rules::flake8_datetimez::rules::CallDatetimeToday,
|
||||
rules::flake8_datetimez::rules::CallDatetimeUtcnow,
|
||||
rules::flake8_datetimez::rules::CallDatetimeUtcfromtimestamp,
|
||||
rules::flake8_datetimez::rules::CallDatetimeNowWithoutTzinfo,
|
||||
rules::flake8_datetimez::rules::CallDatetimeFromtimestamp,
|
||||
rules::flake8_datetimez::rules::CallDatetimeStrptimeWithoutZone,
|
||||
rules::flake8_datetimez::rules::CallDateToday,
|
||||
rules::flake8_datetimez::rules::CallDateFromtimestamp,
|
||||
// pygrep-hooks
|
||||
rules::pygrep_hooks::rules::BlanketNOQA,
|
||||
rules::pygrep_hooks::rules::BlanketTypeIgnore,
|
||||
rules::pygrep_hooks::rules::DeprecatedLogWarn,
|
||||
rules::pygrep_hooks::rules::Eval,
|
||||
rules::pygrep_hooks::rules::InvalidMockAccess,
|
||||
// pandas-vet
|
||||
rules::pandas_vet::rules::PandasUseOfInplaceArgument,
|
||||
rules::pandas_vet::rules::PandasUseOfDotIsNull,
|
||||
rules::pandas_vet::rules::PandasUseOfDotNotNull,
|
||||
rules::pandas_vet::rules::PandasUseOfDotIx,
|
||||
rules::pandas_vet::rules::PandasUseOfDotAt,
|
||||
rules::pandas_vet::rules::PandasUseOfDotIat,
|
||||
rules::pandas_vet::rules::PandasUseOfDotPivotOrUnstack,
|
||||
rules::pandas_vet::rules::PandasUseOfDotValues,
|
||||
rules::pandas_vet::rules::PandasUseOfDotReadTable,
|
||||
rules::pandas_vet::rules::PandasUseOfDotStack,
|
||||
rules::pandas_vet::rules::PandasUseOfPdMerge,
|
||||
rules::pandas_vet::rules::PandasDfVariableName,
|
||||
// flake8-errmsg
|
||||
rules::flake8_errmsg::rules::RawStringInException,
|
||||
rules::flake8_errmsg::rules::FStringInException,
|
||||
rules::flake8_errmsg::rules::DotFormatInException,
|
||||
// flake8-pyi
|
||||
rules::flake8_pyi::rules::AnyEqNeAnnotation,
|
||||
rules::flake8_pyi::rules::ArgumentDefaultInStub,
|
||||
rules::flake8_pyi::rules::AssignmentDefaultInStub,
|
||||
rules::flake8_pyi::rules::BadVersionInfoComparison,
|
||||
rules::flake8_pyi::rules::DocstringInStub,
|
||||
rules::flake8_pyi::rules::IterMethodReturnIterable,
|
||||
rules::flake8_pyi::rules::DuplicateUnionMember,
|
||||
rules::flake8_pyi::rules::EllipsisInNonEmptyClassBody,
|
||||
rules::flake8_pyi::rules::NonSelfReturnType,
|
||||
rules::flake8_pyi::rules::CollectionsNamedTuple,
|
||||
rules::flake8_pyi::rules::StringOrBytesTooLong,
|
||||
rules::flake8_pyi::rules::NonEmptyStubBody,
|
||||
rules::flake8_pyi::rules::PassInClassBody,
|
||||
rules::flake8_pyi::rules::PassStatementStubBody,
|
||||
rules::flake8_pyi::rules::NumericLiteralTooLong,
|
||||
rules::flake8_pyi::rules::QuotedAnnotationInStub,
|
||||
rules::flake8_pyi::rules::SnakeCaseTypeAlias,
|
||||
rules::flake8_pyi::rules::StubBodyMultipleStatements,
|
||||
rules::flake8_pyi::rules::TSuffixedTypeAlias,
|
||||
rules::flake8_pyi::rules::TypeCommentInStub,
|
||||
rules::flake8_pyi::rules::TypedArgumentDefaultInStub,
|
||||
rules::flake8_pyi::rules::UnaliasedCollectionsAbcSetImport,
|
||||
rules::flake8_pyi::rules::UnannotatedAssignmentInStub,
|
||||
rules::flake8_pyi::rules::UnprefixedTypeParam,
|
||||
rules::flake8_pyi::rules::UnrecognizedPlatformCheck,
|
||||
rules::flake8_pyi::rules::UnrecognizedPlatformName,
|
||||
// flake8-pytest-style
|
||||
rules::flake8_pytest_style::rules::PytestFixtureIncorrectParenthesesStyle,
|
||||
rules::flake8_pytest_style::rules::PytestFixturePositionalArgs,
|
||||
rules::flake8_pytest_style::rules::PytestExtraneousScopeFunction,
|
||||
rules::flake8_pytest_style::rules::PytestMissingFixtureNameUnderscore,
|
||||
rules::flake8_pytest_style::rules::PytestIncorrectFixtureNameUnderscore,
|
||||
rules::flake8_pytest_style::rules::PytestParametrizeNamesWrongType,
|
||||
rules::flake8_pytest_style::rules::PytestParametrizeValuesWrongType,
|
||||
rules::flake8_pytest_style::rules::PytestPatchWithLambda,
|
||||
rules::flake8_pytest_style::rules::PytestUnittestAssertion,
|
||||
rules::flake8_pytest_style::rules::PytestRaisesWithoutException,
|
||||
rules::flake8_pytest_style::rules::PytestRaisesTooBroad,
|
||||
rules::flake8_pytest_style::rules::PytestRaisesWithMultipleStatements,
|
||||
rules::flake8_pytest_style::rules::PytestIncorrectPytestImport,
|
||||
rules::flake8_pytest_style::rules::PytestAssertAlwaysFalse,
|
||||
rules::flake8_pytest_style::rules::PytestFailWithoutMessage,
|
||||
rules::flake8_pytest_style::rules::PytestAssertInExcept,
|
||||
rules::flake8_pytest_style::rules::PytestCompositeAssertion,
|
||||
rules::flake8_pytest_style::rules::PytestFixtureParamWithoutValue,
|
||||
rules::flake8_pytest_style::rules::PytestDeprecatedYieldFixture,
|
||||
rules::flake8_pytest_style::rules::PytestFixtureFinalizerCallback,
|
||||
rules::flake8_pytest_style::rules::PytestUselessYieldFixture,
|
||||
rules::flake8_pytest_style::rules::PytestIncorrectMarkParenthesesStyle,
|
||||
rules::flake8_pytest_style::rules::PytestUnnecessaryAsyncioMarkOnFixture,
|
||||
rules::flake8_pytest_style::rules::PytestErroneousUseFixturesOnFixture,
|
||||
rules::flake8_pytest_style::rules::PytestUseFixturesWithoutParameters,
|
||||
// flake8-pie
|
||||
rules::flake8_pie::rules::UnnecessaryPass,
|
||||
rules::flake8_pie::rules::DuplicateClassFieldDefinition,
|
||||
rules::flake8_pie::rules::NonUniqueEnums,
|
||||
rules::flake8_pie::rules::UnnecessarySpread,
|
||||
rules::flake8_pie::rules::UnnecessaryDictKwargs,
|
||||
rules::flake8_pie::rules::ReimplementedListBuiltin,
|
||||
rules::flake8_pie::rules::MultipleStartsEndsWith,
|
||||
// flake8-commas
|
||||
rules::flake8_commas::rules::MissingTrailingComma,
|
||||
rules::flake8_commas::rules::TrailingCommaOnBareTuple,
|
||||
rules::flake8_commas::rules::ProhibitedTrailingComma,
|
||||
// flake8-no-pep420
|
||||
rules::flake8_no_pep420::rules::ImplicitNamespacePackage,
|
||||
// flake8-executable
|
||||
rules::flake8_executable::rules::ShebangNotExecutable,
|
||||
rules::flake8_executable::rules::ShebangMissingExecutableFile,
|
||||
rules::flake8_executable::rules::ShebangMissingPython,
|
||||
rules::flake8_executable::rules::ShebangLeadingWhitespace,
|
||||
rules::flake8_executable::rules::ShebangNotFirstLine,
|
||||
// flake8-type-checking
|
||||
rules::flake8_type_checking::rules::TypingOnlyFirstPartyImport,
|
||||
rules::flake8_type_checking::rules::TypingOnlyThirdPartyImport,
|
||||
rules::flake8_type_checking::rules::TypingOnlyStandardLibraryImport,
|
||||
rules::flake8_type_checking::rules::RuntimeImportInTypeCheckingBlock,
|
||||
rules::flake8_type_checking::rules::EmptyTypeCheckingBlock,
|
||||
// tryceratops
|
||||
rules::tryceratops::rules::RaiseVanillaClass,
|
||||
rules::tryceratops::rules::RaiseVanillaArgs,
|
||||
rules::tryceratops::rules::TypeCheckWithoutTypeError,
|
||||
rules::tryceratops::rules::ReraiseNoCause,
|
||||
rules::tryceratops::rules::VerboseRaise,
|
||||
rules::tryceratops::rules::TryConsiderElse,
|
||||
rules::tryceratops::rules::UselessTryExcept,
|
||||
rules::tryceratops::rules::RaiseWithinTry,
|
||||
rules::tryceratops::rules::ErrorInsteadOfException,
|
||||
rules::tryceratops::rules::VerboseLogMessage,
|
||||
// flake8-use-pathlib
|
||||
rules::flake8_use_pathlib::violations::OsPathAbspath,
|
||||
rules::flake8_use_pathlib::violations::OsChmod,
|
||||
rules::flake8_use_pathlib::violations::OsMkdir,
|
||||
rules::flake8_use_pathlib::violations::OsMakedirs,
|
||||
rules::flake8_use_pathlib::violations::OsRename,
|
||||
rules::flake8_use_pathlib::violations::PathlibReplace,
|
||||
rules::flake8_use_pathlib::violations::OsRmdir,
|
||||
rules::flake8_use_pathlib::violations::OsRemove,
|
||||
rules::flake8_use_pathlib::violations::OsUnlink,
|
||||
rules::flake8_use_pathlib::violations::OsGetcwd,
|
||||
rules::flake8_use_pathlib::violations::OsPathExists,
|
||||
rules::flake8_use_pathlib::violations::OsPathExpanduser,
|
||||
rules::flake8_use_pathlib::violations::OsPathIsdir,
|
||||
rules::flake8_use_pathlib::violations::OsPathIsfile,
|
||||
rules::flake8_use_pathlib::violations::OsPathIslink,
|
||||
rules::flake8_use_pathlib::violations::OsReadlink,
|
||||
rules::flake8_use_pathlib::violations::OsStat,
|
||||
rules::flake8_use_pathlib::violations::OsPathIsabs,
|
||||
rules::flake8_use_pathlib::violations::OsPathJoin,
|
||||
rules::flake8_use_pathlib::violations::OsPathBasename,
|
||||
rules::flake8_use_pathlib::violations::OsPathDirname,
|
||||
rules::flake8_use_pathlib::violations::OsPathSamefile,
|
||||
rules::flake8_use_pathlib::violations::OsPathSplitext,
|
||||
rules::flake8_use_pathlib::violations::BuiltinOpen,
|
||||
rules::flake8_use_pathlib::violations::PyPath,
|
||||
// flake8-logging-format
|
||||
rules::flake8_logging_format::violations::LoggingStringFormat,
|
||||
rules::flake8_logging_format::violations::LoggingPercentFormat,
|
||||
rules::flake8_logging_format::violations::LoggingStringConcat,
|
||||
rules::flake8_logging_format::violations::LoggingFString,
|
||||
rules::flake8_logging_format::violations::LoggingWarn,
|
||||
rules::flake8_logging_format::violations::LoggingExtraAttrClash,
|
||||
rules::flake8_logging_format::violations::LoggingExcInfo,
|
||||
rules::flake8_logging_format::violations::LoggingRedundantExcInfo,
|
||||
// flake8-raise
|
||||
rules::flake8_raise::rules::UnnecessaryParenOnRaiseException,
|
||||
// flake8-self
|
||||
rules::flake8_self::rules::PrivateMemberAccess,
|
||||
// flake8-gettext
|
||||
rules::flake8_gettext::rules::FStringInGetTextFuncCall,
|
||||
rules::flake8_gettext::rules::FormatInGetTextFuncCall,
|
||||
rules::flake8_gettext::rules::PrintfInGetTextFuncCall,
|
||||
// numpy
|
||||
rules::numpy::rules::NumpyDeprecatedTypeAlias,
|
||||
rules::numpy::rules::NumpyLegacyRandom,
|
||||
// ruff
|
||||
rules::ruff::rules::AmbiguousUnicodeCharacterString,
|
||||
rules::ruff::rules::AmbiguousUnicodeCharacterDocstring,
|
||||
rules::ruff::rules::AmbiguousUnicodeCharacterComment,
|
||||
rules::ruff::rules::CollectionLiteralConcatenation,
|
||||
rules::ruff::rules::AsyncioDanglingTask,
|
||||
rules::ruff::rules::UnusedNOQA,
|
||||
rules::ruff::rules::PairwiseOverZipped,
|
||||
rules::ruff::rules::MutableDataclassDefault,
|
||||
rules::ruff::rules::FunctionCallInDataclassDefaultArgument,
|
||||
rules::ruff::rules::ExplicitFStringTypeConversion,
|
||||
rules::ruff::rules::InvalidPyprojectToml,
|
||||
// flake8-django
|
||||
rules::flake8_django::rules::DjangoNullableModelStringField,
|
||||
rules::flake8_django::rules::DjangoLocalsInRenderFunction,
|
||||
rules::flake8_django::rules::DjangoExcludeWithModelForm,
|
||||
rules::flake8_django::rules::DjangoAllWithModelForm,
|
||||
rules::flake8_django::rules::DjangoModelWithoutDunderStr,
|
||||
rules::flake8_django::rules::DjangoUnorderedBodyContentInModel,
|
||||
rules::flake8_django::rules::DjangoNonLeadingReceiverDecorator,
|
||||
// flynt
|
||||
rules::flynt::rules::StaticJoinToFString,
|
||||
// flake8-todo
|
||||
rules::flake8_todos::rules::InvalidTodoTag,
|
||||
rules::flake8_todos::rules::MissingTodoAuthor,
|
||||
rules::flake8_todos::rules::MissingTodoLink,
|
||||
rules::flake8_todos::rules::MissingTodoColon,
|
||||
rules::flake8_todos::rules::MissingTodoDescription,
|
||||
rules::flake8_todos::rules::InvalidTodoCapitalization,
|
||||
rules::flake8_todos::rules::MissingSpaceAfterTodoColon,
|
||||
// airflow
|
||||
rules::airflow::rules::AirflowVariableNameTaskIdMismatch,
|
||||
// flake8-fixme
|
||||
rules::flake8_fixme::rules::LineContainsTodo,
|
||||
rules::flake8_fixme::rules::LineContainsHack,
|
||||
rules::flake8_fixme::rules::LineContainsXxx,
|
||||
rules::flake8_fixme::rules::LineContainsFixme,
|
||||
);
|
||||
|
||||
pub trait AsRule {
|
||||
fn rule(&self) -> Rule;
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ impl RuleSet {
|
|||
///
|
||||
/// let iter: Vec<_> = set.iter().collect();
|
||||
///
|
||||
/// assert_eq!(iter, vec![Rule::AmbiguousFunctionName, Rule::AnyType]);
|
||||
/// assert_eq!(iter, vec![Rule::AnyType, Rule::AmbiguousFunctionName]);
|
||||
/// ```
|
||||
pub fn iter(&self) -> RuleSetIterator {
|
||||
RuleSetIterator {
|
||||
|
|
|
@ -6,7 +6,8 @@ use strum::IntoEnumIterator;
|
|||
use strum_macros::EnumIter;
|
||||
|
||||
use crate::codes::RuleCodePrefix;
|
||||
use crate::registry::{Linter, Rule, RuleIter, RuleNamespace};
|
||||
use crate::codes::RuleIter;
|
||||
use crate::registry::{Linter, Rule, RuleNamespace};
|
||||
use crate::rule_redirects::get_redirect;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -11,7 +11,6 @@ mod config;
|
|||
mod derive_message_formats;
|
||||
mod map_codes;
|
||||
mod newtype_index;
|
||||
mod register_rules;
|
||||
mod rule_code_prefix;
|
||||
mod rule_namespace;
|
||||
mod violation;
|
||||
|
@ -44,12 +43,6 @@ pub fn cache_key(input: TokenStream) -> TokenStream {
|
|||
TokenStream::from(stream)
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
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.
|
||||
#[proc_macro_attribute]
|
||||
pub fn violation(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
|
|
@ -10,61 +10,59 @@ use syn::{
|
|||
|
||||
use crate::rule_code_prefix::{get_prefix_ident, if_all_same, is_nursery};
|
||||
|
||||
struct LinterToRuleData {
|
||||
/// The rule identifier, e.g., `Rule::UnaryPrefixIncrement`.
|
||||
rule_id: Path,
|
||||
/// The rule group identifiers, e.g., `RuleGroup::Unspecified`.
|
||||
rule_group_id: Path,
|
||||
/// The rule attributes.
|
||||
/// A rule entry in the big match statement such a
|
||||
/// `(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),`
|
||||
#[derive(Clone)]
|
||||
struct Rule {
|
||||
/// The actual name of the rule, e.g., `NoIndentedBlock`.
|
||||
name: Ident,
|
||||
/// The linter associated with the rule, e.g., `Pycodestyle`.
|
||||
linter: Ident,
|
||||
/// The code associated with the rule, e.g., `"E112"`.
|
||||
code: LitStr,
|
||||
/// The rule group identifier, e.g., `RuleGroup::Nursery`.
|
||||
group: Path,
|
||||
/// The path to the struct implementing the rule, e.g.
|
||||
/// `rules::pycodestyle::rules::logical_lines::NoIndentedBlock`
|
||||
path: Path,
|
||||
/// The rule attributes, e.g. for feature gates
|
||||
attrs: Vec<Attribute>,
|
||||
}
|
||||
|
||||
struct RuleToLinterData<'a> {
|
||||
/// The linter associated with the rule, e.g., `Flake8Bugbear`.
|
||||
linter: &'a Ident,
|
||||
/// The code associated with the rule, e.g., `"002"`.
|
||||
code: &'a str,
|
||||
/// The rule group identifier, e.g., `RuleGroup::Unspecified`.
|
||||
rule_group_id: &'a Path,
|
||||
/// The rule attributes.
|
||||
attrs: &'a [Attribute],
|
||||
}
|
||||
|
||||
pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
||||
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 (..) { .. })`"))
|
||||
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 (..) { .. })`"));
|
||||
};
|
||||
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 (..) { .. })`"));
|
||||
};
|
||||
|
||||
// Map from: linter (e.g., `Flake8Bugbear`) to rule code (e.g.,`"002"`) to rule data (e.g.,
|
||||
// `(Rule::UnaryPrefixIncrement, RuleGroup::Unspecified, vec![])`).
|
||||
let mut linter_to_rules: BTreeMap<Ident, BTreeMap<String, LinterToRuleData>> = BTreeMap::new();
|
||||
let mut linter_to_rules: BTreeMap<Ident, BTreeMap<String, Rule>> = BTreeMap::new();
|
||||
|
||||
for arm in arms {
|
||||
if matches!(arm.pat, Pat::Wild(..)) {
|
||||
break;
|
||||
}
|
||||
|
||||
let entry = syn::parse::<Entry>(arm.into_token_stream().into())?;
|
||||
linter_to_rules.entry(entry.linter).or_default().insert(
|
||||
entry.code.value(),
|
||||
LinterToRuleData {
|
||||
rule_id: entry.rule,
|
||||
rule_group_id: entry.group,
|
||||
attrs: entry.attrs,
|
||||
},
|
||||
);
|
||||
let rule = syn::parse::<Rule>(arm.into_token_stream().into())?;
|
||||
linter_to_rules
|
||||
.entry(rule.linter.clone())
|
||||
.or_default()
|
||||
.insert(rule.code.value(), rule);
|
||||
}
|
||||
|
||||
let linter_idents: Vec<_> = linter_to_rules.keys().collect();
|
||||
|
||||
let mut output = quote! {
|
||||
let all_rules = linter_to_rules.values().flat_map(BTreeMap::values);
|
||||
let mut output = register_rules(all_rules);
|
||||
|
||||
output.extend(quote! {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum RuleCodePrefix {
|
||||
#(#linter_idents(#linter_idents),)*
|
||||
|
@ -83,21 +81,14 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
for (linter, rules) in &linter_to_rules {
|
||||
output.extend(super::rule_code_prefix::expand(
|
||||
linter,
|
||||
rules.iter().map(
|
||||
|(
|
||||
code,
|
||||
LinterToRuleData {
|
||||
rule_group_id,
|
||||
attrs,
|
||||
..
|
||||
},
|
||||
)| (code.as_str(), rule_group_id, attrs),
|
||||
),
|
||||
rules
|
||||
.iter()
|
||||
.map(|(code, Rule { group, attrs, .. })| (code.as_str(), group, attrs)),
|
||||
));
|
||||
|
||||
output.extend(quote! {
|
||||
|
@ -117,56 +108,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
|||
let mut all_codes = Vec::new();
|
||||
|
||||
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,
|
||||
LinterToRuleData {
|
||||
rule_id,
|
||||
rule_group_id,
|
||||
attrs,
|
||||
},
|
||||
) in rules
|
||||
{
|
||||
// Nursery rules have to be explicitly selected, so we ignore them when looking at
|
||||
// prefixes.
|
||||
if is_nursery(rule_group_id) {
|
||||
rules_by_prefix.insert(code.clone(), vec![(rule_id.clone(), attrs.clone())]);
|
||||
continue;
|
||||
}
|
||||
|
||||
for i in 1..=code.len() {
|
||||
let prefix = code[..i].to_string();
|
||||
let rules: Vec<_> = rules
|
||||
.iter()
|
||||
.filter_map(
|
||||
|(
|
||||
code,
|
||||
LinterToRuleData {
|
||||
rule_id,
|
||||
rule_group_id,
|
||||
attrs,
|
||||
},
|
||||
)| {
|
||||
// Nursery rules have to be explicitly selected, so we ignore them when
|
||||
// looking at prefixes.
|
||||
if is_nursery(rule_group_id) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if code.starts_with(&prefix) {
|
||||
Some((rule_id.clone(), attrs.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
)
|
||||
.collect();
|
||||
rules_by_prefix.insert(prefix, rules);
|
||||
}
|
||||
}
|
||||
let rules_by_prefix = rules_by_prefix(rules);
|
||||
|
||||
for (prefix, rules) in &rules_by_prefix {
|
||||
let prefix_ident = get_prefix_ident(prefix);
|
||||
|
@ -182,9 +124,10 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
|||
let mut prefix_into_iter_match_arms = quote!();
|
||||
|
||||
for (prefix, rules) in rules_by_prefix {
|
||||
let rule_paths = rules
|
||||
.iter()
|
||||
.map(|(path, .., attrs)| quote!(#(#attrs)* #path));
|
||||
let rule_paths = rules.iter().map(|(path, .., attrs)| {
|
||||
let rule_name = path.segments.last().unwrap();
|
||||
quote!(#(#attrs)* Rule::#rule_name)
|
||||
});
|
||||
let prefix_ident = get_prefix_ident(&prefix);
|
||||
let attr = match if_all_same(rules.iter().map(|(.., attrs)| attrs)) {
|
||||
Some(attr) => quote!(#(#attr)*),
|
||||
|
@ -232,35 +175,71 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
|||
}
|
||||
});
|
||||
|
||||
// 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.
|
||||
let mut rule_to_codes: HashMap<&Path, Vec<RuleToLinterData>> = HashMap::new();
|
||||
let rule_to_code = generate_rule_to_code(&linter_to_rules);
|
||||
output.extend(rule_to_code);
|
||||
|
||||
let iter = generate_iter_impl(&linter_to_rules, &all_codes);
|
||||
output.extend(iter);
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
/// Group the rules by their common prefixes.
|
||||
fn rules_by_prefix(
|
||||
rules: &BTreeMap<String, Rule>,
|
||||
) -> BTreeMap<String, Vec<(Path, Vec<Attribute>)>> {
|
||||
// TODO(charlie): Why do we do this here _and_ in `rule_code_prefix::expand`?
|
||||
let mut rules_by_prefix = BTreeMap::new();
|
||||
|
||||
for (code, rule) in rules {
|
||||
// Nursery rules have to be explicitly selected, so we ignore them when looking at
|
||||
// prefixes.
|
||||
if is_nursery(&rule.group) {
|
||||
rules_by_prefix.insert(code.clone(), vec![(rule.path.clone(), rule.attrs.clone())]);
|
||||
continue;
|
||||
}
|
||||
|
||||
for i in 1..=code.len() {
|
||||
let prefix = code[..i].to_string();
|
||||
let rules: Vec<_> = rules
|
||||
.iter()
|
||||
.filter_map(|(code, rule)| {
|
||||
// Nursery rules have to be explicitly selected, so we ignore them when
|
||||
// looking at prefixes.
|
||||
if is_nursery(&rule.group) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if code.starts_with(&prefix) {
|
||||
Some((rule.path.clone(), rule.attrs.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
rules_by_prefix.insert(prefix, rules);
|
||||
}
|
||||
}
|
||||
rules_by_prefix
|
||||
}
|
||||
|
||||
/// 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.
|
||||
fn generate_rule_to_code(linter_to_rules: &BTreeMap<Ident, BTreeMap<String, Rule>>) -> TokenStream {
|
||||
let mut rule_to_codes: HashMap<&Path, Vec<&Rule>> = HashMap::new();
|
||||
let mut linter_code_for_rule_match_arms = quote!();
|
||||
|
||||
for (linter, map) in &linter_to_rules {
|
||||
for (
|
||||
code,
|
||||
LinterToRuleData {
|
||||
rule_id,
|
||||
rule_group_id,
|
||||
attrs,
|
||||
},
|
||||
) in map
|
||||
{
|
||||
rule_to_codes
|
||||
.entry(rule_id)
|
||||
.or_default()
|
||||
.push(RuleToLinterData {
|
||||
linter,
|
||||
code,
|
||||
rule_group_id,
|
||||
attrs,
|
||||
});
|
||||
for (linter, map) in linter_to_rules {
|
||||
for (code, rule) in map {
|
||||
let Rule {
|
||||
path, attrs, name, ..
|
||||
} = rule;
|
||||
rule_to_codes.entry(path).or_default().push(rule);
|
||||
linter_code_for_rule_match_arms.extend(quote! {
|
||||
#(#attrs)* (Self::#linter, #rule_id) => Some(#code),
|
||||
#(#attrs)* (Self::#linter, Rule::#name) => Some(#code),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +248,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
|||
let mut rule_group_match_arms = quote!();
|
||||
|
||||
for (rule, codes) in rule_to_codes {
|
||||
let rule_name = rule.segments.last().unwrap();
|
||||
assert_eq!(
|
||||
codes.len(),
|
||||
1,
|
||||
|
@ -284,30 +264,31 @@ and before we can do that we have to rename all our rules to match our naming co
|
|||
|
||||
See also https://github.com/charliermarsh/ruff/issues/2186.
|
||||
",
|
||||
rule.segments.last().unwrap().ident
|
||||
rule_name.ident
|
||||
);
|
||||
|
||||
let RuleToLinterData {
|
||||
let Rule {
|
||||
linter,
|
||||
code,
|
||||
rule_group_id,
|
||||
group,
|
||||
attrs,
|
||||
..
|
||||
} = codes
|
||||
.iter()
|
||||
.sorted_by_key(|data| *data.linter == "Pylint")
|
||||
.sorted_by_key(|data| data.linter == "Pylint")
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
rule_noqa_code_match_arms.extend(quote! {
|
||||
#(#attrs)* #rule => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code),
|
||||
#(#attrs)* Rule::#rule_name => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code),
|
||||
});
|
||||
|
||||
rule_group_match_arms.extend(quote! {
|
||||
#(#attrs)* #rule => #rule_group_id,
|
||||
#(#attrs)* Rule::#rule_name => #group,
|
||||
});
|
||||
}
|
||||
|
||||
output.extend(quote! {
|
||||
let rule_to_code = quote! {
|
||||
impl Rule {
|
||||
pub fn noqa_code(&self) -> NoqaCode {
|
||||
use crate::registry::RuleNamespace;
|
||||
|
@ -338,19 +319,27 @@ See also https://github.com/charliermarsh/ruff/issues/2186.
|
|||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
rule_to_code
|
||||
}
|
||||
|
||||
/// Implement `impl IntoIterator for &Linter` and `RuleCodePrefix::iter()`
|
||||
fn generate_iter_impl(
|
||||
linter_to_rules: &BTreeMap<Ident, BTreeMap<String, Rule>>,
|
||||
all_codes: &[TokenStream],
|
||||
) -> TokenStream {
|
||||
let mut linter_into_iter_match_arms = quote!();
|
||||
for (linter, map) in &linter_to_rules {
|
||||
let rule_paths = map
|
||||
.values()
|
||||
.map(|LinterToRuleData { rule_id, attrs, .. }| quote!(#(#attrs)* #rule_id));
|
||||
for (linter, map) in linter_to_rules {
|
||||
let rule_paths = map.values().map(|Rule { attrs, path, .. }| {
|
||||
let rule_name = path.segments.last().unwrap();
|
||||
quote!(#(#attrs)* Rule::#rule_name)
|
||||
});
|
||||
linter_into_iter_match_arms.extend(quote! {
|
||||
Linter::#linter => vec![#(#rule_paths,)*].into_iter(),
|
||||
});
|
||||
}
|
||||
|
||||
output.extend(quote! {
|
||||
quote! {
|
||||
impl IntoIterator for &Linter {
|
||||
type Item = Rule;
|
||||
type IntoIter = ::std::vec::IntoIter<Self::Item>;
|
||||
|
@ -362,29 +351,94 @@ See also https://github.com/charliermarsh/ruff/issues/2186.
|
|||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
output.extend(quote! {
|
||||
impl RuleCodePrefix {
|
||||
pub fn iter() -> ::std::vec::IntoIter<RuleCodePrefix> {
|
||||
vec![ #(#all_codes,)* ].into_iter()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
linter: Ident,
|
||||
code: LitStr,
|
||||
group: Path,
|
||||
rule: Path,
|
||||
attrs: Vec<Attribute>,
|
||||
/// Generate the `Rule` enum
|
||||
fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {
|
||||
let mut rule_variants = quote!();
|
||||
let mut rule_message_formats_match_arms = quote!();
|
||||
let mut rule_autofixable_match_arms = quote!();
|
||||
let mut rule_explanation_match_arms = quote!();
|
||||
|
||||
let mut from_impls_for_diagnostic_kind = quote!();
|
||||
|
||||
for Rule {
|
||||
name, attrs, path, ..
|
||||
} in input
|
||||
{
|
||||
rule_variants.extend(quote! {
|
||||
#(#attrs)*
|
||||
#name,
|
||||
});
|
||||
// Apply the `attrs` to each arm, like `[cfg(feature = "foo")]`.
|
||||
rule_message_formats_match_arms
|
||||
.extend(quote! {#(#attrs)* Self::#name => <#path as ruff_diagnostics::Violation>::message_formats(),});
|
||||
rule_autofixable_match_arms.extend(
|
||||
quote! {#(#attrs)* Self::#name => <#path as ruff_diagnostics::Violation>::AUTOFIX,},
|
||||
);
|
||||
rule_explanation_match_arms
|
||||
.extend(quote! {#(#attrs)* Self::#name => #path::explanation(),});
|
||||
|
||||
// Enable conversion from `DiagnosticKind` to `Rule`.
|
||||
from_impls_for_diagnostic_kind
|
||||
.extend(quote! {#(#attrs)* stringify!(#name) => Rule::#name,});
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[derive(
|
||||
EnumIter,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Copy,
|
||||
Clone,
|
||||
Hash,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
::ruff_macros::CacheKey,
|
||||
AsRefStr,
|
||||
::strum_macros::IntoStaticStr,
|
||||
)]
|
||||
#[repr(u16)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Rule { #rule_variants }
|
||||
|
||||
impl Rule {
|
||||
/// Returns the format strings used to report violations of this rule.
|
||||
pub fn message_formats(&self) -> &'static [&'static str] {
|
||||
match self { #rule_message_formats_match_arms }
|
||||
}
|
||||
|
||||
/// Returns the documentation for this rule.
|
||||
pub fn explanation(&self) -> Option<&'static str> {
|
||||
match self { #rule_explanation_match_arms }
|
||||
}
|
||||
|
||||
/// Returns the autofix status of this rule.
|
||||
pub const fn autofixable(&self) -> ruff_diagnostics::AutofixKind {
|
||||
match self { #rule_autofixable_match_arms }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRule for ruff_diagnostics::DiagnosticKind {
|
||||
fn rule(&self) -> Rule {
|
||||
match self.name.as_str() {
|
||||
#from_impls_for_diagnostic_kind
|
||||
_ => unreachable!("invalid rule name: {}", self.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Entry {
|
||||
/// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Nursery, Rule::NoIndentedBlock),`
|
||||
impl Parse for Rule {
|
||||
/// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),`
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let attrs = Attribute::parse_outer(input)?;
|
||||
let pat_tuple;
|
||||
|
@ -397,13 +451,15 @@ impl Parse for Entry {
|
|||
parenthesized!(pat_tuple in input);
|
||||
let group: Path = pat_tuple.parse()?;
|
||||
let _: Token!(,) = pat_tuple.parse()?;
|
||||
let rule: Path = pat_tuple.parse()?;
|
||||
let rule_path: Path = pat_tuple.parse()?;
|
||||
let _: Token!(,) = input.parse()?;
|
||||
Ok(Entry {
|
||||
let rule_name = rule_path.segments.last().unwrap().ident.clone();
|
||||
Ok(Rule {
|
||||
name: rule_name,
|
||||
linter,
|
||||
code,
|
||||
group,
|
||||
rule,
|
||||
path: rule_path,
|
||||
attrs,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
use quote::quote;
|
||||
use syn::parse::Parse;
|
||||
use syn::{Attribute, Ident, Path, Token};
|
||||
|
||||
pub(crate) fn register_rules(input: &Input) -> proc_macro2::TokenStream {
|
||||
let mut rule_variants = quote!();
|
||||
let mut rule_message_formats_match_arms = quote!();
|
||||
let mut rule_autofixable_match_arms = quote!();
|
||||
let mut rule_explanation_match_arms = quote!();
|
||||
|
||||
let mut from_impls_for_diagnostic_kind = quote!();
|
||||
|
||||
for (path, name, attr) in &input.entries {
|
||||
rule_variants.extend(quote! {
|
||||
#(#attr)*
|
||||
#name,
|
||||
});
|
||||
// Apply the `attrs` to each arm, like `[cfg(feature = "foo")]`.
|
||||
rule_message_formats_match_arms
|
||||
.extend(quote! {#(#attr)* Self::#name => <#path as ruff_diagnostics::Violation>::message_formats(),});
|
||||
rule_autofixable_match_arms.extend(
|
||||
quote! {#(#attr)* Self::#name => <#path as ruff_diagnostics::Violation>::AUTOFIX,},
|
||||
);
|
||||
rule_explanation_match_arms.extend(quote! {#(#attr)* Self::#name => #path::explanation(),});
|
||||
|
||||
// Enable conversion from `DiagnosticKind` to `Rule`.
|
||||
from_impls_for_diagnostic_kind.extend(quote! {#(#attr)* stringify!(#name) => Rule::#name,});
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[derive(
|
||||
EnumIter,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Copy,
|
||||
Clone,
|
||||
Hash,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
::ruff_macros::CacheKey,
|
||||
AsRefStr,
|
||||
::strum_macros::IntoStaticStr,
|
||||
)]
|
||||
#[repr(u16)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Rule { #rule_variants }
|
||||
|
||||
impl Rule {
|
||||
/// Returns the format strings used to report violations of this rule.
|
||||
pub fn message_formats(&self) -> &'static [&'static str] {
|
||||
match self { #rule_message_formats_match_arms }
|
||||
}
|
||||
|
||||
/// Returns the documentation for this rule.
|
||||
pub fn explanation(&self) -> Option<&'static str> {
|
||||
match self { #rule_explanation_match_arms }
|
||||
}
|
||||
|
||||
/// Returns the autofix status of this rule.
|
||||
pub const fn autofixable(&self) -> ruff_diagnostics::AutofixKind {
|
||||
match self { #rule_autofixable_match_arms }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRule for ruff_diagnostics::DiagnosticKind {
|
||||
fn rule(&self) -> Rule {
|
||||
match self.name.as_str() {
|
||||
#from_impls_for_diagnostic_kind
|
||||
_ => unreachable!("invalid rule name: {}", self.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Input {
|
||||
entries: Vec<(Path, Ident, Vec<Attribute>)>,
|
||||
}
|
||||
|
||||
impl Parse for Input {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let mut entries = Vec::new();
|
||||
while !input.is_empty() {
|
||||
// Grab the `#[cfg(...)]` attributes.
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
|
||||
let path: Path = input.parse()?;
|
||||
let name = path.segments.last().unwrap().ident.clone();
|
||||
let _: Token![,] = input.parse()?;
|
||||
entries.push((path, name, attrs));
|
||||
}
|
||||
Ok(Self { entries })
|
||||
}
|
||||
}
|
|
@ -103,8 +103,7 @@ pub struct {name};
|
|||
impl Violation for {name} {{
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {{
|
||||
todo!("implement message");
|
||||
format!("TODO: write message")
|
||||
format!("TODO: write message: {{}}", todo!("implement message"))
|
||||
}}
|
||||
}}
|
||||
""",
|
||||
|
@ -116,56 +115,6 @@ pub(crate) fn {rule_name_snake}(checker: &mut Checker) {{}}
|
|||
""",
|
||||
)
|
||||
|
||||
# Add the relevant code-to-violation pair to `src/registry.rs`.
|
||||
content = (ROOT_DIR / "crates/ruff/src/registry.rs").read_text()
|
||||
|
||||
seen_macro = False
|
||||
has_written = False
|
||||
has_seen_linter = False
|
||||
with (ROOT_DIR / "crates/ruff/src/registry.rs").open("w") as fp:
|
||||
lines = []
|
||||
for line in content.splitlines():
|
||||
if has_written:
|
||||
fp.write(line)
|
||||
fp.write("\n")
|
||||
continue
|
||||
|
||||
if line.startswith("ruff_macros::register_rules!"):
|
||||
seen_macro = True
|
||||
fp.write(line)
|
||||
fp.write("\n")
|
||||
continue
|
||||
|
||||
if not seen_macro:
|
||||
fp.write(line)
|
||||
fp.write("\n")
|
||||
continue
|
||||
|
||||
if line.strip() == f"// {linter}":
|
||||
indent = get_indent(line)
|
||||
lines.append(f"{indent}rules::{dir_name(linter)}::rules::{name},")
|
||||
has_seen_linter = True
|
||||
fp.write(line)
|
||||
fp.write("\n")
|
||||
continue
|
||||
|
||||
if not has_seen_linter:
|
||||
fp.write(line)
|
||||
fp.write("\n")
|
||||
continue
|
||||
|
||||
if not line.strip().startswith("// "):
|
||||
lines.append(line)
|
||||
else:
|
||||
lines.sort()
|
||||
fp.write("\n".join(lines))
|
||||
fp.write("\n")
|
||||
fp.write(line)
|
||||
fp.write("\n")
|
||||
has_written = True
|
||||
|
||||
assert has_written
|
||||
|
||||
text = ""
|
||||
with (ROOT_DIR / "crates/ruff/src/codes.rs").open("r") as fp:
|
||||
while (line := next(fp)).strip() != f"// {linter}":
|
||||
|
@ -177,17 +126,15 @@ pub(crate) fn {rule_name_snake}(checker: &mut Checker) {{}}
|
|||
lines.append(line)
|
||||
|
||||
variant = pascal_case(linter)
|
||||
rule = f"""rules::{linter.split(" ")[0]}::rules::{name}"""
|
||||
lines.append(
|
||||
" " * 8
|
||||
+ f"""({variant}, "{code}") => (RuleGroup::Unspecified, Rule::{name}),\n""",
|
||||
+ f"""({variant}, "{code}") => (RuleGroup::Unspecified, {rule}),\n""",
|
||||
)
|
||||
lines.sort()
|
||||
|
||||
text += "".join(lines)
|
||||
text += "\n"
|
||||
|
||||
text += fp.read()
|
||||
|
||||
with (ROOT_DIR / "crates/ruff/src/codes.rs").open("w") as fp:
|
||||
fp.write(text)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue