mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
Avoid generating diagnostics with per-file ignores (#18801)
## Summary This PR avoids one of the three calls to `NoqaCode::rule` from https://github.com/astral-sh/ruff/pull/18391 by applying per-file ignores in the `LintContext`. To help with this, it also replaces all direct uses of `LinterSettings.rules.enabled` with a `LintContext::enabled` (or `Checker::enabled`, which defers to its context) method. There are still some direct accesses to `settings.rules`, but as far as I can tell these are not in a part of the code where we can really access a `LintContext`. I believe all of the code reachable from `check_path`, where the replaced per-file ignore code was, should be converted to the new methods. ## Test Plan Existing tests, with a single snapshot updated for RUF100, which I think actually shows a more accurate diagnostic message now.
This commit is contained in:
parent
ffb09c84f2
commit
8cff77c82e
65 changed files with 1138 additions and 1167 deletions
|
@ -10,7 +10,7 @@ use crate::rules::{
|
|||
|
||||
/// Run lint rules over the [`Binding`]s.
|
||||
pub(crate) fn bindings(checker: &Checker) {
|
||||
if !checker.any_enabled(&[
|
||||
if !checker.any_rule_enabled(&[
|
||||
Rule::AssignmentInAssert,
|
||||
Rule::InvalidAllFormat,
|
||||
Rule::InvalidAllObject,
|
||||
|
@ -30,7 +30,7 @@ pub(crate) fn bindings(checker: &Checker) {
|
|||
}
|
||||
|
||||
for (binding_id, binding) in checker.semantic.bindings.iter_enumerated() {
|
||||
if checker.enabled(Rule::UnusedVariable) {
|
||||
if checker.is_rule_enabled(Rule::UnusedVariable) {
|
||||
if binding.kind.is_bound_exception()
|
||||
&& binding.is_unused()
|
||||
&& !checker
|
||||
|
@ -54,47 +54,47 @@ pub(crate) fn bindings(checker: &Checker) {
|
|||
});
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::InvalidAllFormat) {
|
||||
if checker.is_rule_enabled(Rule::InvalidAllFormat) {
|
||||
pylint::rules::invalid_all_format(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidAllObject) {
|
||||
if checker.is_rule_enabled(Rule::InvalidAllObject) {
|
||||
pylint::rules::invalid_all_object(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::NonAsciiName) {
|
||||
if checker.is_rule_enabled(Rule::NonAsciiName) {
|
||||
pylint::rules::non_ascii_name(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::UnconventionalImportAlias) {
|
||||
if checker.is_rule_enabled(Rule::UnconventionalImportAlias) {
|
||||
flake8_import_conventions::rules::unconventional_import_alias(
|
||||
checker,
|
||||
binding,
|
||||
&checker.settings.flake8_import_conventions.aliases,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::UnaliasedCollectionsAbcSetImport) {
|
||||
if checker.is_rule_enabled(Rule::UnaliasedCollectionsAbcSetImport) {
|
||||
flake8_pyi::rules::unaliased_collections_abc_set_import(checker, binding);
|
||||
}
|
||||
if !checker.source_type.is_stub() && checker.enabled(Rule::UnquotedTypeAlias) {
|
||||
if !checker.source_type.is_stub() && checker.is_rule_enabled(Rule::UnquotedTypeAlias) {
|
||||
flake8_type_checking::rules::unquoted_type_alias(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::UnsortedDunderSlots) {
|
||||
if checker.is_rule_enabled(Rule::UnsortedDunderSlots) {
|
||||
ruff::rules::sort_dunder_slots(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::UsedDummyVariable) {
|
||||
if checker.is_rule_enabled(Rule::UsedDummyVariable) {
|
||||
ruff::rules::used_dummy_variable(checker, binding, binding_id);
|
||||
}
|
||||
if checker.enabled(Rule::AssignmentInAssert) {
|
||||
if checker.is_rule_enabled(Rule::AssignmentInAssert) {
|
||||
ruff::rules::assignment_in_assert(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::PytestUnittestRaisesAssertion) {
|
||||
if checker.is_rule_enabled(Rule::PytestUnittestRaisesAssertion) {
|
||||
flake8_pytest_style::rules::unittest_raises_assertion_binding(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::ForLoopWrites) {
|
||||
if checker.is_rule_enabled(Rule::ForLoopWrites) {
|
||||
refurb::rules::for_loop_writes_binding(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::CustomTypeVarForSelf) {
|
||||
if checker.is_rule_enabled(Rule::CustomTypeVarForSelf) {
|
||||
flake8_pyi::rules::custom_type_var_instead_of_self(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::PrivateTypeParameter) {
|
||||
if checker.is_rule_enabled(Rule::PrivateTypeParameter) {
|
||||
pyupgrade::rules::private_type_parameter(checker, binding);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ use crate::rules::{flake8_simplify, refurb};
|
|||
|
||||
/// Run lint rules over a [`Comprehension`] syntax nodes.
|
||||
pub(crate) fn comprehension(comprehension: &Comprehension, checker: &Checker) {
|
||||
if checker.enabled(Rule::InDictKeys) {
|
||||
if checker.is_rule_enabled(Rule::InDictKeys) {
|
||||
flake8_simplify::rules::key_in_dict_comprehension(checker, comprehension);
|
||||
}
|
||||
if checker.enabled(Rule::ReadlinesInFor) {
|
||||
if checker.is_rule_enabled(Rule::ReadlinesInFor) {
|
||||
refurb::rules::readlines_in_comprehension(checker, comprehension);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,31 +14,31 @@ pub(crate) fn deferred_for_loops(checker: &mut Checker) {
|
|||
let Stmt::For(stmt_for) = checker.semantic.current_statement() else {
|
||||
unreachable!("Expected Stmt::For");
|
||||
};
|
||||
if checker.enabled(Rule::UnusedLoopControlVariable) {
|
||||
if checker.is_rule_enabled(Rule::UnusedLoopControlVariable) {
|
||||
flake8_bugbear::rules::unused_loop_control_variable(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::IncorrectDictIterator) {
|
||||
if checker.is_rule_enabled(Rule::IncorrectDictIterator) {
|
||||
perflint::rules::incorrect_dict_iterator(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::YieldInForLoop) {
|
||||
if checker.is_rule_enabled(Rule::YieldInForLoop) {
|
||||
pyupgrade::rules::yield_in_for_loop(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::UnnecessaryEnumerate) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryEnumerate) {
|
||||
refurb::rules::unnecessary_enumerate(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::EnumerateForLoop) {
|
||||
if checker.is_rule_enabled(Rule::EnumerateForLoop) {
|
||||
flake8_simplify::rules::enumerate_for_loop(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::LoopIteratorMutation) {
|
||||
if checker.is_rule_enabled(Rule::LoopIteratorMutation) {
|
||||
flake8_bugbear::rules::loop_iterator_mutation(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::DictIndexMissingItems) {
|
||||
if checker.is_rule_enabled(Rule::DictIndexMissingItems) {
|
||||
pylint::rules::dict_index_missing_items(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::ManualDictComprehension) {
|
||||
if checker.is_rule_enabled(Rule::ManualDictComprehension) {
|
||||
perflint::rules::manual_dict_comprehension(checker, stmt_for);
|
||||
}
|
||||
if checker.enabled(Rule::ManualListComprehension) {
|
||||
if checker.is_rule_enabled(Rule::ManualListComprehension) {
|
||||
perflint::rules::manual_list_comprehension(checker, stmt_for);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ pub(crate) fn deferred_lambdas(checker: &mut Checker) {
|
|||
unreachable!("Expected Expr::Lambda");
|
||||
};
|
||||
|
||||
if checker.enabled(Rule::UnnecessaryLambda) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryLambda) {
|
||||
pylint::rules::unnecessary_lambda(checker, lambda);
|
||||
}
|
||||
if checker.enabled(Rule::ReimplementedContainerBuiltin) {
|
||||
if checker.is_rule_enabled(Rule::ReimplementedContainerBuiltin) {
|
||||
flake8_pie::rules::reimplemented_container_builtin(checker, lambda);
|
||||
}
|
||||
if checker.enabled(Rule::BuiltinLambdaArgumentShadowing) {
|
||||
if checker.is_rule_enabled(Rule::BuiltinLambdaArgumentShadowing) {
|
||||
flake8_builtins::rules::builtin_lambda_argument_shadowing(checker, lambda);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::rules::{
|
|||
|
||||
/// Run lint rules over all deferred scopes in the [`SemanticModel`].
|
||||
pub(crate) fn deferred_scopes(checker: &Checker) {
|
||||
if !checker.any_enabled(&[
|
||||
if !checker.any_rule_enabled(&[
|
||||
Rule::AsyncioDanglingTask,
|
||||
Rule::BadStaticmethodArgument,
|
||||
Rule::BuiltinAttributeShadowing,
|
||||
|
@ -58,7 +58,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
// used at runtime, then by default, we avoid flagging any other
|
||||
// imports from that model as typing-only.
|
||||
let enforce_typing_only_imports = !checker.source_type.is_stub()
|
||||
&& checker.any_enabled(&[
|
||||
&& checker.any_rule_enabled(&[
|
||||
Rule::TypingOnlyFirstPartyImport,
|
||||
Rule::TypingOnlyStandardLibraryImport,
|
||||
Rule::TypingOnlyThirdPartyImport,
|
||||
|
@ -89,11 +89,11 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
for scope_id in checker.analyze.scopes.iter().rev().copied() {
|
||||
let scope = &checker.semantic.scopes[scope_id];
|
||||
|
||||
if checker.enabled(Rule::UndefinedLocal) {
|
||||
if checker.is_rule_enabled(Rule::UndefinedLocal) {
|
||||
pyflakes::rules::undefined_local(checker, scope_id, scope);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::GlobalVariableNotAssigned) {
|
||||
if checker.is_rule_enabled(Rule::GlobalVariableNotAssigned) {
|
||||
for (name, binding_id) in scope.bindings() {
|
||||
let binding = checker.semantic.binding(binding_id);
|
||||
// If the binding is a `global`, then it's a top-level `global` that was never
|
||||
|
@ -123,7 +123,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::RedefinedArgumentFromLocal) {
|
||||
if checker.is_rule_enabled(Rule::RedefinedArgumentFromLocal) {
|
||||
for (name, binding_id) in scope.bindings() {
|
||||
for shadow in checker.semantic.shadowed_bindings(scope_id, binding_id) {
|
||||
let binding = &checker.semantic.bindings[shadow.binding_id()];
|
||||
|
@ -156,7 +156,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::ImportShadowedByLoopVar) {
|
||||
if checker.is_rule_enabled(Rule::ImportShadowedByLoopVar) {
|
||||
for (name, binding_id) in scope.bindings() {
|
||||
for shadow in checker.semantic.shadowed_bindings(scope_id, binding_id) {
|
||||
// If the shadowing binding isn't a loop variable, abort.
|
||||
|
@ -197,7 +197,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::RedefinedWhileUnused) {
|
||||
if checker.is_rule_enabled(Rule::RedefinedWhileUnused) {
|
||||
// Index the redefined bindings by statement.
|
||||
let mut redefinitions = FxHashMap::default();
|
||||
|
||||
|
@ -353,43 +353,43 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
if checker.source_type.is_stub()
|
||||
|| matches!(scope.kind, ScopeKind::Module | ScopeKind::Function(_))
|
||||
{
|
||||
if checker.enabled(Rule::UnusedPrivateTypeVar) {
|
||||
if checker.is_rule_enabled(Rule::UnusedPrivateTypeVar) {
|
||||
flake8_pyi::rules::unused_private_type_var(checker, scope);
|
||||
}
|
||||
if checker.enabled(Rule::UnusedPrivateProtocol) {
|
||||
if checker.is_rule_enabled(Rule::UnusedPrivateProtocol) {
|
||||
flake8_pyi::rules::unused_private_protocol(checker, scope);
|
||||
}
|
||||
if checker.enabled(Rule::UnusedPrivateTypeAlias) {
|
||||
if checker.is_rule_enabled(Rule::UnusedPrivateTypeAlias) {
|
||||
flake8_pyi::rules::unused_private_type_alias(checker, scope);
|
||||
}
|
||||
if checker.enabled(Rule::UnusedPrivateTypedDict) {
|
||||
if checker.is_rule_enabled(Rule::UnusedPrivateTypedDict) {
|
||||
flake8_pyi::rules::unused_private_typed_dict(checker, scope);
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::AsyncioDanglingTask) {
|
||||
if checker.is_rule_enabled(Rule::AsyncioDanglingTask) {
|
||||
ruff::rules::asyncio_dangling_binding(scope, checker);
|
||||
}
|
||||
|
||||
if let Some(class_def) = scope.kind.as_class() {
|
||||
if checker.enabled(Rule::BuiltinAttributeShadowing) {
|
||||
if checker.is_rule_enabled(Rule::BuiltinAttributeShadowing) {
|
||||
flake8_builtins::rules::builtin_attribute_shadowing(
|
||||
checker, scope_id, scope, class_def,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::FunctionCallInDataclassDefaultArgument) {
|
||||
if checker.is_rule_enabled(Rule::FunctionCallInDataclassDefaultArgument) {
|
||||
ruff::rules::function_call_in_dataclass_default(checker, class_def);
|
||||
}
|
||||
if checker.enabled(Rule::MutableClassDefault) {
|
||||
if checker.is_rule_enabled(Rule::MutableClassDefault) {
|
||||
ruff::rules::mutable_class_default(checker, class_def);
|
||||
}
|
||||
if checker.enabled(Rule::MutableDataclassDefault) {
|
||||
if checker.is_rule_enabled(Rule::MutableDataclassDefault) {
|
||||
ruff::rules::mutable_dataclass_default(checker, class_def);
|
||||
}
|
||||
}
|
||||
|
||||
if matches!(scope.kind, ScopeKind::Function(_) | ScopeKind::Lambda(_)) {
|
||||
if checker.any_enabled(&[Rule::UnusedVariable, Rule::UnusedUnpackedVariable])
|
||||
if checker.any_rule_enabled(&[Rule::UnusedVariable, Rule::UnusedUnpackedVariable])
|
||||
&& !(scope.uses_locals() && scope.kind.is_function())
|
||||
{
|
||||
let unused_bindings = scope
|
||||
|
@ -418,22 +418,22 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
});
|
||||
|
||||
for (unused_name, unused_binding) in unused_bindings {
|
||||
if checker.enabled(Rule::UnusedVariable) {
|
||||
if checker.is_rule_enabled(Rule::UnusedVariable) {
|
||||
pyflakes::rules::unused_variable(checker, unused_name, unused_binding);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::UnusedUnpackedVariable) {
|
||||
if checker.is_rule_enabled(Rule::UnusedUnpackedVariable) {
|
||||
ruff::rules::unused_unpacked_variable(checker, unused_name, unused_binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::UnusedAnnotation) {
|
||||
if checker.is_rule_enabled(Rule::UnusedAnnotation) {
|
||||
pyflakes::rules::unused_annotation(checker, scope);
|
||||
}
|
||||
|
||||
if !checker.source_type.is_stub() {
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::UnusedClassMethodArgument,
|
||||
Rule::UnusedFunctionArgument,
|
||||
Rule::UnusedLambdaArgument,
|
||||
|
@ -447,7 +447,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
|
||||
if matches!(scope.kind, ScopeKind::Function(_) | ScopeKind::Module) {
|
||||
if !checker.source_type.is_stub()
|
||||
&& checker.enabled(Rule::RuntimeImportInTypeCheckingBlock)
|
||||
&& checker.is_rule_enabled(Rule::RuntimeImportInTypeCheckingBlock)
|
||||
{
|
||||
flake8_type_checking::rules::runtime_import_in_type_checking_block(checker, scope);
|
||||
}
|
||||
|
@ -467,37 +467,37 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::UnusedImport) {
|
||||
if checker.is_rule_enabled(Rule::UnusedImport) {
|
||||
pyflakes::rules::unused_import(checker, scope);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::ImportPrivateName) {
|
||||
if checker.is_rule_enabled(Rule::ImportPrivateName) {
|
||||
pylint::rules::import_private_name(checker, scope);
|
||||
}
|
||||
}
|
||||
|
||||
if scope.kind.is_function() {
|
||||
if checker.enabled(Rule::NoSelfUse) {
|
||||
if checker.is_rule_enabled(Rule::NoSelfUse) {
|
||||
pylint::rules::no_self_use(checker, scope_id, scope);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::TooManyLocals) {
|
||||
if checker.is_rule_enabled(Rule::TooManyLocals) {
|
||||
pylint::rules::too_many_locals(checker, scope);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::SingledispatchMethod) {
|
||||
if checker.is_rule_enabled(Rule::SingledispatchMethod) {
|
||||
pylint::rules::singledispatch_method(checker, scope);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::SingledispatchmethodFunction) {
|
||||
if checker.is_rule_enabled(Rule::SingledispatchmethodFunction) {
|
||||
pylint::rules::singledispatchmethod_function(checker, scope);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::BadStaticmethodArgument) {
|
||||
if checker.is_rule_enabled(Rule::BadStaticmethodArgument) {
|
||||
pylint::rules::bad_staticmethod_argument(checker, scope);
|
||||
}
|
||||
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::InvalidFirstArgumentNameForClassMethod,
|
||||
Rule::InvalidFirstArgumentNameForMethod,
|
||||
]) {
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::{docstrings, warn_user};
|
|||
/// it is expected that all [`Definition`] nodes have been visited by the time, and that this
|
||||
/// method will not recurse into any other nodes.
|
||||
pub(crate) fn definitions(checker: &mut Checker) {
|
||||
let enforce_annotations = checker.any_enabled(&[
|
||||
let enforce_annotations = checker.any_rule_enabled(&[
|
||||
Rule::AnyType,
|
||||
Rule::MissingReturnTypeClassMethod,
|
||||
Rule::MissingReturnTypePrivateFunction,
|
||||
|
@ -28,10 +28,11 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
Rule::MissingTypeFunctionArgument,
|
||||
Rule::MissingTypeKwargs,
|
||||
]);
|
||||
let enforce_stubs = checker.source_type.is_stub() && checker.enabled(Rule::DocstringInStub);
|
||||
let enforce_stubs_and_runtime = checker.enabled(Rule::IterMethodReturnIterable);
|
||||
let enforce_dunder_method = checker.enabled(Rule::BadDunderMethodName);
|
||||
let enforce_docstrings = checker.any_enabled(&[
|
||||
let enforce_stubs =
|
||||
checker.source_type.is_stub() && checker.is_rule_enabled(Rule::DocstringInStub);
|
||||
let enforce_stubs_and_runtime = checker.is_rule_enabled(Rule::IterMethodReturnIterable);
|
||||
let enforce_dunder_method = checker.is_rule_enabled(Rule::BadDunderMethodName);
|
||||
let enforce_docstrings = checker.any_rule_enabled(&[
|
||||
Rule::MissingBlankLineAfterLastSection,
|
||||
Rule::MissingBlankLineAfterSummary,
|
||||
Rule::BlankLineBeforeClass,
|
||||
|
@ -79,7 +80,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
Rule::UndocumentedPublicNestedClass,
|
||||
Rule::UndocumentedPublicPackage,
|
||||
]);
|
||||
let enforce_pydoclint = checker.any_enabled(&[
|
||||
let enforce_pydoclint = checker.any_rule_enabled(&[
|
||||
Rule::DocstringMissingReturns,
|
||||
Rule::DocstringExtraneousReturns,
|
||||
Rule::DocstringMissingYields,
|
||||
|
@ -202,74 +203,76 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
if !pydocstyle::rules::not_empty(checker, &docstring) {
|
||||
continue;
|
||||
}
|
||||
if checker.enabled(Rule::UnnecessaryMultilineDocstring) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryMultilineDocstring) {
|
||||
pydocstyle::rules::one_liner(checker, &docstring);
|
||||
}
|
||||
if checker.any_enabled(&[Rule::BlankLineAfterFunction, Rule::BlankLineBeforeFunction]) {
|
||||
if checker
|
||||
.any_rule_enabled(&[Rule::BlankLineAfterFunction, Rule::BlankLineBeforeFunction])
|
||||
{
|
||||
pydocstyle::rules::blank_before_after_function(checker, &docstring);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::BlankLineBeforeClass,
|
||||
Rule::IncorrectBlankLineAfterClass,
|
||||
Rule::IncorrectBlankLineBeforeClass,
|
||||
]) {
|
||||
pydocstyle::rules::blank_before_after_class(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::MissingBlankLineAfterSummary) {
|
||||
if checker.is_rule_enabled(Rule::MissingBlankLineAfterSummary) {
|
||||
pydocstyle::rules::blank_after_summary(checker, &docstring);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::DocstringTabIndentation,
|
||||
Rule::OverIndentation,
|
||||
Rule::UnderIndentation,
|
||||
]) {
|
||||
pydocstyle::rules::indent(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::NewLineAfterLastParagraph) {
|
||||
if checker.is_rule_enabled(Rule::NewLineAfterLastParagraph) {
|
||||
pydocstyle::rules::newline_after_last_paragraph(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::SurroundingWhitespace) {
|
||||
if checker.is_rule_enabled(Rule::SurroundingWhitespace) {
|
||||
pydocstyle::rules::no_surrounding_whitespace(checker, &docstring);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::MultiLineSummaryFirstLine,
|
||||
Rule::MultiLineSummarySecondLine,
|
||||
]) {
|
||||
pydocstyle::rules::multi_line_summary_start(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::TripleSingleQuotes) {
|
||||
if checker.is_rule_enabled(Rule::TripleSingleQuotes) {
|
||||
pydocstyle::rules::triple_quotes(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::EscapeSequenceInDocstring) {
|
||||
if checker.is_rule_enabled(Rule::EscapeSequenceInDocstring) {
|
||||
pydocstyle::rules::backslashes(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::MissingTrailingPeriod) {
|
||||
if checker.is_rule_enabled(Rule::MissingTrailingPeriod) {
|
||||
pydocstyle::rules::ends_with_period(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::NonImperativeMood) {
|
||||
if checker.is_rule_enabled(Rule::NonImperativeMood) {
|
||||
pydocstyle::rules::non_imperative_mood(
|
||||
checker,
|
||||
&docstring,
|
||||
&checker.settings.pydocstyle,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::SignatureInDocstring) {
|
||||
if checker.is_rule_enabled(Rule::SignatureInDocstring) {
|
||||
pydocstyle::rules::no_signature(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::FirstWordUncapitalized) {
|
||||
if checker.is_rule_enabled(Rule::FirstWordUncapitalized) {
|
||||
pydocstyle::rules::capitalized(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::DocstringStartsWithThis) {
|
||||
if checker.is_rule_enabled(Rule::DocstringStartsWithThis) {
|
||||
pydocstyle::rules::starts_with_this(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::MissingTerminalPunctuation) {
|
||||
if checker.is_rule_enabled(Rule::MissingTerminalPunctuation) {
|
||||
pydocstyle::rules::ends_with_punctuation(checker, &docstring);
|
||||
}
|
||||
if checker.enabled(Rule::OverloadWithDocstring) {
|
||||
if checker.is_rule_enabled(Rule::OverloadWithDocstring) {
|
||||
pydocstyle::rules::if_needed(checker, &docstring);
|
||||
}
|
||||
|
||||
let enforce_sections = checker.any_enabled(&[
|
||||
let enforce_sections = checker.any_rule_enabled(&[
|
||||
Rule::MissingBlankLineAfterLastSection,
|
||||
Rule::BlankLinesBetweenHeaderAndContent,
|
||||
Rule::NonCapitalizedSectionName,
|
||||
|
|
|
@ -17,17 +17,17 @@ pub(crate) fn except_handler(except_handler: &ExceptHandler, checker: &Checker)
|
|||
range: _,
|
||||
node_index: _,
|
||||
}) => {
|
||||
if checker.enabled(Rule::BareExcept) {
|
||||
if checker.is_rule_enabled(Rule::BareExcept) {
|
||||
pycodestyle::rules::bare_except(checker, type_.as_deref(), body, except_handler);
|
||||
}
|
||||
if checker.enabled(Rule::RaiseWithoutFromInsideExcept) {
|
||||
if checker.is_rule_enabled(Rule::RaiseWithoutFromInsideExcept) {
|
||||
flake8_bugbear::rules::raise_without_from_inside_except(
|
||||
checker,
|
||||
name.as_deref(),
|
||||
body,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::BlindExcept) {
|
||||
if checker.is_rule_enabled(Rule::BlindExcept) {
|
||||
flake8_blind_except::rules::blind_except(
|
||||
checker,
|
||||
type_.as_deref(),
|
||||
|
@ -35,7 +35,7 @@ pub(crate) fn except_handler(except_handler: &ExceptHandler, checker: &Checker)
|
|||
body,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::TryExceptPass) {
|
||||
if checker.is_rule_enabled(Rule::TryExceptPass) {
|
||||
flake8_bandit::rules::try_except_pass(
|
||||
checker,
|
||||
except_handler,
|
||||
|
@ -44,7 +44,7 @@ pub(crate) fn except_handler(except_handler: &ExceptHandler, checker: &Checker)
|
|||
checker.settings.flake8_bandit.check_typed_exception,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::TryExceptContinue) {
|
||||
if checker.is_rule_enabled(Rule::TryExceptContinue) {
|
||||
flake8_bandit::rules::try_except_continue(
|
||||
checker,
|
||||
except_handler,
|
||||
|
@ -53,24 +53,24 @@ pub(crate) fn except_handler(except_handler: &ExceptHandler, checker: &Checker)
|
|||
checker.settings.flake8_bandit.check_typed_exception,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::ExceptWithEmptyTuple) {
|
||||
if checker.is_rule_enabled(Rule::ExceptWithEmptyTuple) {
|
||||
flake8_bugbear::rules::except_with_empty_tuple(checker, except_handler);
|
||||
}
|
||||
if checker.enabled(Rule::ExceptWithNonExceptionClasses) {
|
||||
if checker.is_rule_enabled(Rule::ExceptWithNonExceptionClasses) {
|
||||
flake8_bugbear::rules::except_with_non_exception_classes(checker, except_handler);
|
||||
}
|
||||
if checker.enabled(Rule::BinaryOpException) {
|
||||
if checker.is_rule_enabled(Rule::BinaryOpException) {
|
||||
pylint::rules::binary_op_exception(checker, except_handler);
|
||||
}
|
||||
if let Some(name) = name {
|
||||
if checker.enabled(Rule::AmbiguousVariableName) {
|
||||
if checker.is_rule_enabled(Rule::AmbiguousVariableName) {
|
||||
pycodestyle::rules::ambiguous_variable_name(
|
||||
checker,
|
||||
name.as_str(),
|
||||
name.range(),
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::BuiltinVariableShadowing) {
|
||||
if checker.is_rule_enabled(Rule::BuiltinVariableShadowing) {
|
||||
flake8_builtins::rules::builtin_variable_shadowing(checker, name, name.range());
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,10 +6,10 @@ use crate::rules::{flake8_bugbear, ruff};
|
|||
|
||||
/// Run lint rules over a module.
|
||||
pub(crate) fn module(suite: &Suite, checker: &Checker) {
|
||||
if checker.enabled(Rule::FStringDocstring) {
|
||||
if checker.is_rule_enabled(Rule::FStringDocstring) {
|
||||
flake8_bugbear::rules::f_string_docstring(checker, suite);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidFormatterSuppressionComment) {
|
||||
if checker.is_rule_enabled(Rule::InvalidFormatterSuppressionComment) {
|
||||
ruff::rules::ignored_formatter_suppression_comment(checker, suite);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ use crate::rules::{flake8_builtins, pycodestyle};
|
|||
|
||||
/// Run lint rules over a [`Parameter`] syntax node.
|
||||
pub(crate) fn parameter(parameter: &Parameter, checker: &Checker) {
|
||||
if checker.enabled(Rule::AmbiguousVariableName) {
|
||||
if checker.is_rule_enabled(Rule::AmbiguousVariableName) {
|
||||
pycodestyle::rules::ambiguous_variable_name(
|
||||
checker,
|
||||
¶meter.name,
|
||||
parameter.name.range(),
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::BuiltinArgumentShadowing) {
|
||||
if checker.is_rule_enabled(Rule::BuiltinArgumentShadowing) {
|
||||
flake8_builtins::rules::builtin_argument_shadowing(checker, parameter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,17 @@ use crate::rules::{flake8_bugbear, flake8_pyi, ruff};
|
|||
|
||||
/// Run lint rules over a [`Parameters`] syntax node.
|
||||
pub(crate) fn parameters(parameters: &Parameters, checker: &Checker) {
|
||||
if checker.enabled(Rule::FunctionCallInDefaultArgument) {
|
||||
if checker.is_rule_enabled(Rule::FunctionCallInDefaultArgument) {
|
||||
flake8_bugbear::rules::function_call_in_argument_default(checker, parameters);
|
||||
}
|
||||
if checker.settings.rules.enabled(Rule::ImplicitOptional) {
|
||||
if checker.is_rule_enabled(Rule::ImplicitOptional) {
|
||||
ruff::rules::implicit_optional(checker, parameters);
|
||||
}
|
||||
if checker.source_type.is_stub() {
|
||||
if checker.enabled(Rule::TypedArgumentDefaultInStub) {
|
||||
if checker.is_rule_enabled(Rule::TypedArgumentDefaultInStub) {
|
||||
flake8_pyi::rules::typed_argument_simple_defaults(checker, parameters);
|
||||
}
|
||||
if checker.enabled(Rule::ArgumentDefaultInStub) {
|
||||
if checker.is_rule_enabled(Rule::ArgumentDefaultInStub) {
|
||||
flake8_pyi::rules::argument_simple_defaults(checker, parameters);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,37 +6,39 @@ use crate::rules::{flake8_bandit, flake8_pyi, flake8_quotes, pycodestyle, ruff};
|
|||
|
||||
/// Run lint rules over a [`StringLike`] syntax nodes.
|
||||
pub(crate) fn string_like(string_like: StringLike, checker: &Checker) {
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::AmbiguousUnicodeCharacterString,
|
||||
Rule::AmbiguousUnicodeCharacterDocstring,
|
||||
]) {
|
||||
ruff::rules::ambiguous_unicode_character_string(checker, string_like);
|
||||
}
|
||||
if checker.enabled(Rule::HardcodedBindAllInterfaces) {
|
||||
if checker.is_rule_enabled(Rule::HardcodedBindAllInterfaces) {
|
||||
flake8_bandit::rules::hardcoded_bind_all_interfaces(checker, string_like);
|
||||
}
|
||||
if checker.enabled(Rule::HardcodedTempFile) {
|
||||
if checker.is_rule_enabled(Rule::HardcodedTempFile) {
|
||||
flake8_bandit::rules::hardcoded_tmp_directory(checker, string_like);
|
||||
}
|
||||
if checker.source_type.is_stub() {
|
||||
if checker.enabled(Rule::StringOrBytesTooLong) {
|
||||
if checker.is_rule_enabled(Rule::StringOrBytesTooLong) {
|
||||
flake8_pyi::rules::string_or_bytes_too_long(checker, string_like);
|
||||
}
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::BadQuotesInlineString,
|
||||
Rule::BadQuotesMultilineString,
|
||||
Rule::BadQuotesDocstring,
|
||||
]) {
|
||||
flake8_quotes::rules::check_string_quotes(checker, string_like);
|
||||
}
|
||||
if checker.enabled(Rule::UnnecessaryEscapedQuote) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryEscapedQuote) {
|
||||
flake8_quotes::rules::unnecessary_escaped_quote(checker, string_like);
|
||||
}
|
||||
if checker.enabled(Rule::AvoidableEscapedQuote) && checker.settings.flake8_quotes.avoid_escape {
|
||||
if checker.is_rule_enabled(Rule::AvoidableEscapedQuote)
|
||||
&& checker.settings.flake8_quotes.avoid_escape
|
||||
{
|
||||
flake8_quotes::rules::avoidable_escaped_quote(checker, string_like);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidEscapeSequence) {
|
||||
if checker.is_rule_enabled(Rule::InvalidEscapeSequence) {
|
||||
pycodestyle::rules::invalid_escape_sequence(checker, string_like);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ use crate::rules::refurb;
|
|||
|
||||
/// Run lint rules over a suite of [`Stmt`] syntax nodes.
|
||||
pub(crate) fn suite(suite: &[Stmt], checker: &Checker) {
|
||||
if checker.enabled(Rule::UnnecessaryPlaceholder) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryPlaceholder) {
|
||||
flake8_pie::rules::unnecessary_placeholder(checker, suite);
|
||||
}
|
||||
if checker.enabled(Rule::RepeatedGlobal) {
|
||||
if checker.is_rule_enabled(Rule::RepeatedGlobal) {
|
||||
refurb::rules::repeated_global(checker, suite);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,13 @@ use crate::rules::pyflakes;
|
|||
|
||||
/// Run lint rules over all [`UnresolvedReference`] entities in the [`SemanticModel`].
|
||||
pub(crate) fn unresolved_references(checker: &Checker) {
|
||||
if !checker.any_enabled(&[Rule::UndefinedLocalWithImportStarUsage, Rule::UndefinedName]) {
|
||||
if !checker.any_rule_enabled(&[Rule::UndefinedLocalWithImportStarUsage, Rule::UndefinedName]) {
|
||||
return;
|
||||
}
|
||||
|
||||
for reference in checker.semantic.unresolved_references() {
|
||||
if reference.is_wildcard_import() {
|
||||
if checker.enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
||||
if checker.is_rule_enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::UndefinedLocalWithImportStarUsage {
|
||||
name: reference.name(checker.source()).to_string(),
|
||||
|
@ -22,7 +22,7 @@ pub(crate) fn unresolved_references(checker: &Checker) {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::UndefinedName) {
|
||||
if checker.is_rule_enabled(Rule::UndefinedName) {
|
||||
if checker.semantic.in_no_type_check() {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ use ruff_python_semantic::{
|
|||
};
|
||||
use ruff_python_stdlib::builtins::{MAGIC_GLOBALS, python_builtins};
|
||||
use ruff_python_trivia::CommentRanges;
|
||||
use ruff_source_file::{OneIndexed, SourceFile, SourceRow};
|
||||
use ruff_source_file::{OneIndexed, SourceFile, SourceFileBuilder, SourceRow};
|
||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||
|
||||
use crate::checkers::ast::annotation::AnnotationContext;
|
||||
|
@ -72,6 +72,7 @@ use crate::rules::pyflakes::rules::{
|
|||
};
|
||||
use crate::rules::pylint::rules::{AwaitOutsideAsync, LoadBeforeGlobalDeclaration};
|
||||
use crate::rules::{flake8_pyi, flake8_type_checking, pyflakes, pyupgrade};
|
||||
use crate::settings::rule_table::RuleTable;
|
||||
use crate::settings::{LinterSettings, TargetVersion, flags};
|
||||
use crate::{Edit, OldDiagnostic, Violation};
|
||||
use crate::{Locator, docstrings, noqa};
|
||||
|
@ -480,14 +481,14 @@ impl<'a> Checker<'a> {
|
|||
|
||||
/// Returns whether the given rule should be checked.
|
||||
#[inline]
|
||||
pub(crate) const fn enabled(&self, rule: Rule) -> bool {
|
||||
self.settings.rules.enabled(rule)
|
||||
pub(crate) const fn is_rule_enabled(&self, rule: Rule) -> bool {
|
||||
self.context.is_rule_enabled(rule)
|
||||
}
|
||||
|
||||
/// Returns whether any of the given rules should be checked.
|
||||
#[inline]
|
||||
pub(crate) const fn any_enabled(&self, rules: &[Rule]) -> bool {
|
||||
self.settings.rules.any_enabled(rules)
|
||||
pub(crate) const fn any_rule_enabled(&self, rules: &[Rule]) -> bool {
|
||||
self.context.any_rule_enabled(rules)
|
||||
}
|
||||
|
||||
/// Returns the [`IsolationLevel`] to isolate fixes for a given node.
|
||||
|
@ -622,16 +623,12 @@ impl SemanticSyntaxContext for Checker<'_> {
|
|||
fn report_semantic_error(&self, error: SemanticSyntaxError) {
|
||||
match error.kind {
|
||||
SemanticSyntaxErrorKind::LateFutureImport => {
|
||||
if self.settings.rules.enabled(Rule::LateFutureImport) {
|
||||
if self.is_rule_enabled(Rule::LateFutureImport) {
|
||||
self.report_diagnostic(LateFutureImport, error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::LoadBeforeGlobalDeclaration { name, start } => {
|
||||
if self
|
||||
.settings
|
||||
.rules
|
||||
.enabled(Rule::LoadBeforeGlobalDeclaration)
|
||||
{
|
||||
if self.is_rule_enabled(Rule::LoadBeforeGlobalDeclaration) {
|
||||
self.report_diagnostic(
|
||||
LoadBeforeGlobalDeclaration {
|
||||
name,
|
||||
|
@ -642,17 +639,17 @@ impl SemanticSyntaxContext for Checker<'_> {
|
|||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::YieldOutsideFunction(kind) => {
|
||||
if self.settings.rules.enabled(Rule::YieldOutsideFunction) {
|
||||
if self.is_rule_enabled(Rule::YieldOutsideFunction) {
|
||||
self.report_diagnostic(YieldOutsideFunction::new(kind), error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::ReturnOutsideFunction => {
|
||||
if self.settings.rules.enabled(Rule::ReturnOutsideFunction) {
|
||||
if self.is_rule_enabled(Rule::ReturnOutsideFunction) {
|
||||
self.report_diagnostic(ReturnOutsideFunction, error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::AwaitOutsideAsyncFunction(_) => {
|
||||
if self.settings.rules.enabled(Rule::AwaitOutsideAsync) {
|
||||
if self.is_rule_enabled(Rule::AwaitOutsideAsync) {
|
||||
self.report_diagnostic(AwaitOutsideAsync, error.range);
|
||||
}
|
||||
}
|
||||
|
@ -2364,7 +2361,7 @@ impl<'a> Checker<'a> {
|
|||
fn visit_cast_type_argument(&mut self, arg: &'a Expr) {
|
||||
self.visit_type_definition(arg);
|
||||
|
||||
if !self.source_type.is_stub() && self.enabled(Rule::RuntimeCastValue) {
|
||||
if !self.source_type.is_stub() && self.is_rule_enabled(Rule::RuntimeCastValue) {
|
||||
flake8_type_checking::rules::runtime_cast_value(self, arg);
|
||||
}
|
||||
}
|
||||
|
@ -2766,12 +2763,12 @@ impl<'a> Checker<'a> {
|
|||
if self.semantic.in_annotation()
|
||||
&& self.semantic.in_typing_only_annotation()
|
||||
{
|
||||
if self.enabled(Rule::QuotedAnnotation) {
|
||||
if self.is_rule_enabled(Rule::QuotedAnnotation) {
|
||||
pyupgrade::rules::quoted_annotation(self, annotation, range);
|
||||
}
|
||||
}
|
||||
if self.source_type.is_stub() {
|
||||
if self.enabled(Rule::QuotedAnnotationInStub) {
|
||||
if self.is_rule_enabled(Rule::QuotedAnnotationInStub) {
|
||||
flake8_pyi::rules::quoted_annotation_in_stub(
|
||||
self, annotation, range,
|
||||
);
|
||||
|
@ -2793,7 +2790,9 @@ impl<'a> Checker<'a> {
|
|||
self.visit_expr(parsed_expr);
|
||||
if self.semantic.in_type_alias_value() {
|
||||
// stub files are covered by PYI020
|
||||
if !self.source_type.is_stub() && self.enabled(Rule::QuotedTypeAlias) {
|
||||
if !self.source_type.is_stub()
|
||||
&& self.is_rule_enabled(Rule::QuotedTypeAlias)
|
||||
{
|
||||
flake8_type_checking::rules::quoted_type_alias(
|
||||
self,
|
||||
parsed_expr,
|
||||
|
@ -2806,7 +2805,7 @@ impl<'a> Checker<'a> {
|
|||
Err(parse_error) => {
|
||||
self.semantic.restore(snapshot);
|
||||
|
||||
if self.enabled(Rule::ForwardAnnotationSyntaxError) {
|
||||
if self.is_rule_enabled(Rule::ForwardAnnotationSyntaxError) {
|
||||
self.report_type_diagnostic(
|
||||
pyflakes::rules::ForwardAnnotationSyntaxError {
|
||||
parse_error: parse_error.error.to_string(),
|
||||
|
@ -2953,7 +2952,7 @@ impl<'a> Checker<'a> {
|
|||
self.semantic.flags -= SemanticModelFlags::DUNDER_ALL_DEFINITION;
|
||||
} else {
|
||||
if self.semantic.global_scope().uses_star_imports() {
|
||||
if self.enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
||||
if self.is_rule_enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
||||
self.report_diagnostic(
|
||||
pyflakes::rules::UndefinedLocalWithImportStarUsage {
|
||||
name: name.to_string(),
|
||||
|
@ -2963,7 +2962,7 @@ impl<'a> Checker<'a> {
|
|||
.set_parent(definition.start());
|
||||
}
|
||||
} else {
|
||||
if self.enabled(Rule::UndefinedExport) {
|
||||
if self.is_rule_enabled(Rule::UndefinedExport) {
|
||||
if is_undefined_export_in_dunder_init_enabled(self.settings)
|
||||
|| !self.path.ends_with("__init__.py")
|
||||
{
|
||||
|
@ -3114,17 +3113,29 @@ pub(crate) fn check_ast(
|
|||
/// a [`Violation`] to the contained [`OldDiagnostic`] collection on `Drop`.
|
||||
pub(crate) struct LintContext<'a> {
|
||||
diagnostics: RefCell<Vec<OldDiagnostic>>,
|
||||
source_file: &'a SourceFile,
|
||||
source_file: SourceFile,
|
||||
rules: RuleTable,
|
||||
#[expect(unused, reason = "TODO(brent) use this instead of Checker::settings")]
|
||||
settings: &'a LinterSettings,
|
||||
}
|
||||
|
||||
impl<'a> LintContext<'a> {
|
||||
/// Create a new collector with the given `source_file` and an empty collection of
|
||||
/// `OldDiagnostic`s.
|
||||
pub(crate) fn new(source_file: &'a SourceFile, settings: &'a LinterSettings) -> Self {
|
||||
pub(crate) fn new(path: &Path, contents: &str, settings: &'a LinterSettings) -> Self {
|
||||
let source_file =
|
||||
SourceFileBuilder::new(path.to_string_lossy().as_ref(), contents).finish();
|
||||
|
||||
// Ignore diagnostics based on per-file-ignores.
|
||||
let mut rules = settings.rules.clone();
|
||||
for ignore in crate::fs::ignores_from_path(path, &settings.per_file_ignores) {
|
||||
rules.disable(ignore);
|
||||
}
|
||||
|
||||
Self {
|
||||
diagnostics: RefCell::default(),
|
||||
source_file,
|
||||
rules,
|
||||
settings,
|
||||
}
|
||||
}
|
||||
|
@ -3140,7 +3151,7 @@ impl<'a> LintContext<'a> {
|
|||
) -> DiagnosticGuard<'chk, 'a> {
|
||||
DiagnosticGuard {
|
||||
context: self,
|
||||
diagnostic: Some(OldDiagnostic::new(kind, range, self.source_file)),
|
||||
diagnostic: Some(OldDiagnostic::new(kind, range, &self.source_file)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3154,28 +3165,42 @@ impl<'a> LintContext<'a> {
|
|||
kind: T,
|
||||
range: TextRange,
|
||||
) -> Option<DiagnosticGuard<'chk, 'a>> {
|
||||
if self.settings.rules.enabled(T::rule()) {
|
||||
if self.is_rule_enabled(T::rule()) {
|
||||
Some(DiagnosticGuard {
|
||||
context: self,
|
||||
diagnostic: Some(OldDiagnostic::new(kind, range, self.source_file)),
|
||||
diagnostic: Some(OldDiagnostic::new(kind, range, &self.source_file)),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_diagnostics(self) -> Vec<OldDiagnostic> {
|
||||
self.diagnostics.into_inner()
|
||||
#[inline]
|
||||
pub(crate) const fn is_rule_enabled(&self, rule: Rule) -> bool {
|
||||
self.rules.enabled(rule)
|
||||
}
|
||||
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.diagnostics.borrow().is_empty()
|
||||
#[inline]
|
||||
pub(crate) const fn any_rule_enabled(&self, rules: &[Rule]) -> bool {
|
||||
self.rules.any_enabled(rules)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn iter_enabled_rules(&self) -> impl Iterator<Item = Rule> + '_ {
|
||||
self.rules.iter_enabled()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn into_parts(self) -> (Vec<OldDiagnostic>, SourceFile) {
|
||||
(self.diagnostics.into_inner(), self.source_file)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn as_mut_vec(&mut self) -> &mut Vec<OldDiagnostic> {
|
||||
self.diagnostics.get_mut()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn iter(&mut self) -> impl Iterator<Item = &OldDiagnostic> {
|
||||
self.diagnostics.get_mut().iter()
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ pub(crate) fn check_file_path(
|
|||
context: &LintContext,
|
||||
) {
|
||||
// flake8-no-pep420
|
||||
if settings.rules.enabled(Rule::ImplicitNamespacePackage) {
|
||||
if context.is_rule_enabled(Rule::ImplicitNamespacePackage) {
|
||||
let allow_nested_roots = is_allow_nested_roots_enabled(settings);
|
||||
implicit_namespace_package(
|
||||
path,
|
||||
|
@ -38,12 +38,12 @@ pub(crate) fn check_file_path(
|
|||
}
|
||||
|
||||
// pep8-naming
|
||||
if settings.rules.enabled(Rule::InvalidModuleName) {
|
||||
if context.is_rule_enabled(Rule::InvalidModuleName) {
|
||||
invalid_module_name(path, package, &settings.pep8_naming.ignore_names, context);
|
||||
}
|
||||
|
||||
// flake8-builtins
|
||||
if settings.rules.enabled(Rule::StdlibModuleShadowing) {
|
||||
if context.is_rule_enabled(Rule::StdlibModuleShadowing) {
|
||||
stdlib_module_shadowing(path, settings, target_version, context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ pub(crate) fn check_imports(
|
|||
let blocks: Vec<&Block> = tracker.iter().collect();
|
||||
|
||||
// Enforce import rules.
|
||||
if settings.rules.enabled(Rule::UnsortedImports) {
|
||||
if context.is_rule_enabled(Rule::UnsortedImports) {
|
||||
for block in &blocks {
|
||||
if !block.imports.is_empty() {
|
||||
isort::rules::organize_imports(
|
||||
|
@ -60,7 +60,7 @@ pub(crate) fn check_imports(
|
|||
}
|
||||
}
|
||||
}
|
||||
if settings.rules.enabled(Rule::MissingRequiredImport) {
|
||||
if context.is_rule_enabled(Rule::MissingRequiredImport) {
|
||||
isort::rules::add_required_imports(
|
||||
parsed,
|
||||
locator,
|
||||
|
|
|
@ -47,49 +47,48 @@ pub(crate) fn check_logical_lines(
|
|||
let mut prev_indent_level = None;
|
||||
let indent_char = stylist.indentation().as_char();
|
||||
|
||||
let enforce_space_around_operator = settings.rules.any_enabled(&[
|
||||
let enforce_space_around_operator = context.any_rule_enabled(&[
|
||||
Rule::MultipleSpacesBeforeOperator,
|
||||
Rule::MultipleSpacesAfterOperator,
|
||||
Rule::TabBeforeOperator,
|
||||
Rule::TabAfterOperator,
|
||||
]);
|
||||
let enforce_whitespace_around_named_parameter_equals = settings.rules.any_enabled(&[
|
||||
let enforce_whitespace_around_named_parameter_equals = context.any_rule_enabled(&[
|
||||
Rule::UnexpectedSpacesAroundKeywordParameterEquals,
|
||||
Rule::MissingWhitespaceAroundParameterEquals,
|
||||
]);
|
||||
let enforce_missing_whitespace_around_operator = settings.rules.any_enabled(&[
|
||||
let enforce_missing_whitespace_around_operator = context.any_rule_enabled(&[
|
||||
Rule::MissingWhitespaceAroundOperator,
|
||||
Rule::MissingWhitespaceAroundArithmeticOperator,
|
||||
Rule::MissingWhitespaceAroundBitwiseOrShiftOperator,
|
||||
Rule::MissingWhitespaceAroundModuloOperator,
|
||||
]);
|
||||
let enforce_missing_whitespace = settings.rules.enabled(Rule::MissingWhitespace);
|
||||
let enforce_space_after_comma = settings
|
||||
.rules
|
||||
.any_enabled(&[Rule::MultipleSpacesAfterComma, Rule::TabAfterComma]);
|
||||
let enforce_extraneous_whitespace = settings.rules.any_enabled(&[
|
||||
let enforce_missing_whitespace = context.is_rule_enabled(Rule::MissingWhitespace);
|
||||
let enforce_space_after_comma =
|
||||
context.any_rule_enabled(&[Rule::MultipleSpacesAfterComma, Rule::TabAfterComma]);
|
||||
let enforce_extraneous_whitespace = context.any_rule_enabled(&[
|
||||
Rule::WhitespaceAfterOpenBracket,
|
||||
Rule::WhitespaceBeforeCloseBracket,
|
||||
Rule::WhitespaceBeforePunctuation,
|
||||
]);
|
||||
let enforce_whitespace_around_keywords = settings.rules.any_enabled(&[
|
||||
let enforce_whitespace_around_keywords = context.any_rule_enabled(&[
|
||||
Rule::MultipleSpacesAfterKeyword,
|
||||
Rule::MultipleSpacesBeforeKeyword,
|
||||
Rule::TabAfterKeyword,
|
||||
Rule::TabBeforeKeyword,
|
||||
]);
|
||||
let enforce_missing_whitespace_after_keyword =
|
||||
settings.rules.enabled(Rule::MissingWhitespaceAfterKeyword);
|
||||
let enforce_whitespace_before_comment = settings.rules.any_enabled(&[
|
||||
context.is_rule_enabled(Rule::MissingWhitespaceAfterKeyword);
|
||||
let enforce_whitespace_before_comment = context.any_rule_enabled(&[
|
||||
Rule::TooFewSpacesBeforeInlineComment,
|
||||
Rule::NoSpaceAfterInlineComment,
|
||||
Rule::NoSpaceAfterBlockComment,
|
||||
Rule::MultipleLeadingHashesForBlockComment,
|
||||
]);
|
||||
let enforce_whitespace_before_parameters =
|
||||
settings.rules.enabled(Rule::WhitespaceBeforeParameters);
|
||||
let enforce_redundant_backslash = settings.rules.enabled(Rule::RedundantBackslash);
|
||||
let enforce_indentation = settings.rules.any_enabled(&[
|
||||
context.is_rule_enabled(Rule::WhitespaceBeforeParameters);
|
||||
let enforce_redundant_backslash = context.is_rule_enabled(Rule::RedundantBackslash);
|
||||
let enforce_indentation = context.any_rule_enabled(&[
|
||||
Rule::IndentationWithInvalidMultiple,
|
||||
Rule::NoIndentedBlock,
|
||||
Rule::UnexpectedIndentation,
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::fix::edits::delete_comment;
|
|||
use crate::noqa::{
|
||||
Code, Directive, FileExemption, FileNoqaDirectives, NoqaDirectives, NoqaMapping,
|
||||
};
|
||||
use crate::registry::{Rule, RuleSet};
|
||||
use crate::registry::Rule;
|
||||
use crate::rule_redirects::get_redirect_target;
|
||||
use crate::rules::pygrep_hooks;
|
||||
use crate::rules::ruff;
|
||||
|
@ -22,7 +22,6 @@ use crate::{Edit, Fix, Locator};
|
|||
|
||||
use super::ast::LintContext;
|
||||
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
pub(crate) fn check_noqa(
|
||||
context: &mut LintContext,
|
||||
path: &Path,
|
||||
|
@ -30,7 +29,6 @@ pub(crate) fn check_noqa(
|
|||
comment_ranges: &CommentRanges,
|
||||
noqa_line_for: &NoqaMapping,
|
||||
analyze_directives: bool,
|
||||
per_file_ignores: &RuleSet,
|
||||
settings: &LinterSettings,
|
||||
) -> Vec<usize> {
|
||||
// Identify any codes that are globally exempted (within the current file).
|
||||
|
@ -107,10 +105,9 @@ pub(crate) fn check_noqa(
|
|||
|
||||
// Enforce that the noqa directive was actually used (RUF100), unless RUF100 was itself
|
||||
// suppressed.
|
||||
if settings.rules.enabled(Rule::UnusedNOQA)
|
||||
if context.is_rule_enabled(Rule::UnusedNOQA)
|
||||
&& analyze_directives
|
||||
&& !exemption.includes(Rule::UnusedNOQA)
|
||||
&& !per_file_ignores.contains(Rule::UnusedNOQA)
|
||||
{
|
||||
let directives = noqa_directives
|
||||
.lines()
|
||||
|
@ -162,7 +159,7 @@ pub(crate) fn check_noqa(
|
|||
if is_code_used {
|
||||
valid_codes.push(original_code);
|
||||
} else if let Ok(rule) = Rule::from_code(code) {
|
||||
if settings.rules.enabled(rule) {
|
||||
if context.is_rule_enabled(rule) {
|
||||
unmatched_codes.push(original_code);
|
||||
} else {
|
||||
disabled_codes.push(original_code);
|
||||
|
@ -232,18 +229,12 @@ pub(crate) fn check_noqa(
|
|||
}
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::RedirectedNOQA)
|
||||
&& !per_file_ignores.contains(Rule::RedirectedNOQA)
|
||||
&& !exemption.includes(Rule::RedirectedNOQA)
|
||||
{
|
||||
if context.is_rule_enabled(Rule::RedirectedNOQA) && !exemption.includes(Rule::RedirectedNOQA) {
|
||||
ruff::rules::redirected_noqa(context, &noqa_directives);
|
||||
ruff::rules::redirected_file_noqa(context, &file_noqa_directives);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::BlanketNOQA)
|
||||
&& !per_file_ignores.contains(Rule::BlanketNOQA)
|
||||
&& !exemption.enumerates(Rule::BlanketNOQA)
|
||||
{
|
||||
if context.is_rule_enabled(Rule::BlanketNOQA) && !exemption.enumerates(Rule::BlanketNOQA) {
|
||||
pygrep_hooks::rules::blanket_noqa(
|
||||
context,
|
||||
&noqa_directives,
|
||||
|
@ -252,8 +243,7 @@ pub(crate) fn check_noqa(
|
|||
);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::InvalidRuleCode)
|
||||
&& !per_file_ignores.contains(Rule::InvalidRuleCode)
|
||||
if context.is_rule_enabled(Rule::InvalidRuleCode)
|
||||
&& !exemption.enumerates(Rule::InvalidRuleCode)
|
||||
{
|
||||
ruff::rules::invalid_noqa_code(context, &noqa_directives, locator, &settings.external);
|
||||
|
|
|
@ -26,15 +26,16 @@ pub(crate) fn check_physical_lines(
|
|||
settings: &LinterSettings,
|
||||
context: &LintContext,
|
||||
) {
|
||||
let enforce_doc_line_too_long = settings.rules.enabled(Rule::DocLineTooLong);
|
||||
let enforce_line_too_long = settings.rules.enabled(Rule::LineTooLong);
|
||||
let enforce_no_newline_at_end_of_file = settings.rules.enabled(Rule::MissingNewlineAtEndOfFile);
|
||||
let enforce_mixed_spaces_and_tabs = settings.rules.enabled(Rule::MixedSpacesAndTabs);
|
||||
let enforce_bidirectional_unicode = settings.rules.enabled(Rule::BidirectionalUnicode);
|
||||
let enforce_trailing_whitespace = settings.rules.enabled(Rule::TrailingWhitespace);
|
||||
let enforce_doc_line_too_long = context.is_rule_enabled(Rule::DocLineTooLong);
|
||||
let enforce_line_too_long = context.is_rule_enabled(Rule::LineTooLong);
|
||||
let enforce_no_newline_at_end_of_file =
|
||||
context.is_rule_enabled(Rule::MissingNewlineAtEndOfFile);
|
||||
let enforce_mixed_spaces_and_tabs = context.is_rule_enabled(Rule::MixedSpacesAndTabs);
|
||||
let enforce_bidirectional_unicode = context.is_rule_enabled(Rule::BidirectionalUnicode);
|
||||
let enforce_trailing_whitespace = context.is_rule_enabled(Rule::TrailingWhitespace);
|
||||
let enforce_blank_line_contains_whitespace =
|
||||
settings.rules.enabled(Rule::BlankLineWithWhitespace);
|
||||
let enforce_copyright_notice = settings.rules.enabled(Rule::MissingCopyrightNotice);
|
||||
context.is_rule_enabled(Rule::BlankLineWithWhitespace);
|
||||
let enforce_copyright_notice = context.is_rule_enabled(Rule::MissingCopyrightNotice);
|
||||
|
||||
let mut doc_lines_iter = doc_lines.iter().peekable();
|
||||
let comment_ranges = indexer.comment_ranges();
|
||||
|
@ -62,10 +63,10 @@ pub(crate) fn check_physical_lines(
|
|||
}
|
||||
|
||||
if enforce_trailing_whitespace || enforce_blank_line_contains_whitespace {
|
||||
trailing_whitespace(&line, locator, indexer, settings, context);
|
||||
trailing_whitespace(&line, locator, indexer, context);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::IndentedFormFeed) {
|
||||
if context.is_rule_enabled(Rule::IndentedFormFeed) {
|
||||
indented_form_feed(&line, context);
|
||||
}
|
||||
}
|
||||
|
@ -81,10 +82,11 @@ pub(crate) fn check_physical_lines(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use ruff_python_codegen::Stylist;
|
||||
use ruff_python_index::Indexer;
|
||||
use ruff_python_parser::parse_module;
|
||||
use ruff_source_file::SourceFileBuilder;
|
||||
|
||||
use crate::Locator;
|
||||
use crate::checkers::ast::LintContext;
|
||||
|
@ -104,7 +106,6 @@ mod tests {
|
|||
let stylist = Stylist::from_tokens(parsed.tokens(), locator.contents());
|
||||
|
||||
let check_with_max_line_length = |line_length: LineLength| {
|
||||
let source_file = SourceFileBuilder::new("<filename>", line).finish();
|
||||
let settings = LinterSettings {
|
||||
pycodestyle: pycodestyle::settings::Settings {
|
||||
max_line_length: line_length,
|
||||
|
@ -112,9 +113,9 @@ mod tests {
|
|||
},
|
||||
..LinterSettings::for_rule(Rule::LineTooLong)
|
||||
};
|
||||
let diagnostics = LintContext::new(&source_file, &settings);
|
||||
let diagnostics = LintContext::new(Path::new("<filename>"), line, &settings);
|
||||
check_physical_lines(&locator, &stylist, &indexer, &[], &settings, &diagnostics);
|
||||
diagnostics.into_diagnostics()
|
||||
diagnostics.into_parts().0
|
||||
};
|
||||
let line_length = LineLength::try_from(8).unwrap();
|
||||
assert_eq!(check_with_max_line_length(line_length), vec![]);
|
||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) fn check_tokens(
|
|||
) {
|
||||
let comment_ranges = indexer.comment_ranges();
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::BlankLineBetweenMethods,
|
||||
Rule::BlankLinesTopLevel,
|
||||
Rule::TooManyBlankLines,
|
||||
|
@ -53,36 +53,33 @@ pub(crate) fn check_tokens(
|
|||
.check_lines(tokens);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::BlanketTypeIgnore) {
|
||||
if context.is_rule_enabled(Rule::BlanketTypeIgnore) {
|
||||
pygrep_hooks::rules::blanket_type_ignore(context, comment_ranges, locator);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::EmptyComment) {
|
||||
if context.is_rule_enabled(Rule::EmptyComment) {
|
||||
pylint::rules::empty_comments(context, comment_ranges, locator);
|
||||
}
|
||||
|
||||
if settings
|
||||
.rules
|
||||
.enabled(Rule::AmbiguousUnicodeCharacterComment)
|
||||
{
|
||||
if context.is_rule_enabled(Rule::AmbiguousUnicodeCharacterComment) {
|
||||
for range in comment_ranges {
|
||||
ruff::rules::ambiguous_unicode_character_comment(context, locator, range, settings);
|
||||
}
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::CommentedOutCode) {
|
||||
if context.is_rule_enabled(Rule::CommentedOutCode) {
|
||||
eradicate::rules::commented_out_code(context, locator, comment_ranges, settings);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::UTF8EncodingDeclaration) {
|
||||
if context.is_rule_enabled(Rule::UTF8EncodingDeclaration) {
|
||||
pyupgrade::rules::unnecessary_coding_comment(context, locator, comment_ranges);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::TabIndentation) {
|
||||
if context.is_rule_enabled(Rule::TabIndentation) {
|
||||
pycodestyle::rules::tab_indentation(context, locator, indexer);
|
||||
}
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::InvalidCharacterBackspace,
|
||||
Rule::InvalidCharacterSub,
|
||||
Rule::InvalidCharacterEsc,
|
||||
|
@ -94,7 +91,7 @@ pub(crate) fn check_tokens(
|
|||
}
|
||||
}
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::MultipleStatementsOnOneLineColon,
|
||||
Rule::MultipleStatementsOnOneLineSemicolon,
|
||||
Rule::UselessSemicolon,
|
||||
|
@ -109,14 +106,14 @@ pub(crate) fn check_tokens(
|
|||
);
|
||||
}
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::SingleLineImplicitStringConcatenation,
|
||||
Rule::MultiLineImplicitStringConcatenation,
|
||||
]) {
|
||||
flake8_implicit_str_concat::rules::implicit(context, tokens, locator, indexer, settings);
|
||||
}
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::MissingTrailingComma,
|
||||
Rule::TrailingCommaOnBareTuple,
|
||||
Rule::ProhibitedTrailingComma,
|
||||
|
@ -124,25 +121,25 @@ pub(crate) fn check_tokens(
|
|||
flake8_commas::rules::trailing_commas(context, tokens, locator, indexer);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::ExtraneousParentheses) {
|
||||
if context.is_rule_enabled(Rule::ExtraneousParentheses) {
|
||||
pyupgrade::rules::extraneous_parentheses(context, tokens, locator);
|
||||
}
|
||||
|
||||
if source_type.is_stub() && settings.rules.enabled(Rule::TypeCommentInStub) {
|
||||
if source_type.is_stub() && context.is_rule_enabled(Rule::TypeCommentInStub) {
|
||||
flake8_pyi::rules::type_comment_in_stub(context, locator, comment_ranges);
|
||||
}
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::ShebangNotExecutable,
|
||||
Rule::ShebangMissingExecutableFile,
|
||||
Rule::ShebangLeadingWhitespace,
|
||||
Rule::ShebangNotFirstLine,
|
||||
Rule::ShebangMissingPython,
|
||||
]) {
|
||||
flake8_executable::rules::from_tokens(context, path, locator, comment_ranges, settings);
|
||||
flake8_executable::rules::from_tokens(context, path, locator, comment_ranges);
|
||||
}
|
||||
|
||||
if settings.rules.any_enabled(&[
|
||||
if context.any_rule_enabled(&[
|
||||
Rule::InvalidTodoTag,
|
||||
Rule::MissingTodoAuthor,
|
||||
Rule::MissingTodoLink,
|
||||
|
@ -167,7 +164,7 @@ pub(crate) fn check_tokens(
|
|||
flake8_fixme::rules::todos(context, &todo_comments);
|
||||
}
|
||||
|
||||
if settings.rules.enabled(Rule::TooManyNewlinesAtEndOfFile) {
|
||||
if context.is_rule_enabled(Rule::TooManyNewlinesAtEndOfFile) {
|
||||
pycodestyle::rules::too_many_newlines_at_end_of_file(context, tokens, cell_offsets);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ pub fn get_cwd() -> &'static Path {
|
|||
|
||||
/// Create a set with codes matching the pattern/code pairs.
|
||||
pub(crate) fn ignores_from_path(path: &Path, ignore_list: &CompiledPerFileIgnoreList) -> RuleSet {
|
||||
if ignore_list.is_empty() {
|
||||
return RuleSet::empty();
|
||||
}
|
||||
ignore_list
|
||||
.iter_matches(path, "Adding per-file ignores")
|
||||
.flatten()
|
||||
|
|
|
@ -13,7 +13,7 @@ use ruff_python_ast::{ModModule, PySourceType, PythonVersion};
|
|||
use ruff_python_codegen::Stylist;
|
||||
use ruff_python_index::Indexer;
|
||||
use ruff_python_parser::{ParseError, ParseOptions, Parsed, UnsupportedSyntaxError};
|
||||
use ruff_source_file::{SourceFile, SourceFileBuilder};
|
||||
use ruff_source_file::SourceFile;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::OldDiagnostic;
|
||||
|
@ -30,7 +30,7 @@ use crate::fix::{FixResult, fix_file};
|
|||
use crate::noqa::add_noqa;
|
||||
use crate::package::PackageRoot;
|
||||
use crate::preview::is_py314_support_enabled;
|
||||
use crate::registry::{Rule, RuleSet};
|
||||
use crate::registry::Rule;
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
use crate::rules::ruff::rules::test_rules::{self, TEST_RULES, TestRule};
|
||||
use crate::settings::types::UnsafeFixes;
|
||||
|
@ -160,11 +160,8 @@ pub fn check_path(
|
|||
parsed: &Parsed<ModModule>,
|
||||
target_version: TargetVersion,
|
||||
) -> Vec<OldDiagnostic> {
|
||||
let source_file =
|
||||
SourceFileBuilder::new(path.to_string_lossy().as_ref(), locator.contents()).finish();
|
||||
|
||||
// Aggregate all diagnostics.
|
||||
let mut diagnostics = LintContext::new(&source_file, settings);
|
||||
let mut context = LintContext::new(path, locator.contents(), settings);
|
||||
|
||||
// Aggregate all semantic syntax errors.
|
||||
let mut semantic_syntax_errors = vec![];
|
||||
|
@ -174,16 +171,15 @@ pub fn check_path(
|
|||
|
||||
// Collect doc lines. This requires a rare mix of tokens (for comments) and AST
|
||||
// (for docstrings), which demands special-casing at this level.
|
||||
let use_doc_lines = settings.rules.enabled(Rule::DocLineTooLong);
|
||||
let use_doc_lines = context.is_rule_enabled(Rule::DocLineTooLong);
|
||||
let mut doc_lines = vec![];
|
||||
if use_doc_lines {
|
||||
doc_lines.extend(doc_lines_from_tokens(tokens));
|
||||
}
|
||||
|
||||
// Run the token-based rules.
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
if context
|
||||
.iter_enabled_rules()
|
||||
.any(|rule_code| rule_code.lint_source().is_tokens())
|
||||
{
|
||||
check_tokens(
|
||||
|
@ -195,14 +191,13 @@ pub fn check_path(
|
|||
settings,
|
||||
source_type,
|
||||
source_kind.as_ipy_notebook().map(Notebook::cell_offsets),
|
||||
&mut diagnostics,
|
||||
&mut context,
|
||||
);
|
||||
}
|
||||
|
||||
// Run the filesystem-based rules.
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
if context
|
||||
.iter_enabled_rules()
|
||||
.any(|rule_code| rule_code.lint_source().is_filesystem())
|
||||
{
|
||||
check_file_path(
|
||||
|
@ -212,23 +207,17 @@ pub fn check_path(
|
|||
comment_ranges,
|
||||
settings,
|
||||
target_version.linter_version(),
|
||||
&diagnostics,
|
||||
&context,
|
||||
);
|
||||
}
|
||||
|
||||
// Run the logical line-based rules.
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
if context
|
||||
.iter_enabled_rules()
|
||||
.any(|rule_code| rule_code.lint_source().is_logical_lines())
|
||||
{
|
||||
crate::checkers::logical_lines::check_logical_lines(
|
||||
tokens,
|
||||
locator,
|
||||
indexer,
|
||||
stylist,
|
||||
settings,
|
||||
&diagnostics,
|
||||
tokens, locator, indexer, stylist, settings, &context,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -251,13 +240,12 @@ pub fn check_path(
|
|||
cell_offsets,
|
||||
notebook_index,
|
||||
target_version,
|
||||
&diagnostics,
|
||||
&context,
|
||||
));
|
||||
|
||||
let use_imports = !directives.isort.skip_file
|
||||
&& settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
&& context
|
||||
.iter_enabled_rules()
|
||||
.any(|rule_code| rule_code.lint_source().is_imports());
|
||||
if use_imports || use_doc_lines {
|
||||
if use_imports {
|
||||
|
@ -272,7 +260,7 @@ pub fn check_path(
|
|||
source_type,
|
||||
cell_offsets,
|
||||
target_version.linter_version(),
|
||||
&diagnostics,
|
||||
&context,
|
||||
);
|
||||
}
|
||||
if use_doc_lines {
|
||||
|
@ -288,89 +276,77 @@ pub fn check_path(
|
|||
}
|
||||
|
||||
// Run the lines-based rules.
|
||||
if settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
if context
|
||||
.iter_enabled_rules()
|
||||
.any(|rule_code| rule_code.lint_source().is_physical_lines())
|
||||
{
|
||||
check_physical_lines(
|
||||
locator,
|
||||
stylist,
|
||||
indexer,
|
||||
&doc_lines,
|
||||
settings,
|
||||
&diagnostics,
|
||||
);
|
||||
check_physical_lines(locator, stylist, indexer, &doc_lines, settings, &context);
|
||||
}
|
||||
|
||||
// Raise violations for internal test rules
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
{
|
||||
for test_rule in TEST_RULES {
|
||||
if !settings.rules.enabled(*test_rule) {
|
||||
if !context.is_rule_enabled(*test_rule) {
|
||||
continue;
|
||||
}
|
||||
match test_rule {
|
||||
Rule::StableTestRule => {
|
||||
test_rules::StableTestRule::diagnostic(locator, comment_ranges, &diagnostics);
|
||||
test_rules::StableTestRule::diagnostic(locator, comment_ranges, &context);
|
||||
}
|
||||
Rule::StableTestRuleSafeFix => {
|
||||
test_rules::StableTestRuleSafeFix::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&context,
|
||||
);
|
||||
}
|
||||
Rule::StableTestRuleSafeFix => test_rules::StableTestRuleSafeFix::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
),
|
||||
Rule::StableTestRuleUnsafeFix => test_rules::StableTestRuleUnsafeFix::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
&context,
|
||||
),
|
||||
Rule::StableTestRuleDisplayOnlyFix => {
|
||||
test_rules::StableTestRuleDisplayOnlyFix::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
&context,
|
||||
);
|
||||
}
|
||||
Rule::PreviewTestRule => {
|
||||
test_rules::PreviewTestRule::diagnostic(locator, comment_ranges, &diagnostics);
|
||||
test_rules::PreviewTestRule::diagnostic(locator, comment_ranges, &context);
|
||||
}
|
||||
Rule::DeprecatedTestRule => {
|
||||
test_rules::DeprecatedTestRule::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
);
|
||||
test_rules::DeprecatedTestRule::diagnostic(locator, comment_ranges, &context);
|
||||
}
|
||||
Rule::AnotherDeprecatedTestRule => {
|
||||
test_rules::AnotherDeprecatedTestRule::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
&context,
|
||||
);
|
||||
}
|
||||
Rule::RemovedTestRule => {
|
||||
test_rules::RemovedTestRule::diagnostic(locator, comment_ranges, &diagnostics);
|
||||
test_rules::RemovedTestRule::diagnostic(locator, comment_ranges, &context);
|
||||
}
|
||||
Rule::AnotherRemovedTestRule => test_rules::AnotherRemovedTestRule::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
),
|
||||
Rule::RedirectedToTestRule => test_rules::RedirectedToTestRule::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
&context,
|
||||
),
|
||||
Rule::RedirectedToTestRule => {
|
||||
test_rules::RedirectedToTestRule::diagnostic(locator, comment_ranges, &context);
|
||||
}
|
||||
Rule::RedirectedFromTestRule => test_rules::RedirectedFromTestRule::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
&context,
|
||||
),
|
||||
Rule::RedirectedFromPrefixTestRule => {
|
||||
test_rules::RedirectedFromPrefixTestRule::diagnostic(
|
||||
locator,
|
||||
comment_ranges,
|
||||
&diagnostics,
|
||||
&context,
|
||||
);
|
||||
}
|
||||
_ => unreachable!("All test rules must have an implementation"),
|
||||
|
@ -378,52 +354,29 @@ pub fn check_path(
|
|||
}
|
||||
}
|
||||
|
||||
// Ignore diagnostics based on per-file-ignores.
|
||||
let per_file_ignores = if (!diagnostics.is_empty()
|
||||
|| settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| rule_code.lint_source().is_noqa()))
|
||||
&& !settings.per_file_ignores.is_empty()
|
||||
{
|
||||
fs::ignores_from_path(path, &settings.per_file_ignores)
|
||||
} else {
|
||||
RuleSet::empty()
|
||||
};
|
||||
if !per_file_ignores.is_empty() {
|
||||
diagnostics.as_mut_vec().retain(|diagnostic| {
|
||||
diagnostic
|
||||
.noqa_code()
|
||||
.and_then(|code| code.rule())
|
||||
.is_none_or(|rule| !per_file_ignores.contains(rule))
|
||||
});
|
||||
}
|
||||
|
||||
// Enforce `noqa` directives.
|
||||
if noqa.is_enabled()
|
||||
|| settings
|
||||
.rules
|
||||
.iter_enabled()
|
||||
|| context
|
||||
.iter_enabled_rules()
|
||||
.any(|rule_code| rule_code.lint_source().is_noqa())
|
||||
{
|
||||
let ignored = check_noqa(
|
||||
&mut diagnostics,
|
||||
&mut context,
|
||||
path,
|
||||
locator,
|
||||
comment_ranges,
|
||||
&directives.noqa_line_for,
|
||||
parsed.has_valid_syntax(),
|
||||
&per_file_ignores,
|
||||
settings,
|
||||
);
|
||||
if noqa.is_enabled() {
|
||||
for index in ignored.iter().rev() {
|
||||
diagnostics.as_mut_vec().swap_remove(*index);
|
||||
context.as_mut_vec().swap_remove(*index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut diagnostics = diagnostics.into_diagnostics();
|
||||
let (mut diagnostics, source_file) = context.into_parts();
|
||||
|
||||
if parsed.has_valid_syntax() {
|
||||
// Remove fixes for any rules marked as unfixable.
|
||||
|
|
|
@ -253,7 +253,7 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
],
|
||||
) = (ops, comparators)
|
||||
{
|
||||
if *n == 3 && checker.enabled(Rule::SysVersionInfo0Eq3) {
|
||||
if *n == 3 && checker.is_rule_enabled(Rule::SysVersionInfo0Eq3) {
|
||||
checker.report_diagnostic(
|
||||
SysVersionInfo0Eq3 {
|
||||
eq: matches!(*operator, CmpOp::Eq),
|
||||
|
@ -273,7 +273,7 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
],
|
||||
) = (ops, comparators)
|
||||
{
|
||||
if checker.enabled(Rule::SysVersionInfo1CmpInt) {
|
||||
if checker.is_rule_enabled(Rule::SysVersionInfo1CmpInt) {
|
||||
checker.report_diagnostic(SysVersionInfo1CmpInt, left.range());
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
],
|
||||
) = (ops, comparators)
|
||||
{
|
||||
if checker.enabled(Rule::SysVersionInfoMinorCmpInt) {
|
||||
if checker.is_rule_enabled(Rule::SysVersionInfoMinorCmpInt) {
|
||||
checker.report_diagnostic(SysVersionInfoMinorCmpInt, left.range());
|
||||
}
|
||||
}
|
||||
|
@ -310,10 +310,10 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
) = (ops, comparators)
|
||||
{
|
||||
if value.len() == 1 {
|
||||
if checker.enabled(Rule::SysVersionCmpStr10) {
|
||||
if checker.is_rule_enabled(Rule::SysVersionCmpStr10) {
|
||||
checker.report_diagnostic(SysVersionCmpStr10, left.range());
|
||||
}
|
||||
} else if checker.enabled(Rule::SysVersionCmpStr3) {
|
||||
} else if checker.is_rule_enabled(Rule::SysVersionCmpStr3) {
|
||||
checker.report_diagnostic(SysVersionCmpStr3, left.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,9 +183,9 @@ pub(crate) fn subscript(checker: &Checker, value: &Expr, slice: &Expr) {
|
|||
..
|
||||
}) = upper.as_ref()
|
||||
{
|
||||
if *i == 1 && checker.enabled(Rule::SysVersionSlice1) {
|
||||
if *i == 1 && checker.is_rule_enabled(Rule::SysVersionSlice1) {
|
||||
checker.report_diagnostic(SysVersionSlice1, value.range());
|
||||
} else if *i == 3 && checker.enabled(Rule::SysVersionSlice3) {
|
||||
} else if *i == 3 && checker.is_rule_enabled(Rule::SysVersionSlice3) {
|
||||
checker.report_diagnostic(SysVersionSlice3, value.range());
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +195,9 @@ pub(crate) fn subscript(checker: &Checker, value: &Expr, slice: &Expr) {
|
|||
value: ast::Number::Int(i),
|
||||
..
|
||||
}) => {
|
||||
if *i == 2 && checker.enabled(Rule::SysVersion2) {
|
||||
if *i == 2 && checker.is_rule_enabled(Rule::SysVersion2) {
|
||||
checker.report_diagnostic(SysVersion2, value.range());
|
||||
} else if *i == 0 && checker.enabled(Rule::SysVersion0) {
|
||||
} else if *i == 0 && checker.is_rule_enabled(Rule::SysVersion0) {
|
||||
checker.report_diagnostic(SysVersion0, value.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -639,7 +639,7 @@ pub(crate) fn definition(
|
|||
// ANN401 for dynamically typed parameters
|
||||
if let Some(annotation) = parameter.annotation() {
|
||||
has_any_typed_arg = true;
|
||||
if checker.enabled(Rule::AnyType) && !is_overridden {
|
||||
if checker.is_rule_enabled(Rule::AnyType) && !is_overridden {
|
||||
check_dynamically_typed(
|
||||
checker,
|
||||
annotation,
|
||||
|
@ -654,7 +654,7 @@ pub(crate) fn definition(
|
|||
.dummy_variable_rgx
|
||||
.is_match(parameter.name()))
|
||||
{
|
||||
if checker.enabled(Rule::MissingTypeFunctionArgument) {
|
||||
if checker.is_rule_enabled(Rule::MissingTypeFunctionArgument) {
|
||||
diagnostics.push(checker.report_diagnostic(
|
||||
MissingTypeFunctionArgument {
|
||||
name: parameter.name().to_string(),
|
||||
|
@ -671,7 +671,7 @@ pub(crate) fn definition(
|
|||
if let Some(expr) = &arg.annotation {
|
||||
has_any_typed_arg = true;
|
||||
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
||||
if checker.enabled(Rule::AnyType) && !is_overridden {
|
||||
if checker.is_rule_enabled(Rule::AnyType) && !is_overridden {
|
||||
let name = &arg.name;
|
||||
check_dynamically_typed(checker, expr, || format!("*{name}"), &mut diagnostics);
|
||||
}
|
||||
|
@ -680,7 +680,7 @@ pub(crate) fn definition(
|
|||
if !(checker.settings.flake8_annotations.suppress_dummy_args
|
||||
&& checker.settings.dummy_variable_rgx.is_match(&arg.name))
|
||||
{
|
||||
if checker.enabled(Rule::MissingTypeArgs) {
|
||||
if checker.is_rule_enabled(Rule::MissingTypeArgs) {
|
||||
diagnostics.push(checker.report_diagnostic(
|
||||
MissingTypeArgs {
|
||||
name: arg.name.to_string(),
|
||||
|
@ -697,7 +697,7 @@ pub(crate) fn definition(
|
|||
if let Some(expr) = &arg.annotation {
|
||||
has_any_typed_arg = true;
|
||||
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
||||
if checker.enabled(Rule::AnyType) && !is_overridden {
|
||||
if checker.is_rule_enabled(Rule::AnyType) && !is_overridden {
|
||||
let name = &arg.name;
|
||||
check_dynamically_typed(
|
||||
checker,
|
||||
|
@ -711,7 +711,7 @@ pub(crate) fn definition(
|
|||
if !(checker.settings.flake8_annotations.suppress_dummy_args
|
||||
&& checker.settings.dummy_variable_rgx.is_match(&arg.name))
|
||||
{
|
||||
if checker.enabled(Rule::MissingTypeKwargs) {
|
||||
if checker.is_rule_enabled(Rule::MissingTypeKwargs) {
|
||||
diagnostics.push(checker.report_diagnostic(
|
||||
MissingTypeKwargs {
|
||||
name: arg.name.to_string(),
|
||||
|
@ -726,7 +726,7 @@ pub(crate) fn definition(
|
|||
// ANN201, ANN202, ANN401
|
||||
if let Some(expr) = &returns {
|
||||
has_typed_return = true;
|
||||
if checker.enabled(Rule::AnyType) && !is_overridden {
|
||||
if checker.is_rule_enabled(Rule::AnyType) && !is_overridden {
|
||||
check_dynamically_typed(checker, expr, || name.to_string(), &mut diagnostics);
|
||||
}
|
||||
} else if !(
|
||||
|
@ -735,7 +735,7 @@ pub(crate) fn definition(
|
|||
checker.settings.flake8_annotations.suppress_none_returning && is_none_returning(body)
|
||||
) {
|
||||
if is_method && visibility::is_classmethod(decorator_list, checker.semantic()) {
|
||||
if checker.enabled(Rule::MissingReturnTypeClassMethod) {
|
||||
if checker.is_rule_enabled(Rule::MissingReturnTypeClassMethod) {
|
||||
let return_type = if is_stub_function(function, checker) {
|
||||
None
|
||||
} else {
|
||||
|
@ -761,7 +761,7 @@ pub(crate) fn definition(
|
|||
diagnostics.push(diagnostic);
|
||||
}
|
||||
} else if is_method && visibility::is_staticmethod(decorator_list, checker.semantic()) {
|
||||
if checker.enabled(Rule::MissingReturnTypeStaticMethod) {
|
||||
if checker.is_rule_enabled(Rule::MissingReturnTypeStaticMethod) {
|
||||
let return_type = if is_stub_function(function, checker) {
|
||||
None
|
||||
} else {
|
||||
|
@ -789,7 +789,7 @@ pub(crate) fn definition(
|
|||
} else if is_method && visibility::is_init(name) {
|
||||
// Allow omission of return annotation in `__init__` functions, as long as at
|
||||
// least one argument is typed.
|
||||
if checker.enabled(Rule::MissingReturnTypeSpecialMethod) {
|
||||
if checker.is_rule_enabled(Rule::MissingReturnTypeSpecialMethod) {
|
||||
if !(checker.settings.flake8_annotations.mypy_init_return && has_any_typed_arg) {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeSpecialMethod {
|
||||
|
@ -806,7 +806,7 @@ pub(crate) fn definition(
|
|||
}
|
||||
}
|
||||
} else if is_method && visibility::is_magic(name) {
|
||||
if checker.enabled(Rule::MissingReturnTypeSpecialMethod) {
|
||||
if checker.is_rule_enabled(Rule::MissingReturnTypeSpecialMethod) {
|
||||
let return_type = simple_magic_return_type(name);
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeSpecialMethod {
|
||||
|
@ -826,7 +826,7 @@ pub(crate) fn definition(
|
|||
} else {
|
||||
match visibility {
|
||||
visibility::Visibility::Public => {
|
||||
if checker.enabled(Rule::MissingReturnTypeUndocumentedPublicFunction) {
|
||||
if checker.is_rule_enabled(Rule::MissingReturnTypeUndocumentedPublicFunction) {
|
||||
let return_type = if is_stub_function(function, checker) {
|
||||
None
|
||||
} else {
|
||||
|
@ -861,7 +861,7 @@ pub(crate) fn definition(
|
|||
}
|
||||
}
|
||||
visibility::Visibility::Private => {
|
||||
if checker.enabled(Rule::MissingReturnTypePrivateFunction) {
|
||||
if checker.is_rule_enabled(Rule::MissingReturnTypePrivateFunction) {
|
||||
let return_type = if is_stub_function(function, checker) {
|
||||
None
|
||||
} else {
|
||||
|
|
|
@ -312,7 +312,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
Some(ShellKeyword {
|
||||
truthiness: truthiness @ (Truthiness::True | Truthiness::Truthy),
|
||||
}) => {
|
||||
if checker.enabled(Rule::SubprocessPopenWithShellEqualsTrue) {
|
||||
if checker.is_rule_enabled(Rule::SubprocessPopenWithShellEqualsTrue) {
|
||||
checker.report_diagnostic(
|
||||
SubprocessPopenWithShellEqualsTrue {
|
||||
safety: Safety::from(arg),
|
||||
|
@ -325,7 +325,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
// S603
|
||||
_ => {
|
||||
if !is_trusted_input(arg) {
|
||||
if checker.enabled(Rule::SubprocessWithoutShellEqualsTrue) {
|
||||
if checker.is_rule_enabled(Rule::SubprocessWithoutShellEqualsTrue) {
|
||||
checker.report_diagnostic(
|
||||
SubprocessWithoutShellEqualsTrue,
|
||||
call.func.range(),
|
||||
|
@ -340,7 +340,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
}) = shell_keyword
|
||||
{
|
||||
// S604
|
||||
if checker.enabled(Rule::CallWithShellEqualsTrue) {
|
||||
if checker.is_rule_enabled(Rule::CallWithShellEqualsTrue) {
|
||||
checker.report_diagnostic(
|
||||
CallWithShellEqualsTrue {
|
||||
is_exact: matches!(truthiness, Truthiness::True),
|
||||
|
@ -351,7 +351,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
|
||||
// S605
|
||||
if checker.enabled(Rule::StartProcessWithAShell) {
|
||||
if checker.is_rule_enabled(Rule::StartProcessWithAShell) {
|
||||
if matches!(call_kind, Some(CallKind::Shell)) {
|
||||
if let Some(arg) = call.arguments.args.first() {
|
||||
checker.report_diagnostic(
|
||||
|
@ -365,14 +365,14 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
|
||||
// S606
|
||||
if checker.enabled(Rule::StartProcessWithNoShell) {
|
||||
if checker.is_rule_enabled(Rule::StartProcessWithNoShell) {
|
||||
if matches!(call_kind, Some(CallKind::NoShell)) {
|
||||
checker.report_diagnostic(StartProcessWithNoShell, call.func.range());
|
||||
}
|
||||
}
|
||||
|
||||
// S607
|
||||
if checker.enabled(Rule::StartProcessWithPartialPath) {
|
||||
if checker.is_rule_enabled(Rule::StartProcessWithPartialPath) {
|
||||
if call_kind.is_some() {
|
||||
if let Some(arg) = call.arguments.args.first() {
|
||||
if is_partial_path(arg) {
|
||||
|
@ -383,7 +383,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
|
||||
// S609
|
||||
if checker.enabled(Rule::UnixCommandWildcardInjection) {
|
||||
if checker.is_rule_enabled(Rule::UnixCommandWildcardInjection) {
|
||||
if matches!(call_kind, Some(CallKind::Shell))
|
||||
|| matches!(
|
||||
(call_kind, shell_keyword),
|
||||
|
|
|
@ -192,7 +192,7 @@ pub(crate) fn abstract_base_class(
|
|||
let has_abstract_decorator = is_abstract(decorator_list, checker.semantic());
|
||||
has_abstract_method |= has_abstract_decorator;
|
||||
|
||||
if !checker.enabled(Rule::EmptyMethodWithoutAbstractDecorator) {
|
||||
if !checker.is_rule_enabled(Rule::EmptyMethodWithoutAbstractDecorator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ pub(crate) fn abstract_base_class(
|
|||
);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::AbstractBaseClassWithoutAbstractMethod) {
|
||||
if checker.is_rule_enabled(Rule::AbstractBaseClassWithoutAbstractMethod) {
|
||||
if !has_abstract_method {
|
||||
checker.report_diagnostic(
|
||||
AbstractBaseClassWithoutAbstractMethod {
|
||||
|
|
|
@ -139,7 +139,7 @@ fn duplicate_handler_exceptions<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::DuplicateHandlerException) {
|
||||
if checker.is_rule_enabled(Rule::DuplicateHandlerException) {
|
||||
// TODO(charlie): Handle "BaseException" and redundant exception aliases.
|
||||
if !duplicates.is_empty() {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
|
@ -209,7 +209,7 @@ pub(crate) fn duplicate_exceptions(checker: &Checker, handlers: &[ExceptHandler]
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::DuplicateTryBlockException) {
|
||||
if checker.is_rule_enabled(Rule::DuplicateTryBlockException) {
|
||||
for (name, exprs) in duplicates {
|
||||
for expr in exprs {
|
||||
let is_star = checker
|
||||
|
|
|
@ -185,7 +185,7 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
|
|||
match first {
|
||||
// Check for string literals.
|
||||
Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => {
|
||||
if checker.enabled(Rule::RawStringInException) {
|
||||
if checker.is_rule_enabled(Rule::RawStringInException) {
|
||||
if string.len() >= checker.settings.flake8_errmsg.max_string_length {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(RawStringInException, first.range());
|
||||
|
@ -205,7 +205,7 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
|
|||
}
|
||||
// Check for f-strings.
|
||||
Expr::FString(_) => {
|
||||
if checker.enabled(Rule::FStringInException) {
|
||||
if checker.is_rule_enabled(Rule::FStringInException) {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(FStringInException, first.range());
|
||||
if let Some(indentation) = whitespace::indentation(checker.source(), stmt) {
|
||||
|
@ -221,7 +221,7 @@ pub(crate) fn string_in_exception(checker: &Checker, stmt: &Stmt, exc: &Expr) {
|
|||
}
|
||||
// Check for .format() calls.
|
||||
Expr::Call(ast::ExprCall { func, .. }) => {
|
||||
if checker.enabled(Rule::DotFormatInException) {
|
||||
if checker.is_rule_enabled(Rule::DotFormatInException) {
|
||||
if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) =
|
||||
func.as_ref()
|
||||
{
|
||||
|
|
|
@ -11,7 +11,6 @@ use crate::Locator;
|
|||
use crate::checkers::ast::LintContext;
|
||||
use crate::codes::Rule;
|
||||
use crate::comments::shebang::ShebangDirective;
|
||||
use crate::settings::LinterSettings;
|
||||
|
||||
mod shebang_leading_whitespace;
|
||||
mod shebang_missing_executable_file;
|
||||
|
@ -24,7 +23,6 @@ pub(crate) fn from_tokens(
|
|||
path: &Path,
|
||||
locator: &Locator,
|
||||
comment_ranges: &CommentRanges,
|
||||
settings: &LinterSettings,
|
||||
) {
|
||||
let mut has_any_shebang = false;
|
||||
for range in comment_ranges {
|
||||
|
@ -34,7 +32,7 @@ pub(crate) fn from_tokens(
|
|||
|
||||
shebang_missing_python(range, &shebang, context);
|
||||
|
||||
if settings.rules.enabled(Rule::ShebangNotExecutable) {
|
||||
if context.is_rule_enabled(Rule::ShebangNotExecutable) {
|
||||
shebang_not_executable(path, range, context);
|
||||
}
|
||||
|
||||
|
@ -45,7 +43,7 @@ pub(crate) fn from_tokens(
|
|||
}
|
||||
|
||||
if !has_any_shebang {
|
||||
if settings.rules.enabled(Rule::ShebangMissingExecutableFile) {
|
||||
if context.is_rule_enabled(Rule::ShebangMissingExecutableFile) {
|
||||
shebang_missing_executable_file(path, context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,12 +47,12 @@ fn check_msg(checker: &Checker, msg: &Expr) {
|
|||
// Check for string concatenation and percent format.
|
||||
Expr::BinOp(ast::ExprBinOp { op, .. }) => match op {
|
||||
Operator::Add => {
|
||||
if checker.enabled(Rule::LoggingStringConcat) {
|
||||
if checker.is_rule_enabled(Rule::LoggingStringConcat) {
|
||||
checker.report_diagnostic(LoggingStringConcat, msg.range());
|
||||
}
|
||||
}
|
||||
Operator::Mod => {
|
||||
if checker.enabled(Rule::LoggingPercentFormat) {
|
||||
if checker.is_rule_enabled(Rule::LoggingPercentFormat) {
|
||||
checker.report_diagnostic(LoggingPercentFormat, msg.range());
|
||||
}
|
||||
}
|
||||
|
@ -60,13 +60,13 @@ fn check_msg(checker: &Checker, msg: &Expr) {
|
|||
},
|
||||
// Check for f-strings.
|
||||
Expr::FString(_) => {
|
||||
if checker.enabled(Rule::LoggingFString) {
|
||||
if checker.is_rule_enabled(Rule::LoggingFString) {
|
||||
checker.report_diagnostic(LoggingFString, msg.range());
|
||||
}
|
||||
}
|
||||
// Check for .format() calls.
|
||||
Expr::Call(ast::ExprCall { func, .. }) => {
|
||||
if checker.enabled(Rule::LoggingStringFormat) {
|
||||
if checker.is_rule_enabled(Rule::LoggingStringFormat) {
|
||||
if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() {
|
||||
if attr == "format" && value.is_literal_expr() {
|
||||
checker.report_diagnostic(LoggingStringFormat, msg.range());
|
||||
|
@ -178,7 +178,7 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
|
||||
// G010
|
||||
if checker.enabled(Rule::LoggingWarn) {
|
||||
if checker.is_rule_enabled(Rule::LoggingWarn) {
|
||||
if matches!(
|
||||
logging_call_type,
|
||||
LoggingCallType::LevelCall(LoggingLevel::Warn)
|
||||
|
@ -192,14 +192,14 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
|
||||
// G101
|
||||
if checker.enabled(Rule::LoggingExtraAttrClash) {
|
||||
if checker.is_rule_enabled(Rule::LoggingExtraAttrClash) {
|
||||
if let Some(extra) = call.arguments.find_keyword("extra") {
|
||||
check_log_record_attr_clash(checker, extra);
|
||||
}
|
||||
}
|
||||
|
||||
// G201, G202
|
||||
if checker.any_enabled(&[Rule::LoggingExcInfo, Rule::LoggingRedundantExcInfo]) {
|
||||
if checker.any_rule_enabled(&[Rule::LoggingExcInfo, Rule::LoggingRedundantExcInfo]) {
|
||||
if !checker.semantic().in_exception_handler() {
|
||||
return;
|
||||
}
|
||||
|
@ -209,12 +209,12 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
if let LoggingCallType::LevelCall(logging_level) = logging_call_type {
|
||||
match logging_level {
|
||||
LoggingLevel::Error => {
|
||||
if checker.enabled(Rule::LoggingExcInfo) {
|
||||
if checker.is_rule_enabled(Rule::LoggingExcInfo) {
|
||||
checker.report_diagnostic(LoggingExcInfo, range);
|
||||
}
|
||||
}
|
||||
LoggingLevel::Exception => {
|
||||
if checker.enabled(Rule::LoggingRedundantExcInfo) {
|
||||
if checker.is_rule_enabled(Rule::LoggingRedundantExcInfo) {
|
||||
checker.report_diagnostic(LoggingRedundantExcInfo, exc_info.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ pub(crate) fn bad_version_info_comparison(checker: &Checker, test: &Expr, has_el
|
|||
}
|
||||
|
||||
if matches!(op, CmpOp::Lt) {
|
||||
if checker.enabled(Rule::BadVersionInfoOrder)
|
||||
if checker.is_rule_enabled(Rule::BadVersionInfoOrder)
|
||||
// See https://github.com/astral-sh/ruff/issues/15347
|
||||
&& (checker.source_type.is_stub() || is_bad_version_info_in_non_stub_enabled(checker.settings))
|
||||
{
|
||||
|
@ -148,7 +148,7 @@ pub(crate) fn bad_version_info_comparison(checker: &Checker, test: &Expr, has_el
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::BadVersionInfoComparison) {
|
||||
if checker.is_rule_enabled(Rule::BadVersionInfoComparison) {
|
||||
checker.report_diagnostic(BadVersionInfoComparison, test.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ pub(crate) fn unrecognized_platform(checker: &Checker, test: &Expr) {
|
|||
|
||||
// "in" might also make sense but we don't currently have one.
|
||||
if !matches!(op, CmpOp::Eq | CmpOp::NotEq) {
|
||||
if checker.enabled(Rule::UnrecognizedPlatformCheck) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedPlatformCheck) {
|
||||
checker.report_diagnostic(UnrecognizedPlatformCheck, test.range());
|
||||
}
|
||||
return;
|
||||
|
@ -123,7 +123,7 @@ pub(crate) fn unrecognized_platform(checker: &Checker, test: &Expr) {
|
|||
if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = right {
|
||||
// Other values are possible but we don't need them right now.
|
||||
// This protects against typos.
|
||||
if checker.enabled(Rule::UnrecognizedPlatformName) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedPlatformName) {
|
||||
if !matches!(value.to_str(), "linux" | "win32" | "cygwin" | "darwin") {
|
||||
checker.report_diagnostic(
|
||||
UnrecognizedPlatformName {
|
||||
|
@ -134,7 +134,7 @@ pub(crate) fn unrecognized_platform(checker: &Checker, test: &Expr) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::UnrecognizedPlatformCheck) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedPlatformCheck) {
|
||||
checker.report_diagnostic(UnrecognizedPlatformCheck, test.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ pub(crate) fn unrecognized_version_info(checker: &Checker, test: &Expr) {
|
|||
if let Some(expected) = ExpectedComparator::try_from(left) {
|
||||
version_check(checker, expected, test, *op, comparator);
|
||||
} else {
|
||||
if checker.enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
checker.report_diagnostic(UnrecognizedVersionInfoCheck, test.range());
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ fn version_check(
|
|||
// Single digit comparison, e.g., `sys.version_info[0] == 2`.
|
||||
if expected == ExpectedComparator::MajorDigit {
|
||||
if !is_int_constant(comparator) {
|
||||
if checker.enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
checker.report_diagnostic(UnrecognizedVersionInfoCheck, test.range());
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ fn version_check(
|
|||
|
||||
// Tuple comparison, e.g., `sys.version_info == (3, 4)`.
|
||||
let Expr::Tuple(tuple) = comparator else {
|
||||
if checker.enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
checker.report_diagnostic(UnrecognizedVersionInfoCheck, test.range());
|
||||
}
|
||||
return;
|
||||
|
@ -181,18 +181,18 @@ fn version_check(
|
|||
if !tuple.iter().all(is_int_constant) {
|
||||
// All tuple elements must be integers, e.g., `sys.version_info == (3, 4)` instead of
|
||||
// `sys.version_info == (3.0, 4)`.
|
||||
if checker.enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
if checker.is_rule_enabled(Rule::UnrecognizedVersionInfoCheck) {
|
||||
checker.report_diagnostic(UnrecognizedVersionInfoCheck, test.range());
|
||||
}
|
||||
} else if tuple.len() > 2 {
|
||||
// Must compare against major and minor version only, e.g., `sys.version_info == (3, 4)`
|
||||
// instead of `sys.version_info == (3, 4, 0)`.
|
||||
if checker.enabled(Rule::PatchVersionComparison) {
|
||||
if checker.is_rule_enabled(Rule::PatchVersionComparison) {
|
||||
checker.report_diagnostic(PatchVersionComparison, test.range());
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::WrongTupleLengthVersionComparison) {
|
||||
if checker.is_rule_enabled(Rule::WrongTupleLengthVersionComparison) {
|
||||
if op == CmpOp::Eq || op == CmpOp::NotEq {
|
||||
let expected_length = match expected {
|
||||
ExpectedComparator::MajorTuple => 1,
|
||||
|
|
|
@ -713,7 +713,7 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
|
|||
range: _,
|
||||
node_index: _,
|
||||
}) => {
|
||||
if checker.enabled(Rule::PytestFixtureIncorrectParenthesesStyle) {
|
||||
if checker.is_rule_enabled(Rule::PytestFixtureIncorrectParenthesesStyle) {
|
||||
if !checker.settings.flake8_pytest_style.fixture_parentheses
|
||||
&& arguments.args.is_empty()
|
||||
&& arguments.keywords.is_empty()
|
||||
|
@ -739,7 +739,7 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestFixturePositionalArgs) {
|
||||
if checker.is_rule_enabled(Rule::PytestFixturePositionalArgs) {
|
||||
if !arguments.args.is_empty() {
|
||||
checker.report_diagnostic(
|
||||
PytestFixturePositionalArgs {
|
||||
|
@ -750,7 +750,7 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestExtraneousScopeFunction) {
|
||||
if checker.is_rule_enabled(Rule::PytestExtraneousScopeFunction) {
|
||||
if let Some(keyword) = arguments.find_keyword("scope") {
|
||||
if keyword_is_literal(keyword, "function") {
|
||||
let mut diagnostic = checker
|
||||
|
@ -769,7 +769,7 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
if checker.enabled(Rule::PytestFixtureIncorrectParenthesesStyle) {
|
||||
if checker.is_rule_enabled(Rule::PytestFixtureIncorrectParenthesesStyle) {
|
||||
if checker.settings.flake8_pytest_style.fixture_parentheses {
|
||||
let fix = Fix::safe_edit(Edit::insertion(
|
||||
Parentheses::Empty.to_string(),
|
||||
|
@ -796,7 +796,7 @@ fn check_fixture_returns(checker: &Checker, name: &str, body: &[Stmt], returns:
|
|||
visitor.visit_stmt(stmt);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestUselessYieldFixture) {
|
||||
if checker.is_rule_enabled(Rule::PytestUselessYieldFixture) {
|
||||
let Some(stmt) = body.last() else {
|
||||
return;
|
||||
};
|
||||
|
@ -924,7 +924,7 @@ fn check_fixture_addfinalizer(checker: &Checker, parameters: &Parameters, body:
|
|||
/// PT024, PT025
|
||||
fn check_fixture_marks(checker: &Checker, decorators: &[Decorator]) {
|
||||
for (expr, marker) in get_mark_decorators(decorators, checker.semantic()) {
|
||||
if checker.enabled(Rule::PytestUnnecessaryAsyncioMarkOnFixture) {
|
||||
if checker.is_rule_enabled(Rule::PytestUnnecessaryAsyncioMarkOnFixture) {
|
||||
if marker == "asyncio" {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(PytestUnnecessaryAsyncioMarkOnFixture, expr.range());
|
||||
|
@ -933,7 +933,7 @@ fn check_fixture_marks(checker: &Checker, decorators: &[Decorator]) {
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestErroneousUseFixturesOnFixture) {
|
||||
if checker.is_rule_enabled(Rule::PytestErroneousUseFixturesOnFixture) {
|
||||
if marker == "usefixtures" {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(PytestErroneousUseFixturesOnFixture, expr.range());
|
||||
|
@ -954,35 +954,35 @@ pub(crate) fn fixture(
|
|||
) {
|
||||
let decorator = fixture_decorator(decorators, checker.semantic());
|
||||
if let Some(decorator) = decorator {
|
||||
if checker.enabled(Rule::PytestFixtureIncorrectParenthesesStyle)
|
||||
|| checker.enabled(Rule::PytestFixturePositionalArgs)
|
||||
|| checker.enabled(Rule::PytestExtraneousScopeFunction)
|
||||
if checker.is_rule_enabled(Rule::PytestFixtureIncorrectParenthesesStyle)
|
||||
|| checker.is_rule_enabled(Rule::PytestFixturePositionalArgs)
|
||||
|| checker.is_rule_enabled(Rule::PytestExtraneousScopeFunction)
|
||||
{
|
||||
check_fixture_decorator(checker, name, decorator);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestDeprecatedYieldFixture) {
|
||||
if checker.is_rule_enabled(Rule::PytestDeprecatedYieldFixture) {
|
||||
check_fixture_decorator_name(checker, decorator);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestUselessYieldFixture)
|
||||
if checker.is_rule_enabled(Rule::PytestUselessYieldFixture)
|
||||
&& !is_abstract(decorators, checker.semantic())
|
||||
{
|
||||
check_fixture_returns(checker, name, body, returns);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestFixtureFinalizerCallback) {
|
||||
if checker.is_rule_enabled(Rule::PytestFixtureFinalizerCallback) {
|
||||
check_fixture_addfinalizer(checker, parameters, body);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestUnnecessaryAsyncioMarkOnFixture)
|
||||
|| checker.enabled(Rule::PytestErroneousUseFixturesOnFixture)
|
||||
if checker.is_rule_enabled(Rule::PytestUnnecessaryAsyncioMarkOnFixture)
|
||||
|| checker.is_rule_enabled(Rule::PytestErroneousUseFixturesOnFixture)
|
||||
{
|
||||
check_fixture_marks(checker, decorators);
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestFixtureParamWithoutValue) && name.starts_with("test_") {
|
||||
if checker.is_rule_enabled(Rule::PytestFixtureParamWithoutValue) && name.starts_with("test_") {
|
||||
check_test_function_args(checker, parameters, decorators);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,8 +235,9 @@ fn check_useless_usefixtures(checker: &Checker, decorator: &Decorator, marker: &
|
|||
}
|
||||
|
||||
pub(crate) fn marks(checker: &Checker, decorators: &[Decorator]) {
|
||||
let enforce_parentheses = checker.enabled(Rule::PytestIncorrectMarkParenthesesStyle);
|
||||
let enforce_useless_usefixtures = checker.enabled(Rule::PytestUseFixturesWithoutParameters);
|
||||
let enforce_parentheses = checker.is_rule_enabled(Rule::PytestIncorrectMarkParenthesesStyle);
|
||||
let enforce_useless_usefixtures =
|
||||
checker.is_rule_enabled(Rule::PytestUseFixturesWithoutParameters);
|
||||
|
||||
for (decorator, marker) in get_mark_decorators(decorators, checker.semantic()) {
|
||||
if enforce_parentheses {
|
||||
|
|
|
@ -865,7 +865,7 @@ pub(crate) fn parametrize(checker: &Checker, call: &ExprCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestParametrizeNamesWrongType) {
|
||||
if checker.is_rule_enabled(Rule::PytestParametrizeNamesWrongType) {
|
||||
let names = call.arguments.find_argument_value("argnames", 0);
|
||||
let values = call.arguments.find_argument_value("argvalues", 1);
|
||||
|
||||
|
@ -873,7 +873,7 @@ pub(crate) fn parametrize(checker: &Checker, call: &ExprCall) {
|
|||
check_names(checker, call, names, values);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::PytestParametrizeValuesWrongType) {
|
||||
if checker.is_rule_enabled(Rule::PytestParametrizeValuesWrongType) {
|
||||
let names = call.arguments.find_argument_value("argnames", 0);
|
||||
let values = call.arguments.find_argument_value("argvalues", 1);
|
||||
|
||||
|
@ -881,7 +881,7 @@ pub(crate) fn parametrize(checker: &Checker, call: &ExprCall) {
|
|||
check_values(checker, names, values);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::PytestDuplicateParametrizeTestCases) {
|
||||
if checker.is_rule_enabled(Rule::PytestDuplicateParametrizeTestCases) {
|
||||
if let Some(values) = call.arguments.find_argument_value("argvalues", 1) {
|
||||
check_duplicates(checker, values);
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ const fn is_non_trivial_with_body(body: &[Stmt]) -> bool {
|
|||
|
||||
pub(crate) fn raises_call(checker: &Checker, call: &ast::ExprCall) {
|
||||
if is_pytest_raises(&call.func, checker.semantic()) {
|
||||
if checker.enabled(Rule::PytestRaisesWithoutException) {
|
||||
if checker.is_rule_enabled(Rule::PytestRaisesWithoutException) {
|
||||
if call
|
||||
.arguments
|
||||
.find_argument("expected_exception", 0)
|
||||
|
@ -182,7 +182,7 @@ pub(crate) fn raises_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestRaisesTooBroad) {
|
||||
if checker.is_rule_enabled(Rule::PytestRaisesTooBroad) {
|
||||
// Pytest.raises has two overloads
|
||||
// ```py
|
||||
// with raises(expected_exception: type[E] | tuple[type[E], ...], *, match: str | Pattern[str] | None = ...) → RaisesContext[E] as excinfo
|
||||
|
|
|
@ -172,13 +172,13 @@ const fn is_non_trivial_with_body(body: &[Stmt]) -> bool {
|
|||
/// PT029, PT030
|
||||
pub(crate) fn warns_call(checker: &Checker, call: &ast::ExprCall) {
|
||||
if is_pytest_warns(&call.func, checker.semantic()) {
|
||||
if checker.enabled(Rule::PytestWarnsWithoutWarning) {
|
||||
if checker.is_rule_enabled(Rule::PytestWarnsWithoutWarning) {
|
||||
if call.arguments.is_empty() {
|
||||
checker.report_diagnostic(PytestWarnsWithoutWarning, call.func.range());
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::PytestWarnsTooBroad) {
|
||||
if checker.is_rule_enabled(Rule::PytestWarnsTooBroad) {
|
||||
if let Some(warning) = call.arguments.find_argument_value("expected_warning", 0) {
|
||||
if call
|
||||
.arguments
|
||||
|
|
|
@ -332,7 +332,7 @@ fn strings(checker: &Checker, sequence: &[TextRange]) {
|
|||
for (range, trivia) in sequence.iter().zip(trivia) {
|
||||
if trivia.is_multiline {
|
||||
// If multiline strings aren't enforced, ignore it.
|
||||
if !checker.enabled(Rule::BadQuotesMultilineString) {
|
||||
if !checker.is_rule_enabled(Rule::BadQuotesMultilineString) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,7 @@ fn strings(checker: &Checker, sequence: &[TextRange]) {
|
|||
&& !relax_quote
|
||||
{
|
||||
// If inline strings aren't enforced, ignore it.
|
||||
if !checker.enabled(Rule::BadQuotesInlineString) {
|
||||
if !checker.is_rule_enabled(Rule::BadQuotesInlineString) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -454,13 +454,14 @@ pub(crate) fn check_string_quotes(checker: &Checker, string_like: StringLike) {
|
|||
let ranges: Vec<_> = string_like.parts().map(|part| part.range()).collect();
|
||||
|
||||
if checker.semantic().in_pep_257_docstring() {
|
||||
if checker.enabled(Rule::BadQuotesDocstring) {
|
||||
if checker.is_rule_enabled(Rule::BadQuotesDocstring) {
|
||||
for range in ranges {
|
||||
docstring(checker, range);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if checker.any_enabled(&[Rule::BadQuotesInlineString, Rule::BadQuotesMultilineString]) {
|
||||
if checker.any_rule_enabled(&[Rule::BadQuotesInlineString, Rule::BadQuotesMultilineString])
|
||||
{
|
||||
strings(checker, &ranges);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -700,7 +700,7 @@ pub(crate) fn function(checker: &Checker, function_def: &ast::StmtFunctionDef) {
|
|||
return;
|
||||
}
|
||||
|
||||
if checker.any_enabled(&[
|
||||
if checker.any_rule_enabled(&[
|
||||
Rule::SuperfluousElseReturn,
|
||||
Rule::SuperfluousElseRaise,
|
||||
Rule::SuperfluousElseContinue,
|
||||
|
@ -716,18 +716,18 @@ pub(crate) fn function(checker: &Checker, function_def: &ast::StmtFunctionDef) {
|
|||
|
||||
// If we have at least one non-`None` return...
|
||||
if result_exists(&stack.returns) {
|
||||
if checker.enabled(Rule::ImplicitReturnValue) {
|
||||
if checker.is_rule_enabled(Rule::ImplicitReturnValue) {
|
||||
implicit_return_value(checker, &stack);
|
||||
}
|
||||
if checker.enabled(Rule::ImplicitReturn) {
|
||||
if checker.is_rule_enabled(Rule::ImplicitReturn) {
|
||||
implicit_return(checker, function_def, last_stmt);
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::UnnecessaryAssign) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryAssign) {
|
||||
unnecessary_assign(checker, &stack);
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::UnnecessaryReturnNone) {
|
||||
if checker.is_rule_enabled(Rule::UnnecessaryReturnNone) {
|
||||
// Skip functions that have a return annotation that is not `None`.
|
||||
if returns.as_deref().is_none_or(Expr::is_none_literal_expr) {
|
||||
unnecessary_return_none(checker, decorator_list, &stack);
|
||||
|
|
|
@ -246,7 +246,7 @@ fn collect_typing_references<'a>(
|
|||
// if TC004 is enabled we shouldn't emit a TC007 for a reference to
|
||||
// a binding that would emit a TC004, otherwise the fixes will never
|
||||
// stabilize and keep going in circles
|
||||
if checker.enabled(Rule::RuntimeImportInTypeCheckingBlock)
|
||||
if checker.is_rule_enabled(Rule::RuntimeImportInTypeCheckingBlock)
|
||||
&& checker
|
||||
.semantic()
|
||||
.binding(binding_id)
|
||||
|
@ -267,7 +267,7 @@ pub(crate) fn quoted_type_alias(
|
|||
expr: &Expr,
|
||||
annotation_expr: &ast::ExprStringLiteral,
|
||||
) {
|
||||
if checker.enabled(Rule::RuntimeStringUnion) {
|
||||
if checker.is_rule_enabled(Rule::RuntimeStringUnion) {
|
||||
// this should return a TC010 error instead
|
||||
if let Some(Expr::BinOp(ast::ExprBinOp {
|
||||
op: Operator::BitOr,
|
||||
|
|
|
@ -347,7 +347,7 @@ pub(crate) fn typing_only_runtime_import(
|
|||
}
|
||||
};
|
||||
|
||||
if !checker.enabled(rule_for(import_type)) {
|
||||
if !checker.is_rule_enabled(rule_for(import_type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -412,7 +412,7 @@ pub(crate) fn unused_arguments(checker: &Checker, scope: &Scope) {
|
|||
&checker.settings.pep8_naming.staticmethod_decorators,
|
||||
) {
|
||||
function_type::FunctionType::Function => {
|
||||
if checker.enabled(Argumentable::Function.rule_code())
|
||||
if checker.is_rule_enabled(Argumentable::Function.rule_code())
|
||||
&& !function_type::is_stub(function_def, checker.semantic())
|
||||
&& !is_not_implemented_stub_with_variable(function_def, checker.semantic())
|
||||
&& !visibility::is_overload(decorator_list, checker.semantic())
|
||||
|
@ -421,7 +421,7 @@ pub(crate) fn unused_arguments(checker: &Checker, scope: &Scope) {
|
|||
}
|
||||
}
|
||||
function_type::FunctionType::Method => {
|
||||
if checker.enabled(Argumentable::Method.rule_code())
|
||||
if checker.is_rule_enabled(Argumentable::Method.rule_code())
|
||||
&& !function_type::is_stub(function_def, checker.semantic())
|
||||
&& !is_not_implemented_stub_with_variable(function_def, checker.semantic())
|
||||
&& (!visibility::is_magic(name)
|
||||
|
@ -435,7 +435,7 @@ pub(crate) fn unused_arguments(checker: &Checker, scope: &Scope) {
|
|||
}
|
||||
}
|
||||
function_type::FunctionType::ClassMethod => {
|
||||
if checker.enabled(Argumentable::ClassMethod.rule_code())
|
||||
if checker.is_rule_enabled(Argumentable::ClassMethod.rule_code())
|
||||
&& !function_type::is_stub(function_def, checker.semantic())
|
||||
&& !is_not_implemented_stub_with_variable(function_def, checker.semantic())
|
||||
&& (!visibility::is_magic(name)
|
||||
|
@ -449,7 +449,7 @@ pub(crate) fn unused_arguments(checker: &Checker, scope: &Scope) {
|
|||
}
|
||||
}
|
||||
function_type::FunctionType::StaticMethod => {
|
||||
if checker.enabled(Argumentable::StaticMethod.rule_code())
|
||||
if checker.is_rule_enabled(Argumentable::StaticMethod.rule_code())
|
||||
&& !function_type::is_stub(function_def, checker.semantic())
|
||||
&& !is_not_implemented_stub_with_variable(function_def, checker.semantic())
|
||||
&& (!visibility::is_magic(name)
|
||||
|
@ -463,7 +463,7 @@ pub(crate) fn unused_arguments(checker: &Checker, scope: &Scope) {
|
|||
}
|
||||
}
|
||||
function_type::FunctionType::NewMethod => {
|
||||
if checker.enabled(Argumentable::StaticMethod.rule_code())
|
||||
if checker.is_rule_enabled(Argumentable::StaticMethod.rule_code())
|
||||
&& !function_type::is_stub(function_def, checker.semantic())
|
||||
&& !is_not_implemented_stub_with_variable(function_def, checker.semantic())
|
||||
&& !visibility::is_abstract(decorator_list, checker.semantic())
|
||||
|
@ -479,7 +479,7 @@ pub(crate) fn unused_arguments(checker: &Checker, scope: &Scope) {
|
|||
}
|
||||
ScopeKind::Lambda(ast::ExprLambda { parameters, .. }) => {
|
||||
if let Some(parameters) = parameters {
|
||||
if checker.enabled(Argumentable::Lambda.rule_code()) {
|
||||
if checker.is_rule_enabled(Argumentable::Lambda.rule_code()) {
|
||||
function(Argumentable::Lambda, parameters, scope, checker);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,21 +181,16 @@ pub(crate) fn call(checker: &Checker, func: &Expr) {
|
|||
|
||||
let range = func.range();
|
||||
match attr.as_str() {
|
||||
"isnull" if checker.settings.rules.enabled(Rule::PandasUseOfDotIsNull) => {
|
||||
"isnull" if checker.is_rule_enabled(Rule::PandasUseOfDotIsNull) => {
|
||||
checker.report_diagnostic(PandasUseOfDotIsNull, range);
|
||||
}
|
||||
"notnull" if checker.settings.rules.enabled(Rule::PandasUseOfDotNotNull) => {
|
||||
"notnull" if checker.is_rule_enabled(Rule::PandasUseOfDotNotNull) => {
|
||||
checker.report_diagnostic(PandasUseOfDotNotNull, range);
|
||||
}
|
||||
"pivot" | "unstack"
|
||||
if checker
|
||||
.settings
|
||||
.rules
|
||||
.enabled(Rule::PandasUseOfDotPivotOrUnstack) =>
|
||||
{
|
||||
"pivot" | "unstack" if checker.is_rule_enabled(Rule::PandasUseOfDotPivotOrUnstack) => {
|
||||
checker.report_diagnostic(PandasUseOfDotPivotOrUnstack, range);
|
||||
}
|
||||
"stack" if checker.settings.rules.enabled(Rule::PandasUseOfDotStack) => {
|
||||
"stack" if checker.is_rule_enabled(Rule::PandasUseOfDotStack) => {
|
||||
checker.report_diagnostic(PandasUseOfDotStack, range);
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -163,13 +163,13 @@ pub(crate) fn subscript(checker: &Checker, value: &Expr, expr: &Expr) {
|
|||
let range = expr.range();
|
||||
|
||||
match attr.as_str() {
|
||||
"ix" if checker.settings.rules.enabled(Rule::PandasUseOfDotIx) => {
|
||||
"ix" if checker.is_rule_enabled(Rule::PandasUseOfDotIx) => {
|
||||
checker.report_diagnostic(PandasUseOfDotIx, range)
|
||||
}
|
||||
"at" if checker.settings.rules.enabled(Rule::PandasUseOfDotAt) => {
|
||||
"at" if checker.is_rule_enabled(Rule::PandasUseOfDotAt) => {
|
||||
checker.report_diagnostic(PandasUseOfDotAt, range)
|
||||
}
|
||||
"iat" if checker.settings.rules.enabled(Rule::PandasUseOfDotIat) => {
|
||||
"iat" if checker.is_rule_enabled(Rule::PandasUseOfDotIat) => {
|
||||
checker.report_diagnostic(PandasUseOfDotIat, range)
|
||||
}
|
||||
_ => return,
|
||||
|
|
|
@ -243,7 +243,7 @@ pub(crate) fn invalid_first_argument_name(checker: &Checker, scope: &Scope) {
|
|||
return;
|
||||
}
|
||||
};
|
||||
if !checker.enabled(function_type.rule()) {
|
||||
if !checker.is_rule_enabled(function_type.rule()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
|||
|
||||
if !helpers::is_constant_non_singleton(next) {
|
||||
if let Some(op) = EqCmpOp::try_from(*op) {
|
||||
if checker.enabled(Rule::NoneComparison) && comparator.is_none_literal_expr() {
|
||||
if checker.is_rule_enabled(Rule::NoneComparison) && comparator.is_none_literal_expr() {
|
||||
match op {
|
||||
EqCmpOp::Eq => {
|
||||
let diagnostic =
|
||||
|
@ -239,7 +239,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::TrueFalseComparison) {
|
||||
if checker.is_rule_enabled(Rule::TrueFalseComparison) {
|
||||
if let Expr::BooleanLiteral(ast::ExprBooleanLiteral { value, .. }) = comparator {
|
||||
match op {
|
||||
EqCmpOp::Eq => {
|
||||
|
@ -290,7 +290,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
|||
}
|
||||
|
||||
if let Some(op) = EqCmpOp::try_from(*op) {
|
||||
if checker.enabled(Rule::NoneComparison) && next.is_none_literal_expr() {
|
||||
if checker.is_rule_enabled(Rule::NoneComparison) && next.is_none_literal_expr() {
|
||||
match op {
|
||||
EqCmpOp::Eq => {
|
||||
let diagnostic =
|
||||
|
@ -307,7 +307,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::TrueFalseComparison) {
|
||||
if checker.is_rule_enabled(Rule::TrueFalseComparison) {
|
||||
if let Expr::BooleanLiteral(ast::ExprBooleanLiteral { value, .. }) = next {
|
||||
match op {
|
||||
EqCmpOp::Eq => {
|
||||
|
|
|
@ -96,7 +96,7 @@ pub(crate) fn not_tests(checker: &Checker, unary_op: &ast::ExprUnaryOp) {
|
|||
|
||||
match &**ops {
|
||||
[CmpOp::In] => {
|
||||
if checker.enabled(Rule::NotInTest) {
|
||||
if checker.is_rule_enabled(Rule::NotInTest) {
|
||||
let mut diagnostic = checker.report_diagnostic(NotInTest, unary_op.operand.range());
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
pad(
|
||||
|
@ -116,7 +116,7 @@ pub(crate) fn not_tests(checker: &Checker, unary_op: &ast::ExprUnaryOp) {
|
|||
}
|
||||
}
|
||||
[CmpOp::Is] => {
|
||||
if checker.enabled(Rule::NotIsTest) {
|
||||
if checker.is_rule_enabled(Rule::NotIsTest) {
|
||||
let mut diagnostic = checker.report_diagnostic(NotIsTest, unary_op.operand.range());
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
pad(
|
||||
|
|
|
@ -6,7 +6,6 @@ use ruff_text_size::{TextLen, TextRange, TextSize};
|
|||
use crate::Locator;
|
||||
use crate::checkers::ast::LintContext;
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::{AlwaysFixableViolation, Applicability, Edit, Fix};
|
||||
|
||||
/// ## What it does
|
||||
|
@ -88,7 +87,6 @@ pub(crate) fn trailing_whitespace(
|
|||
line: &Line,
|
||||
locator: &Locator,
|
||||
indexer: &Indexer,
|
||||
settings: &LinterSettings,
|
||||
context: &LintContext,
|
||||
) {
|
||||
let whitespace_len: TextSize = line
|
||||
|
@ -106,7 +104,7 @@ pub(crate) fn trailing_whitespace(
|
|||
Applicability::Safe
|
||||
};
|
||||
if range == line.range() {
|
||||
if settings.rules.enabled(Rule::BlankLineWithWhitespace) {
|
||||
if context.is_rule_enabled(Rule::BlankLineWithWhitespace) {
|
||||
let mut diagnostic = context.report_diagnostic(BlankLineWithWhitespace, range);
|
||||
// Remove any preceding continuations, to avoid introducing a potential
|
||||
// syntax error.
|
||||
|
@ -120,7 +118,7 @@ pub(crate) fn trailing_whitespace(
|
|||
applicability,
|
||||
));
|
||||
}
|
||||
} else if settings.rules.enabled(Rule::TrailingWhitespace) {
|
||||
} else if context.is_rule_enabled(Rule::TrailingWhitespace) {
|
||||
let mut diagnostic = context.report_diagnostic(TrailingWhitespace, range);
|
||||
diagnostic.set_fix(Fix::applicable_edit(
|
||||
Edit::range_deletion(range),
|
||||
|
|
|
@ -915,7 +915,7 @@ pub(crate) fn check_docstring(
|
|||
};
|
||||
|
||||
// DOC201
|
||||
if checker.enabled(Rule::DocstringMissingReturns) {
|
||||
if checker.is_rule_enabled(Rule::DocstringMissingReturns) {
|
||||
if should_document_returns(function_def)
|
||||
&& !returns_documented(docstring, &docstring_sections, convention)
|
||||
{
|
||||
|
@ -953,7 +953,7 @@ pub(crate) fn check_docstring(
|
|||
}
|
||||
|
||||
// DOC402
|
||||
if checker.enabled(Rule::DocstringMissingYields) {
|
||||
if checker.is_rule_enabled(Rule::DocstringMissingYields) {
|
||||
if !yields_documented(docstring, &docstring_sections, convention) {
|
||||
if !body_entries.yields.is_empty() {
|
||||
match function_def.returns.as_deref() {
|
||||
|
@ -974,7 +974,7 @@ pub(crate) fn check_docstring(
|
|||
}
|
||||
|
||||
// DOC501
|
||||
if checker.enabled(Rule::DocstringMissingException) {
|
||||
if checker.is_rule_enabled(Rule::DocstringMissingException) {
|
||||
for body_raise in &body_entries.raised_exceptions {
|
||||
let Some(name) = body_raise.qualified_name.segments().last() else {
|
||||
continue;
|
||||
|
@ -1006,7 +1006,7 @@ pub(crate) fn check_docstring(
|
|||
// document that it raises an exception without including the exception in the implementation.
|
||||
if !visibility::is_abstract(&function_def.decorator_list, semantic) {
|
||||
// DOC202
|
||||
if checker.enabled(Rule::DocstringExtraneousReturns) {
|
||||
if checker.is_rule_enabled(Rule::DocstringExtraneousReturns) {
|
||||
if docstring_sections.returns.is_some() {
|
||||
if body_entries.returns.is_empty()
|
||||
|| body_entries.returns.iter().all(ReturnEntry::is_implicit)
|
||||
|
@ -1017,7 +1017,7 @@ pub(crate) fn check_docstring(
|
|||
}
|
||||
|
||||
// DOC403
|
||||
if checker.enabled(Rule::DocstringExtraneousYields) {
|
||||
if checker.is_rule_enabled(Rule::DocstringExtraneousYields) {
|
||||
if docstring_sections.yields.is_some() {
|
||||
if body_entries.yields.is_empty() {
|
||||
checker.report_diagnostic(DocstringExtraneousYields, docstring.range());
|
||||
|
@ -1026,7 +1026,7 @@ pub(crate) fn check_docstring(
|
|||
}
|
||||
|
||||
// DOC502
|
||||
if checker.enabled(Rule::DocstringExtraneousException) {
|
||||
if checker.is_rule_enabled(Rule::DocstringExtraneousException) {
|
||||
if let Some(docstring_raises) = docstring_sections.raises {
|
||||
let mut extraneous_exceptions = Vec::new();
|
||||
for docstring_raise in &docstring_raises.raised_exceptions {
|
||||
|
|
|
@ -170,8 +170,8 @@ pub(crate) fn blank_before_after_class(checker: &Checker, docstring: &Docstring)
|
|||
return;
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::IncorrectBlankLineBeforeClass)
|
||||
|| checker.enabled(Rule::BlankLineBeforeClass)
|
||||
if checker.is_rule_enabled(Rule::IncorrectBlankLineBeforeClass)
|
||||
|| checker.is_rule_enabled(Rule::BlankLineBeforeClass)
|
||||
{
|
||||
let mut lines = UniversalNewlineIterator::with_offset(
|
||||
checker.locator().slice(between_range),
|
||||
|
@ -191,7 +191,7 @@ pub(crate) fn blank_before_after_class(checker: &Checker, docstring: &Docstring)
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::BlankLineBeforeClass) {
|
||||
if checker.is_rule_enabled(Rule::BlankLineBeforeClass) {
|
||||
if blank_lines_before != 0 {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(BlankLineBeforeClass, docstring.range());
|
||||
|
@ -202,7 +202,7 @@ pub(crate) fn blank_before_after_class(checker: &Checker, docstring: &Docstring)
|
|||
)));
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::IncorrectBlankLineBeforeClass) {
|
||||
if checker.is_rule_enabled(Rule::IncorrectBlankLineBeforeClass) {
|
||||
if blank_lines_before != 1 {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(IncorrectBlankLineBeforeClass, docstring.range());
|
||||
|
@ -216,7 +216,7 @@ pub(crate) fn blank_before_after_class(checker: &Checker, docstring: &Docstring)
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::IncorrectBlankLineAfterClass) {
|
||||
if checker.is_rule_enabled(Rule::IncorrectBlankLineAfterClass) {
|
||||
let class_after_docstring_range = TextRange::new(docstring.end(), class.end());
|
||||
let class_after_docstring = checker.locator().slice(class_after_docstring_range);
|
||||
let mut lines = UniversalNewlineIterator::with_offset(
|
||||
|
|
|
@ -107,7 +107,7 @@ pub(crate) fn blank_before_after_function(checker: &Checker, docstring: &Docstri
|
|||
return;
|
||||
};
|
||||
|
||||
if checker.enabled(Rule::BlankLineBeforeFunction) {
|
||||
if checker.is_rule_enabled(Rule::BlankLineBeforeFunction) {
|
||||
let before = checker
|
||||
.locator()
|
||||
.slice(TextRange::new(function.start(), docstring.start()));
|
||||
|
@ -140,7 +140,7 @@ pub(crate) fn blank_before_after_function(checker: &Checker, docstring: &Docstri
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::BlankLineAfterFunction) {
|
||||
if checker.is_rule_enabled(Rule::BlankLineAfterFunction) {
|
||||
let after = checker
|
||||
.locator()
|
||||
.slice(TextRange::new(docstring.end(), function.end()));
|
||||
|
|
|
@ -220,7 +220,7 @@ pub(crate) fn indent(checker: &Checker, docstring: &Docstring) {
|
|||
// yet.
|
||||
has_seen_tab = has_seen_tab || line_indent.contains('\t');
|
||||
|
||||
if checker.enabled(Rule::UnderIndentation) {
|
||||
if checker.is_rule_enabled(Rule::UnderIndentation) {
|
||||
// We report under-indentation on every line. This isn't great, but enables
|
||||
// fix.
|
||||
if (is_last || !is_blank) && line_indent_size < docstring_indent_size {
|
||||
|
@ -264,13 +264,13 @@ pub(crate) fn indent(checker: &Checker, docstring: &Docstring) {
|
|||
current = lines.next();
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::DocstringTabIndentation) {
|
||||
if checker.is_rule_enabled(Rule::DocstringTabIndentation) {
|
||||
if has_seen_tab {
|
||||
checker.report_diagnostic(DocstringTabIndentation, docstring.range());
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::OverIndentation) {
|
||||
if checker.is_rule_enabled(Rule::OverIndentation) {
|
||||
// If every line (except the last) is over-indented...
|
||||
if let Some(smallest_over_indent_size) = smallest_over_indent_size {
|
||||
for line in over_indented_lines {
|
||||
|
|
|
@ -155,7 +155,7 @@ pub(crate) fn multi_line_summary_start(checker: &Checker, docstring: &Docstring)
|
|||
};
|
||||
|
||||
if is_triple_quote(&first_line) {
|
||||
if checker.enabled(Rule::MultiLineSummaryFirstLine) {
|
||||
if checker.is_rule_enabled(Rule::MultiLineSummaryFirstLine) {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(MultiLineSummaryFirstLine, docstring.range());
|
||||
// Delete until first non-whitespace char.
|
||||
|
@ -179,7 +179,7 @@ pub(crate) fn multi_line_summary_start(checker: &Checker, docstring: &Docstring)
|
|||
// ```
|
||||
return;
|
||||
} else {
|
||||
if checker.enabled(Rule::MultiLineSummarySecondLine) {
|
||||
if checker.is_rule_enabled(Rule::MultiLineSummarySecondLine) {
|
||||
let mut diagnostic =
|
||||
checker.report_diagnostic(MultiLineSummarySecondLine, docstring.range());
|
||||
let mut indentation = Cow::Borrowed(docstring.compute_indentation());
|
||||
|
|
|
@ -45,7 +45,7 @@ pub(crate) fn not_empty(checker: &Checker, docstring: &Docstring) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::EmptyDocstring) {
|
||||
if checker.is_rule_enabled(Rule::EmptyDocstring) {
|
||||
checker.report_diagnostic(EmptyDocstring, docstring.range());
|
||||
}
|
||||
false
|
||||
|
|
|
@ -551,7 +551,7 @@ pub(crate) fn not_missing(
|
|||
if checker.source_type.is_ipynb() {
|
||||
return true;
|
||||
}
|
||||
if checker.enabled(Rule::UndocumentedPublicModule) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicModule) {
|
||||
checker.report_diagnostic(UndocumentedPublicModule, TextRange::default());
|
||||
}
|
||||
false
|
||||
|
@ -560,7 +560,7 @@ pub(crate) fn not_missing(
|
|||
kind: ModuleKind::Package,
|
||||
..
|
||||
}) => {
|
||||
if checker.enabled(Rule::UndocumentedPublicPackage) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicPackage) {
|
||||
checker.report_diagnostic(UndocumentedPublicPackage, TextRange::default());
|
||||
}
|
||||
false
|
||||
|
@ -569,7 +569,7 @@ pub(crate) fn not_missing(
|
|||
kind: MemberKind::Class(class),
|
||||
..
|
||||
}) => {
|
||||
if checker.enabled(Rule::UndocumentedPublicClass) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicClass) {
|
||||
checker.report_diagnostic(UndocumentedPublicClass, class.identifier());
|
||||
}
|
||||
false
|
||||
|
@ -578,7 +578,7 @@ pub(crate) fn not_missing(
|
|||
kind: MemberKind::NestedClass(function),
|
||||
..
|
||||
}) => {
|
||||
if checker.enabled(Rule::UndocumentedPublicNestedClass) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicNestedClass) {
|
||||
checker.report_diagnostic(UndocumentedPublicNestedClass, function.identifier());
|
||||
}
|
||||
false
|
||||
|
@ -590,7 +590,7 @@ pub(crate) fn not_missing(
|
|||
if is_overload(&function.decorator_list, checker.semantic()) {
|
||||
true
|
||||
} else {
|
||||
if checker.enabled(Rule::UndocumentedPublicFunction) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicFunction) {
|
||||
checker.report_diagnostic(UndocumentedPublicFunction, function.identifier());
|
||||
}
|
||||
false
|
||||
|
@ -605,22 +605,22 @@ pub(crate) fn not_missing(
|
|||
{
|
||||
true
|
||||
} else if is_init(&function.name) {
|
||||
if checker.enabled(Rule::UndocumentedPublicInit) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicInit) {
|
||||
checker.report_diagnostic(UndocumentedPublicInit, function.identifier());
|
||||
}
|
||||
true
|
||||
} else if is_new(&function.name) || is_call(&function.name) {
|
||||
if checker.enabled(Rule::UndocumentedPublicMethod) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicMethod) {
|
||||
checker.report_diagnostic(UndocumentedPublicMethod, function.identifier());
|
||||
}
|
||||
true
|
||||
} else if is_magic(&function.name) {
|
||||
if checker.enabled(Rule::UndocumentedMagicMethod) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedMagicMethod) {
|
||||
checker.report_diagnostic(UndocumentedMagicMethod, function.identifier());
|
||||
}
|
||||
true
|
||||
} else {
|
||||
if checker.enabled(Rule::UndocumentedPublicMethod) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedPublicMethod) {
|
||||
checker.report_diagnostic(UndocumentedPublicMethod, function.identifier());
|
||||
}
|
||||
true
|
||||
|
|
|
@ -1361,7 +1361,7 @@ fn blanks_and_section_underline(
|
|||
if let Some(non_blank_line) = following_lines.next() {
|
||||
if let Some(dashed_line) = find_underline(&non_blank_line, '-') {
|
||||
if num_blank_lines_after_header > 0 {
|
||||
if checker.enabled(Rule::MissingSectionUnderlineAfterName) {
|
||||
if checker.is_rule_enabled(Rule::MissingSectionUnderlineAfterName) {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingSectionUnderlineAfterName {
|
||||
name: context.section_name().to_string(),
|
||||
|
@ -1378,7 +1378,7 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
|
||||
if dashed_line.len().to_usize() != context.section_name().len() {
|
||||
if checker.enabled(Rule::MismatchedSectionUnderlineLength) {
|
||||
if checker.is_rule_enabled(Rule::MismatchedSectionUnderlineLength) {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MismatchedSectionUnderlineLength {
|
||||
name: context.section_name().to_string(),
|
||||
|
@ -1394,7 +1394,7 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::OverindentedSectionUnderline) {
|
||||
if checker.is_rule_enabled(Rule::OverindentedSectionUnderline) {
|
||||
let leading_space = leading_space(&non_blank_line);
|
||||
let docstring_indentation = docstring.compute_indentation();
|
||||
if leading_space.len() > docstring_indentation.len() {
|
||||
|
@ -1434,7 +1434,7 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
|
||||
if following_lines.peek().is_none() {
|
||||
if checker.enabled(Rule::EmptyDocstringSection) {
|
||||
if checker.is_rule_enabled(Rule::EmptyDocstringSection) {
|
||||
checker.report_diagnostic(
|
||||
EmptyDocstringSection {
|
||||
name: context.section_name().to_string(),
|
||||
|
@ -1442,7 +1442,7 @@ fn blanks_and_section_underline(
|
|||
context.section_name_range(),
|
||||
);
|
||||
}
|
||||
} else if checker.enabled(Rule::BlankLinesBetweenHeaderAndContent) {
|
||||
} else if checker.is_rule_enabled(Rule::BlankLinesBetweenHeaderAndContent) {
|
||||
// If the section is followed by exactly one line, and then a
|
||||
// reStructuredText directive, the blank lines should be preserved, as in:
|
||||
//
|
||||
|
@ -1495,7 +1495,7 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::EmptyDocstringSection) {
|
||||
if checker.is_rule_enabled(Rule::EmptyDocstringSection) {
|
||||
checker.report_diagnostic(
|
||||
EmptyDocstringSection {
|
||||
name: context.section_name().to_string(),
|
||||
|
@ -1505,7 +1505,8 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if style.is_numpy() && checker.enabled(Rule::MissingDashedUnderlineAfterSection) {
|
||||
if style.is_numpy() && checker.is_rule_enabled(Rule::MissingDashedUnderlineAfterSection)
|
||||
{
|
||||
if let Some(equal_line) = find_underline(&non_blank_line, '=') {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingDashedUnderlineAfterSection {
|
||||
|
@ -1542,7 +1543,7 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
}
|
||||
if num_blank_lines_after_header > 0 {
|
||||
if checker.enabled(Rule::BlankLinesBetweenHeaderAndContent) {
|
||||
if checker.is_rule_enabled(Rule::BlankLinesBetweenHeaderAndContent) {
|
||||
// If the section is followed by exactly one line, and then a
|
||||
// reStructuredText directive, the blank lines should be preserved, as in:
|
||||
//
|
||||
|
@ -1597,7 +1598,7 @@ fn blanks_and_section_underline(
|
|||
}
|
||||
} else {
|
||||
// Nothing but blank lines after the section header.
|
||||
if style.is_numpy() && checker.enabled(Rule::MissingDashedUnderlineAfterSection) {
|
||||
if style.is_numpy() && checker.is_rule_enabled(Rule::MissingDashedUnderlineAfterSection) {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingDashedUnderlineAfterSection {
|
||||
name: context.section_name().to_string(),
|
||||
|
@ -1617,7 +1618,7 @@ fn blanks_and_section_underline(
|
|||
context.summary_range().end(),
|
||||
)));
|
||||
}
|
||||
if checker.enabled(Rule::EmptyDocstringSection) {
|
||||
if checker.is_rule_enabled(Rule::EmptyDocstringSection) {
|
||||
checker.report_diagnostic(
|
||||
EmptyDocstringSection {
|
||||
name: context.section_name().to_string(),
|
||||
|
@ -1635,7 +1636,7 @@ fn common_section(
|
|||
next: Option<&SectionContext>,
|
||||
style: SectionStyle,
|
||||
) {
|
||||
if checker.enabled(Rule::NonCapitalizedSectionName) {
|
||||
if checker.is_rule_enabled(Rule::NonCapitalizedSectionName) {
|
||||
let capitalized_section_name = context.kind().as_str();
|
||||
if context.section_name() != capitalized_section_name {
|
||||
let section_range = context.section_name_range();
|
||||
|
@ -1654,7 +1655,7 @@ fn common_section(
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::OverindentedSection) {
|
||||
if checker.is_rule_enabled(Rule::OverindentedSection) {
|
||||
let leading_space = leading_space(context.summary_line());
|
||||
let docstring_indentation = docstring.compute_indentation();
|
||||
if leading_space.len() > docstring_indentation.len() {
|
||||
|
@ -1680,7 +1681,7 @@ fn common_section(
|
|||
let line_end = checker.stylist().line_ending().as_str();
|
||||
|
||||
if let Some(next) = next {
|
||||
if checker.enabled(Rule::NoBlankLineAfterSection) {
|
||||
if checker.is_rule_enabled(Rule::NoBlankLineAfterSection) {
|
||||
let num_blank_lines = context
|
||||
.following_lines()
|
||||
.rev()
|
||||
|
@ -1704,7 +1705,7 @@ fn common_section(
|
|||
} else {
|
||||
// The first blank line is the line containing the closing triple quotes, so we need at
|
||||
// least two.
|
||||
if checker.enabled(Rule::MissingBlankLineAfterLastSection) {
|
||||
if checker.is_rule_enabled(Rule::MissingBlankLineAfterLastSection) {
|
||||
let num_blank_lines = context
|
||||
.following_lines()
|
||||
.rev()
|
||||
|
@ -1740,7 +1741,7 @@ fn common_section(
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::NoBlankLineBeforeSection) {
|
||||
if checker.is_rule_enabled(Rule::NoBlankLineBeforeSection) {
|
||||
if !context
|
||||
.previous_line()
|
||||
.is_some_and(|line| line.trim().is_empty())
|
||||
|
@ -1930,7 +1931,7 @@ fn numpy_section(
|
|||
) {
|
||||
common_section(checker, docstring, context, next, SectionStyle::Numpy);
|
||||
|
||||
if checker.enabled(Rule::MissingNewLineAfterSectionName) {
|
||||
if checker.is_rule_enabled(Rule::MissingNewLineAfterSectionName) {
|
||||
let suffix = context.summary_after_section_name();
|
||||
|
||||
if !suffix.is_empty() {
|
||||
|
@ -1948,7 +1949,7 @@ fn numpy_section(
|
|||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::UndocumentedParam) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedParam) {
|
||||
if matches!(context.kind(), SectionKind::Parameters) {
|
||||
parameters_section(checker, docstring, context);
|
||||
}
|
||||
|
@ -1963,7 +1964,7 @@ fn google_section(
|
|||
) {
|
||||
common_section(checker, docstring, context, next, SectionStyle::Google);
|
||||
|
||||
if checker.enabled(Rule::MissingSectionNameColon) {
|
||||
if checker.is_rule_enabled(Rule::MissingSectionNameColon) {
|
||||
let suffix = context.summary_after_section_name();
|
||||
if suffix != ":" {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
|
@ -2003,7 +2004,7 @@ fn parse_google_sections(
|
|||
google_section(checker, docstring, &context, iterator.peek());
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::UndocumentedParam) {
|
||||
if checker.is_rule_enabled(Rule::UndocumentedParam) {
|
||||
let mut has_args = false;
|
||||
let mut documented_args: FxHashSet<String> = FxHashSet::default();
|
||||
for section_context in section_contexts {
|
||||
|
|
|
@ -176,7 +176,7 @@ pub(crate) fn repeated_keys(checker: &Checker, dict: &ast::ExprDict) {
|
|||
| Expr::EllipsisLiteral(_)
|
||||
| Expr::Tuple(_)
|
||||
| Expr::FString(_) => {
|
||||
if checker.enabled(Rule::MultiValueRepeatedKeyLiteral) {
|
||||
if checker.is_rule_enabled(Rule::MultiValueRepeatedKeyLiteral) {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MultiValueRepeatedKeyLiteral {
|
||||
name: SourceCodeSnippet::from_str(checker.locator().slice(key)),
|
||||
|
@ -209,7 +209,7 @@ pub(crate) fn repeated_keys(checker: &Checker, dict: &ast::ExprDict) {
|
|||
}
|
||||
}
|
||||
Expr::Name(_) => {
|
||||
if checker.enabled(Rule::MultiValueRepeatedKeyVariable) {
|
||||
if checker.is_rule_enabled(Rule::MultiValueRepeatedKeyVariable) {
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MultiValueRepeatedKeyVariable {
|
||||
name: SourceCodeSnippet::from_str(checker.locator().slice(key)),
|
||||
|
|
|
@ -64,7 +64,7 @@ pub(crate) fn import_outside_top_level(checker: &Checker, stmt: &Stmt) {
|
|||
|
||||
// Check if any of the non-top-level imports are banned by TID253
|
||||
// before emitting the diagnostic to avoid conflicts.
|
||||
if checker.enabled(Rule::BannedModuleLevelImports) {
|
||||
if checker.is_rule_enabled(Rule::BannedModuleLevelImports) {
|
||||
let mut all_aliases_banned = true;
|
||||
let mut has_alias = false;
|
||||
for (policy, node) in &BannedModuleImportPolicies::new(stmt, checker) {
|
||||
|
|
|
@ -152,13 +152,13 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
let num_message_args = call.arguments.args.len() - 1;
|
||||
let num_keywords = call.arguments.keywords.len();
|
||||
|
||||
if checker.enabled(Rule::LoggingTooManyArgs) {
|
||||
if checker.is_rule_enabled(Rule::LoggingTooManyArgs) {
|
||||
if summary.num_positional < num_message_args {
|
||||
checker.report_diagnostic(LoggingTooManyArgs, call.func.range());
|
||||
}
|
||||
}
|
||||
|
||||
if checker.enabled(Rule::LoggingTooFewArgs) {
|
||||
if checker.is_rule_enabled(Rule::LoggingTooFewArgs) {
|
||||
if num_message_args > 0 && num_keywords == 0 && summary.num_positional > num_message_args {
|
||||
checker.report_diagnostic(LoggingTooFewArgs, call.func.range());
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ pub(crate) fn non_pep604_annotation(
|
|||
}
|
||||
}
|
||||
Pep604Operator::Union => {
|
||||
if !checker.enabled(Rule::NonPEP604AnnotationUnion) {
|
||||
if !checker.is_rule_enabled(Rule::NonPEP604AnnotationUnion) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
RUF100_2.py:1:19: RUF100 [*] Unused `noqa` directive (unused: `F401`)
|
||||
RUF100_2.py:1:19: RUF100 [*] Unused `noqa` directive (non-enabled: `F401`)
|
||||
|
|
||||
1 | import itertools # noqa: F401
|
||||
| ^^^^^^^^^^^^ RUF100
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue