Skip to content

Commit 8cff77c

Browse files
authored
Avoid generating diagnostics with per-file ignores (#18801)
## Summary This PR avoids one of the three calls to `NoqaCode::rule` from #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.
1 parent ffb09c8 commit 8cff77c

File tree

65 files changed

+1138
-1167
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1138
-1167
lines changed

crates/ruff_linter/src/checkers/ast/analyze/bindings.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::rules::{
1010

1111
/// Run lint rules over the [`Binding`]s.
1212
pub(crate) fn bindings(checker: &Checker) {
13-
if !checker.any_enabled(&[
13+
if !checker.any_rule_enabled(&[
1414
Rule::AssignmentInAssert,
1515
Rule::InvalidAllFormat,
1616
Rule::InvalidAllObject,
@@ -30,7 +30,7 @@ pub(crate) fn bindings(checker: &Checker) {
3030
}
3131

3232
for (binding_id, binding) in checker.semantic.bindings.iter_enumerated() {
33-
if checker.enabled(Rule::UnusedVariable) {
33+
if checker.is_rule_enabled(Rule::UnusedVariable) {
3434
if binding.kind.is_bound_exception()
3535
&& binding.is_unused()
3636
&& !checker
@@ -54,47 +54,47 @@ pub(crate) fn bindings(checker: &Checker) {
5454
});
5555
}
5656
}
57-
if checker.enabled(Rule::InvalidAllFormat) {
57+
if checker.is_rule_enabled(Rule::InvalidAllFormat) {
5858
pylint::rules::invalid_all_format(checker, binding);
5959
}
60-
if checker.enabled(Rule::InvalidAllObject) {
60+
if checker.is_rule_enabled(Rule::InvalidAllObject) {
6161
pylint::rules::invalid_all_object(checker, binding);
6262
}
63-
if checker.enabled(Rule::NonAsciiName) {
63+
if checker.is_rule_enabled(Rule::NonAsciiName) {
6464
pylint::rules::non_ascii_name(checker, binding);
6565
}
66-
if checker.enabled(Rule::UnconventionalImportAlias) {
66+
if checker.is_rule_enabled(Rule::UnconventionalImportAlias) {
6767
flake8_import_conventions::rules::unconventional_import_alias(
6868
checker,
6969
binding,
7070
&checker.settings.flake8_import_conventions.aliases,
7171
);
7272
}
73-
if checker.enabled(Rule::UnaliasedCollectionsAbcSetImport) {
73+
if checker.is_rule_enabled(Rule::UnaliasedCollectionsAbcSetImport) {
7474
flake8_pyi::rules::unaliased_collections_abc_set_import(checker, binding);
7575
}
76-
if !checker.source_type.is_stub() && checker.enabled(Rule::UnquotedTypeAlias) {
76+
if !checker.source_type.is_stub() && checker.is_rule_enabled(Rule::UnquotedTypeAlias) {
7777
flake8_type_checking::rules::unquoted_type_alias(checker, binding);
7878
}
79-
if checker.enabled(Rule::UnsortedDunderSlots) {
79+
if checker.is_rule_enabled(Rule::UnsortedDunderSlots) {
8080
ruff::rules::sort_dunder_slots(checker, binding);
8181
}
82-
if checker.enabled(Rule::UsedDummyVariable) {
82+
if checker.is_rule_enabled(Rule::UsedDummyVariable) {
8383
ruff::rules::used_dummy_variable(checker, binding, binding_id);
8484
}
85-
if checker.enabled(Rule::AssignmentInAssert) {
85+
if checker.is_rule_enabled(Rule::AssignmentInAssert) {
8686
ruff::rules::assignment_in_assert(checker, binding);
8787
}
88-
if checker.enabled(Rule::PytestUnittestRaisesAssertion) {
88+
if checker.is_rule_enabled(Rule::PytestUnittestRaisesAssertion) {
8989
flake8_pytest_style::rules::unittest_raises_assertion_binding(checker, binding);
9090
}
91-
if checker.enabled(Rule::ForLoopWrites) {
91+
if checker.is_rule_enabled(Rule::ForLoopWrites) {
9292
refurb::rules::for_loop_writes_binding(checker, binding);
9393
}
94-
if checker.enabled(Rule::CustomTypeVarForSelf) {
94+
if checker.is_rule_enabled(Rule::CustomTypeVarForSelf) {
9595
flake8_pyi::rules::custom_type_var_instead_of_self(checker, binding);
9696
}
97-
if checker.enabled(Rule::PrivateTypeParameter) {
97+
if checker.is_rule_enabled(Rule::PrivateTypeParameter) {
9898
pyupgrade::rules::private_type_parameter(checker, binding);
9999
}
100100
}

crates/ruff_linter/src/checkers/ast/analyze/comprehension.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use crate::rules::{flake8_simplify, refurb};
66

77
/// Run lint rules over a [`Comprehension`] syntax nodes.
88
pub(crate) fn comprehension(comprehension: &Comprehension, checker: &Checker) {
9-
if checker.enabled(Rule::InDictKeys) {
9+
if checker.is_rule_enabled(Rule::InDictKeys) {
1010
flake8_simplify::rules::key_in_dict_comprehension(checker, comprehension);
1111
}
12-
if checker.enabled(Rule::ReadlinesInFor) {
12+
if checker.is_rule_enabled(Rule::ReadlinesInFor) {
1313
refurb::rules::readlines_in_comprehension(checker, comprehension);
1414
}
1515
}

crates/ruff_linter/src/checkers/ast/analyze/deferred_for_loops.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,31 @@ pub(crate) fn deferred_for_loops(checker: &mut Checker) {
1414
let Stmt::For(stmt_for) = checker.semantic.current_statement() else {
1515
unreachable!("Expected Stmt::For");
1616
};
17-
if checker.enabled(Rule::UnusedLoopControlVariable) {
17+
if checker.is_rule_enabled(Rule::UnusedLoopControlVariable) {
1818
flake8_bugbear::rules::unused_loop_control_variable(checker, stmt_for);
1919
}
20-
if checker.enabled(Rule::IncorrectDictIterator) {
20+
if checker.is_rule_enabled(Rule::IncorrectDictIterator) {
2121
perflint::rules::incorrect_dict_iterator(checker, stmt_for);
2222
}
23-
if checker.enabled(Rule::YieldInForLoop) {
23+
if checker.is_rule_enabled(Rule::YieldInForLoop) {
2424
pyupgrade::rules::yield_in_for_loop(checker, stmt_for);
2525
}
26-
if checker.enabled(Rule::UnnecessaryEnumerate) {
26+
if checker.is_rule_enabled(Rule::UnnecessaryEnumerate) {
2727
refurb::rules::unnecessary_enumerate(checker, stmt_for);
2828
}
29-
if checker.enabled(Rule::EnumerateForLoop) {
29+
if checker.is_rule_enabled(Rule::EnumerateForLoop) {
3030
flake8_simplify::rules::enumerate_for_loop(checker, stmt_for);
3131
}
32-
if checker.enabled(Rule::LoopIteratorMutation) {
32+
if checker.is_rule_enabled(Rule::LoopIteratorMutation) {
3333
flake8_bugbear::rules::loop_iterator_mutation(checker, stmt_for);
3434
}
35-
if checker.enabled(Rule::DictIndexMissingItems) {
35+
if checker.is_rule_enabled(Rule::DictIndexMissingItems) {
3636
pylint::rules::dict_index_missing_items(checker, stmt_for);
3737
}
38-
if checker.enabled(Rule::ManualDictComprehension) {
38+
if checker.is_rule_enabled(Rule::ManualDictComprehension) {
3939
perflint::rules::manual_dict_comprehension(checker, stmt_for);
4040
}
41-
if checker.enabled(Rule::ManualListComprehension) {
41+
if checker.is_rule_enabled(Rule::ManualListComprehension) {
4242
perflint::rules::manual_list_comprehension(checker, stmt_for);
4343
}
4444
}

crates/ruff_linter/src/checkers/ast/analyze/deferred_lambdas.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ pub(crate) fn deferred_lambdas(checker: &mut Checker) {
1515
unreachable!("Expected Expr::Lambda");
1616
};
1717

18-
if checker.enabled(Rule::UnnecessaryLambda) {
18+
if checker.is_rule_enabled(Rule::UnnecessaryLambda) {
1919
pylint::rules::unnecessary_lambda(checker, lambda);
2020
}
21-
if checker.enabled(Rule::ReimplementedContainerBuiltin) {
21+
if checker.is_rule_enabled(Rule::ReimplementedContainerBuiltin) {
2222
flake8_pie::rules::reimplemented_container_builtin(checker, lambda);
2323
}
24-
if checker.enabled(Rule::BuiltinLambdaArgumentShadowing) {
24+
if checker.is_rule_enabled(Rule::BuiltinLambdaArgumentShadowing) {
2525
flake8_builtins::rules::builtin_lambda_argument_shadowing(checker, lambda);
2626
}
2727
}

crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::rules::{
1414

1515
/// Run lint rules over all deferred scopes in the [`SemanticModel`].
1616
pub(crate) fn deferred_scopes(checker: &Checker) {
17-
if !checker.any_enabled(&[
17+
if !checker.any_rule_enabled(&[
1818
Rule::AsyncioDanglingTask,
1919
Rule::BadStaticmethodArgument,
2020
Rule::BuiltinAttributeShadowing,
@@ -58,7 +58,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
5858
// used at runtime, then by default, we avoid flagging any other
5959
// imports from that model as typing-only.
6060
let enforce_typing_only_imports = !checker.source_type.is_stub()
61-
&& checker.any_enabled(&[
61+
&& checker.any_rule_enabled(&[
6262
Rule::TypingOnlyFirstPartyImport,
6363
Rule::TypingOnlyStandardLibraryImport,
6464
Rule::TypingOnlyThirdPartyImport,
@@ -89,11 +89,11 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
8989
for scope_id in checker.analyze.scopes.iter().rev().copied() {
9090
let scope = &checker.semantic.scopes[scope_id];
9191

92-
if checker.enabled(Rule::UndefinedLocal) {
92+
if checker.is_rule_enabled(Rule::UndefinedLocal) {
9393
pyflakes::rules::undefined_local(checker, scope_id, scope);
9494
}
9595

96-
if checker.enabled(Rule::GlobalVariableNotAssigned) {
96+
if checker.is_rule_enabled(Rule::GlobalVariableNotAssigned) {
9797
for (name, binding_id) in scope.bindings() {
9898
let binding = checker.semantic.binding(binding_id);
9999
// 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) {
123123
}
124124
}
125125

126-
if checker.enabled(Rule::RedefinedArgumentFromLocal) {
126+
if checker.is_rule_enabled(Rule::RedefinedArgumentFromLocal) {
127127
for (name, binding_id) in scope.bindings() {
128128
for shadow in checker.semantic.shadowed_bindings(scope_id, binding_id) {
129129
let binding = &checker.semantic.bindings[shadow.binding_id()];
@@ -156,7 +156,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
156156
}
157157
}
158158

159-
if checker.enabled(Rule::ImportShadowedByLoopVar) {
159+
if checker.is_rule_enabled(Rule::ImportShadowedByLoopVar) {
160160
for (name, binding_id) in scope.bindings() {
161161
for shadow in checker.semantic.shadowed_bindings(scope_id, binding_id) {
162162
// If the shadowing binding isn't a loop variable, abort.
@@ -197,7 +197,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
197197
}
198198
}
199199

200-
if checker.enabled(Rule::RedefinedWhileUnused) {
200+
if checker.is_rule_enabled(Rule::RedefinedWhileUnused) {
201201
// Index the redefined bindings by statement.
202202
let mut redefinitions = FxHashMap::default();
203203

@@ -353,43 +353,43 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
353353
if checker.source_type.is_stub()
354354
|| matches!(scope.kind, ScopeKind::Module | ScopeKind::Function(_))
355355
{
356-
if checker.enabled(Rule::UnusedPrivateTypeVar) {
356+
if checker.is_rule_enabled(Rule::UnusedPrivateTypeVar) {
357357
flake8_pyi::rules::unused_private_type_var(checker, scope);
358358
}
359-
if checker.enabled(Rule::UnusedPrivateProtocol) {
359+
if checker.is_rule_enabled(Rule::UnusedPrivateProtocol) {
360360
flake8_pyi::rules::unused_private_protocol(checker, scope);
361361
}
362-
if checker.enabled(Rule::UnusedPrivateTypeAlias) {
362+
if checker.is_rule_enabled(Rule::UnusedPrivateTypeAlias) {
363363
flake8_pyi::rules::unused_private_type_alias(checker, scope);
364364
}
365-
if checker.enabled(Rule::UnusedPrivateTypedDict) {
365+
if checker.is_rule_enabled(Rule::UnusedPrivateTypedDict) {
366366
flake8_pyi::rules::unused_private_typed_dict(checker, scope);
367367
}
368368
}
369369

370-
if checker.enabled(Rule::AsyncioDanglingTask) {
370+
if checker.is_rule_enabled(Rule::AsyncioDanglingTask) {
371371
ruff::rules::asyncio_dangling_binding(scope, checker);
372372
}
373373

374374
if let Some(class_def) = scope.kind.as_class() {
375-
if checker.enabled(Rule::BuiltinAttributeShadowing) {
375+
if checker.is_rule_enabled(Rule::BuiltinAttributeShadowing) {
376376
flake8_builtins::rules::builtin_attribute_shadowing(
377377
checker, scope_id, scope, class_def,
378378
);
379379
}
380-
if checker.enabled(Rule::FunctionCallInDataclassDefaultArgument) {
380+
if checker.is_rule_enabled(Rule::FunctionCallInDataclassDefaultArgument) {
381381
ruff::rules::function_call_in_dataclass_default(checker, class_def);
382382
}
383-
if checker.enabled(Rule::MutableClassDefault) {
383+
if checker.is_rule_enabled(Rule::MutableClassDefault) {
384384
ruff::rules::mutable_class_default(checker, class_def);
385385
}
386-
if checker.enabled(Rule::MutableDataclassDefault) {
386+
if checker.is_rule_enabled(Rule::MutableDataclassDefault) {
387387
ruff::rules::mutable_dataclass_default(checker, class_def);
388388
}
389389
}
390390

391391
if matches!(scope.kind, ScopeKind::Function(_) | ScopeKind::Lambda(_)) {
392-
if checker.any_enabled(&[Rule::UnusedVariable, Rule::UnusedUnpackedVariable])
392+
if checker.any_rule_enabled(&[Rule::UnusedVariable, Rule::UnusedUnpackedVariable])
393393
&& !(scope.uses_locals() && scope.kind.is_function())
394394
{
395395
let unused_bindings = scope
@@ -418,22 +418,22 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
418418
});
419419

420420
for (unused_name, unused_binding) in unused_bindings {
421-
if checker.enabled(Rule::UnusedVariable) {
421+
if checker.is_rule_enabled(Rule::UnusedVariable) {
422422
pyflakes::rules::unused_variable(checker, unused_name, unused_binding);
423423
}
424424

425-
if checker.enabled(Rule::UnusedUnpackedVariable) {
425+
if checker.is_rule_enabled(Rule::UnusedUnpackedVariable) {
426426
ruff::rules::unused_unpacked_variable(checker, unused_name, unused_binding);
427427
}
428428
}
429429
}
430430

431-
if checker.enabled(Rule::UnusedAnnotation) {
431+
if checker.is_rule_enabled(Rule::UnusedAnnotation) {
432432
pyflakes::rules::unused_annotation(checker, scope);
433433
}
434434

435435
if !checker.source_type.is_stub() {
436-
if checker.any_enabled(&[
436+
if checker.any_rule_enabled(&[
437437
Rule::UnusedClassMethodArgument,
438438
Rule::UnusedFunctionArgument,
439439
Rule::UnusedLambdaArgument,
@@ -447,7 +447,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
447447

448448
if matches!(scope.kind, ScopeKind::Function(_) | ScopeKind::Module) {
449449
if !checker.source_type.is_stub()
450-
&& checker.enabled(Rule::RuntimeImportInTypeCheckingBlock)
450+
&& checker.is_rule_enabled(Rule::RuntimeImportInTypeCheckingBlock)
451451
{
452452
flake8_type_checking::rules::runtime_import_in_type_checking_block(checker, scope);
453453
}
@@ -467,37 +467,37 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
467467
);
468468
}
469469

470-
if checker.enabled(Rule::UnusedImport) {
470+
if checker.is_rule_enabled(Rule::UnusedImport) {
471471
pyflakes::rules::unused_import(checker, scope);
472472
}
473473

474-
if checker.enabled(Rule::ImportPrivateName) {
474+
if checker.is_rule_enabled(Rule::ImportPrivateName) {
475475
pylint::rules::import_private_name(checker, scope);
476476
}
477477
}
478478

479479
if scope.kind.is_function() {
480-
if checker.enabled(Rule::NoSelfUse) {
480+
if checker.is_rule_enabled(Rule::NoSelfUse) {
481481
pylint::rules::no_self_use(checker, scope_id, scope);
482482
}
483483

484-
if checker.enabled(Rule::TooManyLocals) {
484+
if checker.is_rule_enabled(Rule::TooManyLocals) {
485485
pylint::rules::too_many_locals(checker, scope);
486486
}
487487

488-
if checker.enabled(Rule::SingledispatchMethod) {
488+
if checker.is_rule_enabled(Rule::SingledispatchMethod) {
489489
pylint::rules::singledispatch_method(checker, scope);
490490
}
491491

492-
if checker.enabled(Rule::SingledispatchmethodFunction) {
492+
if checker.is_rule_enabled(Rule::SingledispatchmethodFunction) {
493493
pylint::rules::singledispatchmethod_function(checker, scope);
494494
}
495495

496-
if checker.enabled(Rule::BadStaticmethodArgument) {
496+
if checker.is_rule_enabled(Rule::BadStaticmethodArgument) {
497497
pylint::rules::bad_staticmethod_argument(checker, scope);
498498
}
499499

500-
if checker.any_enabled(&[
500+
if checker.any_rule_enabled(&[
501501
Rule::InvalidFirstArgumentNameForClassMethod,
502502
Rule::InvalidFirstArgumentNameForMethod,
503503
]) {

0 commit comments

Comments
 (0)