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:
Brent Westbrook 2025-06-20 13:33:09 -04:00 committed by GitHub
parent ffb09c84f2
commit 8cff77c82e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 1138 additions and 1167 deletions

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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,
]) {

View file

@ -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,

View file

@ -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

View file

@ -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);
}
}

View file

@ -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,
&parameter.name,
parameter.name.range(),
);
}
if checker.enabled(Rule::BuiltinArgumentShadowing) {
if checker.is_rule_enabled(Rule::BuiltinArgumentShadowing) {
flake8_builtins::rules::builtin_argument_shadowing(checker, parameter);
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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()
}

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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,

View file

@ -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);

View file

@ -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![]);

View file

@ -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);
}
}

View file

@ -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()

View file

@ -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.

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -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 {

View file

@ -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),

View file

@ -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 {

View file

@ -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

View file

@ -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()
{

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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 {

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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,

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);
}
_ => {}

View file

@ -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,

View file

@ -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;
}

View file

@ -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 => {

View file

@ -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(

View file

@ -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),

View file

@ -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 {

View file

@ -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(

View file

@ -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()));

View file

@ -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 {

View file

@ -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());

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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)),

View file

@ -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) {

View file

@ -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());
}

View file

@ -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;
}

View file

@ -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