mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Return DiagnosticGuard
from Checker::report_diagnostic
(#18232)
Summary -- This PR adds a `DiagnosticGuard` type to ruff that is adapted from the `DiagnosticGuard` and `LintDiagnosticGuard` types from ty. This guard is returned by `Checker::report_diagnostic` and derefs to a `ruff_diagnostics::Diagnostic` (`OldDiagnostic`), allowing methods like `OldDiagnostic::set_fix` to be called on the result. On `Drop` the `DiagnosticGuard` pushes its contained `OldDiagnostic` to the `Checker`. The main motivation for this is to make a following PR adding a `SourceFile` to each diagnostic easier. For every rule where a `Checker` is available, this will now only require modifying `Checker::report_diagnostic` rather than all the rules. In the few cases where we need to create a diagnostic before we know if we actually want to emit it, there is a `DiagnosticGuard::defuse` method, which consumes the guard without emitting the diagnostic. I was able to restructure about half of the rules that naively called this to avoid calling it, but a handful of rules still need it. One of the fairly common patterns where `defuse` was needed initially was something like ```rust let diagnostic = Diagnostic::new(DiagnosticKind, range); if !checker.enabled(diagnostic.rule()) { return; } ``` So I also added a `Checker::checked_report_diagnostic` method that handles this check internally. That helped to avoid some additional `defuse` calls. The name is a bit repetitive, so I'm definitely open to suggestions there. I included a warning against using it in the docs since, as we've seen, the conversion from a diagnostic to a rule is actually pretty expensive. Test Plan -- Existing tests
This commit is contained in:
parent
b60ba75d09
commit
a3ee6bb3b5
590 changed files with 2983 additions and 3790 deletions
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Fix};
|
||||
use ruff_diagnostics::Fix;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
@ -38,92 +38,64 @@ pub(crate) fn bindings(checker: &Checker) {
|
|||
.dummy_variable_rgx
|
||||
.is_match(binding.name(checker.source()))
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
pyflakes::rules::UnusedVariable {
|
||||
name: binding.name(checker.source()).to_string(),
|
||||
},
|
||||
binding.range(),
|
||||
);
|
||||
diagnostic.try_set_fix(|| {
|
||||
pyflakes::fixes::remove_exception_handler_assignment(binding, checker.locator)
|
||||
checker
|
||||
.report_diagnostic(
|
||||
pyflakes::rules::UnusedVariable {
|
||||
name: binding.name(checker.source()).to_string(),
|
||||
},
|
||||
binding.range(),
|
||||
)
|
||||
.try_set_fix(|| {
|
||||
pyflakes::fixes::remove_exception_handler_assignment(
|
||||
binding,
|
||||
checker.locator,
|
||||
)
|
||||
.map(Fix::safe_edit)
|
||||
});
|
||||
checker.report_diagnostic(diagnostic);
|
||||
});
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::InvalidAllFormat) {
|
||||
if let Some(diagnostic) = pylint::rules::invalid_all_format(binding) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pylint::rules::invalid_all_format(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidAllObject) {
|
||||
if let Some(diagnostic) = pylint::rules::invalid_all_object(binding) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pylint::rules::invalid_all_object(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::NonAsciiName) {
|
||||
if let Some(diagnostic) = pylint::rules::non_ascii_name(binding, checker.locator) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pylint::rules::non_ascii_name(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::UnconventionalImportAlias) {
|
||||
if let Some(diagnostic) = flake8_import_conventions::rules::unconventional_import_alias(
|
||||
flake8_import_conventions::rules::unconventional_import_alias(
|
||||
checker,
|
||||
binding,
|
||||
&checker.settings.flake8_import_conventions.aliases,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::UnaliasedCollectionsAbcSetImport) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_pyi::rules::unaliased_collections_abc_set_import(checker, binding)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_pyi::rules::unaliased_collections_abc_set_import(checker, binding);
|
||||
}
|
||||
if !checker.source_type.is_stub() && checker.enabled(Rule::UnquotedTypeAlias) {
|
||||
flake8_type_checking::rules::unquoted_type_alias(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::UnsortedDunderSlots) {
|
||||
if let Some(diagnostic) = ruff::rules::sort_dunder_slots(checker, binding) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
ruff::rules::sort_dunder_slots(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::UsedDummyVariable) {
|
||||
if let Some(diagnostic) = ruff::rules::used_dummy_variable(checker, binding, binding_id)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
ruff::rules::used_dummy_variable(checker, binding, binding_id);
|
||||
}
|
||||
if checker.enabled(Rule::AssignmentInAssert) {
|
||||
if let Some(diagnostic) = ruff::rules::assignment_in_assert(checker, binding) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
ruff::rules::assignment_in_assert(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::PytestUnittestRaisesAssertion) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_pytest_style::rules::unittest_raises_assertion_binding(checker, binding)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_pytest_style::rules::unittest_raises_assertion_binding(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::ForLoopWrites) {
|
||||
if let Some(diagnostic) = refurb::rules::for_loop_writes_binding(checker, binding) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
refurb::rules::for_loop_writes_binding(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::CustomTypeVarForSelf) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_pyi::rules::custom_type_var_instead_of_self(checker, binding)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_pyi::rules::custom_type_var_instead_of_self(checker, binding);
|
||||
}
|
||||
if checker.enabled(Rule::PrivateTypeParameter) {
|
||||
if let Some(diagnostic) = pyupgrade::rules::private_type_parameter(checker, binding) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pyupgrade::rules::private_type_parameter(checker, binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Fix};
|
||||
use ruff_diagnostics::Fix;
|
||||
use ruff_python_semantic::analyze::visibility;
|
||||
use ruff_python_semantic::{Binding, BindingKind, Imported, ResolvedReference, ScopeKind};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -112,12 +112,12 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
.map(|id| checker.semantic.reference(*id))
|
||||
.all(ResolvedReference::is_load)
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pylint::rules::GlobalVariableNotAssigned {
|
||||
name: (*name).to_string(),
|
||||
},
|
||||
binding.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,12 +146,12 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
if scope.kind.is_generator() {
|
||||
continue;
|
||||
}
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pylint::rules::RedefinedArgumentFromLocal {
|
||||
name: name.to_string(),
|
||||
},
|
||||
binding.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,13 +186,13 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
continue;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::ImportShadowedByLoopVar {
|
||||
name: name.to_string(),
|
||||
row: checker.compute_source_row(shadowed.start()),
|
||||
},
|
||||
binding.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
// Create diagnostics for each statement.
|
||||
for (source, entries) in &redefinitions {
|
||||
for (shadowed, binding) in entries {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
pyflakes::rules::RedefinedWhileUnused {
|
||||
name: binding.name(checker.source()).to_string(),
|
||||
row: checker.compute_source_row(shadowed.start()),
|
||||
|
@ -346,8 +346,6 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
|
|||
if let Some(fix) = source.as_ref().and_then(|source| fixes.get(source)) {
|
||||
diagnostic.set_fix(fix.clone());
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,7 @@ pub(crate) fn except_handler(except_handler: &ExceptHandler, checker: &Checker)
|
|||
range: _,
|
||||
}) => {
|
||||
if checker.enabled(Rule::BareExcept) {
|
||||
if let Some(diagnostic) = pycodestyle::rules::bare_except(
|
||||
type_.as_deref(),
|
||||
body,
|
||||
except_handler,
|
||||
checker.locator,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pycodestyle::rules::bare_except(checker, type_.as_deref(), body, except_handler);
|
||||
}
|
||||
if checker.enabled(Rule::RaiseWithoutFromInsideExcept) {
|
||||
flake8_bugbear::rules::raise_without_from_inside_except(
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Operator};
|
||||
use ruff_python_literal::cformat::{CFormatError, CFormatErrorType};
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
|
||||
use ruff_python_ast::types::Node;
|
||||
use ruff_python_semantic::ScopeKind;
|
||||
use ruff_python_semantic::analyze::typing;
|
||||
|
@ -195,14 +193,13 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
let check_too_many_expressions = checker.enabled(Rule::ExpressionsInStarAssignment);
|
||||
let check_two_starred_expressions =
|
||||
checker.enabled(Rule::MultipleStarredExpressions);
|
||||
if let Some(diagnostic) = pyflakes::rules::starred_expressions(
|
||||
pyflakes::rules::starred_expressions(
|
||||
checker,
|
||||
elts,
|
||||
check_too_many_expressions,
|
||||
check_two_starred_expressions,
|
||||
expr.range(),
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Expr::Name(ast::ExprName { id, ctx, range }) => {
|
||||
|
@ -527,12 +524,12 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
match pyflakes::format::FormatSummary::try_from(string_value.to_str()) {
|
||||
Err(e) => {
|
||||
if checker.enabled(Rule::StringDotFormatInvalidFormat) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::StringDotFormatInvalidFormat {
|
||||
message: pyflakes::format::error_to_string(&e),
|
||||
},
|
||||
location,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(summary) => {
|
||||
|
@ -936,9 +933,7 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
pylint::rules::repeated_keyword_argument(checker, call);
|
||||
}
|
||||
if checker.enabled(Rule::PytestPatchWithLambda) {
|
||||
if let Some(diagnostic) = flake8_pytest_style::rules::patch_with_lambda(call) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_pytest_style::rules::patch_with_lambda(checker, call);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
Rule::PytestParametrizeNamesWrongType,
|
||||
|
@ -1286,22 +1281,22 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
..
|
||||
}) => {
|
||||
if checker.enabled(Rule::PercentFormatUnsupportedFormatCharacter) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::PercentFormatUnsupportedFormatCharacter {
|
||||
char: c,
|
||||
},
|
||||
location,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if checker.enabled(Rule::PercentFormatInvalidFormat) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::PercentFormatInvalidFormat {
|
||||
message: e.to_string(),
|
||||
},
|
||||
location,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(summary) => {
|
||||
|
@ -1365,10 +1360,7 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
op: Operator::Add, ..
|
||||
}) => {
|
||||
if checker.enabled(Rule::ExplicitStringConcatenation) {
|
||||
if let Some(diagnostic) = flake8_implicit_str_concat::rules::explicit(expr, checker)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_implicit_str_concat::rules::explicit(checker, expr);
|
||||
}
|
||||
if checker.enabled(Rule::CollectionLiteralConcatenation) {
|
||||
ruff::rules::collection_literal_concatenation(checker, expr);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::helpers;
|
||||
use ruff_python_ast::types::Node;
|
||||
use ruff_python_ast::{self as ast, Expr, Stmt};
|
||||
|
@ -39,12 +38,12 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
if !checker.semantic.scope_id.is_global() {
|
||||
for name in names {
|
||||
if checker.semantic.nonlocal(name).is_none() {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pylint::rules::NonlocalWithoutBinding {
|
||||
name: name.to_string(),
|
||||
},
|
||||
name.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,22 +54,20 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
Stmt::Break(_) => {
|
||||
if checker.enabled(Rule::BreakOutsideLoop) {
|
||||
if let Some(diagnostic) = pyflakes::rules::break_outside_loop(
|
||||
pyflakes::rules::break_outside_loop(
|
||||
checker,
|
||||
stmt,
|
||||
&mut checker.semantic.current_statements().skip(1),
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Stmt::Continue(_) => {
|
||||
if checker.enabled(Rule::ContinueOutsideLoop) {
|
||||
if let Some(diagnostic) = pyflakes::rules::continue_outside_loop(
|
||||
pyflakes::rules::continue_outside_loop(
|
||||
checker,
|
||||
stmt,
|
||||
&mut checker.semantic.current_statements().skip(1),
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Stmt::FunctionDef(
|
||||
|
@ -98,9 +95,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
fastapi::rules::fastapi_unused_path_parameter(checker, function_def);
|
||||
}
|
||||
if checker.enabled(Rule::AmbiguousFunctionName) {
|
||||
if let Some(diagnostic) = pycodestyle::rules::ambiguous_function_name(name) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pycodestyle::rules::ambiguous_function_name(checker, name);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidBoolReturnType) {
|
||||
pylint::rules::invalid_bool_return(checker, function_def);
|
||||
|
@ -121,15 +116,14 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
pylint::rules::invalid_str_return(checker, function_def);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidFunctionName) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::invalid_function_name(
|
||||
pep8_naming::rules::invalid_function_name(
|
||||
checker,
|
||||
stmt,
|
||||
name,
|
||||
decorator_list,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
&checker.semantic,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.source_type.is_stub() {
|
||||
if checker.enabled(Rule::PassStatementStubBody) {
|
||||
|
@ -179,14 +173,13 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
flake8_pyi::rules::pep_484_positional_parameter(checker, function_def);
|
||||
}
|
||||
if checker.enabled(Rule::DunderFunctionName) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::dunder_function_name(
|
||||
pep8_naming::rules::dunder_function_name(
|
||||
checker,
|
||||
checker.semantic.current_scope(),
|
||||
stmt,
|
||||
name,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::GlobalStatement) {
|
||||
pylint::rules::global_statement(checker, name);
|
||||
|
@ -231,14 +224,13 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
);
|
||||
}
|
||||
if checker.enabled(Rule::ComplexStructure) {
|
||||
if let Some(diagnostic) = mccabe::rules::function_is_too_complex(
|
||||
mccabe::rules::function_is_too_complex(
|
||||
checker,
|
||||
stmt,
|
||||
name,
|
||||
body,
|
||||
checker.settings.mccabe.max_complexity,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::HardcodedPasswordDefault) {
|
||||
flake8_bandit::rules::hardcoded_password_default(checker, parameters);
|
||||
|
@ -258,31 +250,28 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
pylint::rules::too_many_positional_arguments(checker, function_def);
|
||||
}
|
||||
if checker.enabled(Rule::TooManyReturnStatements) {
|
||||
if let Some(diagnostic) = pylint::rules::too_many_return_statements(
|
||||
pylint::rules::too_many_return_statements(
|
||||
checker,
|
||||
stmt,
|
||||
body,
|
||||
checker.settings.pylint.max_returns,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::TooManyBranches) {
|
||||
if let Some(diagnostic) = pylint::rules::too_many_branches(
|
||||
pylint::rules::too_many_branches(
|
||||
checker,
|
||||
stmt,
|
||||
body,
|
||||
checker.settings.pylint.max_branches,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::TooManyStatements) {
|
||||
if let Some(diagnostic) = pylint::rules::too_many_statements(
|
||||
pylint::rules::too_many_statements(
|
||||
checker,
|
||||
stmt,
|
||||
body,
|
||||
checker.settings.pylint.max_statements,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
Rule::PytestFixtureIncorrectParenthesesStyle,
|
||||
|
@ -451,28 +440,24 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
pyupgrade::rules::unnecessary_class_parentheses(checker, class_def);
|
||||
}
|
||||
if checker.enabled(Rule::AmbiguousClassName) {
|
||||
if let Some(diagnostic) = pycodestyle::rules::ambiguous_class_name(name) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pycodestyle::rules::ambiguous_class_name(checker, name);
|
||||
}
|
||||
if checker.enabled(Rule::InvalidClassName) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::invalid_class_name(
|
||||
pep8_naming::rules::invalid_class_name(
|
||||
checker,
|
||||
stmt,
|
||||
name,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::ErrorSuffixOnExceptionName) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::error_suffix_on_exception_name(
|
||||
pep8_naming::rules::error_suffix_on_exception_name(
|
||||
checker,
|
||||
stmt,
|
||||
arguments.as_deref(),
|
||||
name,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if !checker.source_type.is_stub() {
|
||||
if checker.any_enabled(&[
|
||||
|
@ -611,11 +596,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
|
||||
if checker.enabled(Rule::Debugger) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_debugger::rules::debugger_import(stmt, None, &alias.name)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_debugger::rules::debugger_import(checker, stmt, None, &alias.name);
|
||||
}
|
||||
if checker.enabled(Rule::BannedApi) {
|
||||
flake8_tidy_imports::rules::banned_api(
|
||||
|
@ -638,94 +619,74 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
pylint::rules::manual_from_import(checker, stmt, alias, names);
|
||||
}
|
||||
if checker.enabled(Rule::ImportSelf) {
|
||||
if let Some(diagnostic) =
|
||||
pylint::rules::import_self(alias, checker.module.qualified_name())
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pylint::rules::import_self(checker, alias, checker.module.qualified_name());
|
||||
}
|
||||
if let Some(asname) = &alias.asname {
|
||||
let name = alias.name.split('.').next_back().unwrap();
|
||||
if checker.enabled(Rule::ConstantImportedAsNonConstant) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::constant_imported_as_non_constant(
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::LowercaseImportedAsNonLowercase) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::lowercase_imported_as_non_lowercase(
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsLowercase) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::camelcase_imported_as_lowercase(
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsConstant) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::camelcase_imported_as_constant(
|
||||
pep8_naming::rules::constant_imported_as_non_constant(
|
||||
checker,
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::LowercaseImportedAsNonLowercase) {
|
||||
pep8_naming::rules::lowercase_imported_as_non_lowercase(
|
||||
checker,
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsLowercase) {
|
||||
pep8_naming::rules::camelcase_imported_as_lowercase(
|
||||
checker,
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsConstant) {
|
||||
pep8_naming::rules::camelcase_imported_as_constant(
|
||||
checker,
|
||||
name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsAcronym) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::camelcase_imported_as_acronym(
|
||||
pep8_naming::rules::camelcase_imported_as_acronym(
|
||||
name, asname, alias, stmt, checker,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::BannedImportAlias) {
|
||||
if let Some(asname) = &alias.asname {
|
||||
if let Some(diagnostic) =
|
||||
flake8_import_conventions::rules::banned_import_alias(
|
||||
stmt,
|
||||
&alias.name,
|
||||
asname,
|
||||
&checker.settings.flake8_import_conventions.banned_aliases,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_import_conventions::rules::banned_import_alias(
|
||||
checker,
|
||||
stmt,
|
||||
&alias.name,
|
||||
asname,
|
||||
&checker.settings.flake8_import_conventions.banned_aliases,
|
||||
);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::PytestIncorrectPytestImport) {
|
||||
if let Some(diagnostic) = flake8_pytest_style::rules::import(
|
||||
flake8_pytest_style::rules::import(
|
||||
checker,
|
||||
stmt,
|
||||
&alias.name,
|
||||
alias.asname.as_deref(),
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::BuiltinImportShadowing) {
|
||||
flake8_builtins::rules::builtin_import_shadowing(checker, alias);
|
||||
|
@ -837,11 +798,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
|
||||
if checker.enabled(Rule::PytestIncorrectPytestImport) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_pytest_style::rules::import_from(stmt, module, level)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_pytest_style::rules::import_from(checker, stmt, module, level);
|
||||
}
|
||||
if checker.source_type.is_stub() {
|
||||
if checker.enabled(Rule::FutureAnnotationsInStub) {
|
||||
|
@ -856,119 +813,98 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
} else if &alias.name == "*" {
|
||||
if checker.enabled(Rule::UndefinedLocalWithNestedImportStarUsage) {
|
||||
if !matches!(checker.semantic.current_scope().kind, ScopeKind::Module) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::UndefinedLocalWithNestedImportStarUsage {
|
||||
name: helpers::format_import_from(level, module).to_string(),
|
||||
},
|
||||
stmt.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::UndefinedLocalWithImportStar) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::UndefinedLocalWithImportStar {
|
||||
name: helpers::format_import_from(level, module).to_string(),
|
||||
},
|
||||
stmt.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::RelativeImports) {
|
||||
if let Some(diagnostic) = flake8_tidy_imports::rules::banned_relative_import(
|
||||
flake8_tidy_imports::rules::banned_relative_import(
|
||||
checker,
|
||||
stmt,
|
||||
level,
|
||||
module,
|
||||
checker.module.qualified_name(),
|
||||
checker.settings.flake8_tidy_imports.ban_relative_imports,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::Debugger) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_debugger::rules::debugger_import(stmt, module, &alias.name)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_debugger::rules::debugger_import(checker, stmt, module, &alias.name);
|
||||
}
|
||||
if checker.enabled(Rule::BannedImportAlias) {
|
||||
if let Some(asname) = &alias.asname {
|
||||
let qualified_name =
|
||||
helpers::format_import_from_member(level, module, &alias.name);
|
||||
if let Some(diagnostic) =
|
||||
flake8_import_conventions::rules::banned_import_alias(
|
||||
stmt,
|
||||
&qualified_name,
|
||||
asname,
|
||||
&checker.settings.flake8_import_conventions.banned_aliases,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
flake8_import_conventions::rules::banned_import_alias(
|
||||
checker,
|
||||
stmt,
|
||||
&qualified_name,
|
||||
asname,
|
||||
&checker.settings.flake8_import_conventions.banned_aliases,
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(asname) = &alias.asname {
|
||||
if checker.enabled(Rule::ConstantImportedAsNonConstant) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::constant_imported_as_non_constant(
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::LowercaseImportedAsNonLowercase) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::lowercase_imported_as_non_lowercase(
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsLowercase) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::camelcase_imported_as_lowercase(
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsConstant) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::camelcase_imported_as_constant(
|
||||
pep8_naming::rules::constant_imported_as_non_constant(
|
||||
checker,
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::LowercaseImportedAsNonLowercase) {
|
||||
pep8_naming::rules::lowercase_imported_as_non_lowercase(
|
||||
checker,
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsLowercase) {
|
||||
pep8_naming::rules::camelcase_imported_as_lowercase(
|
||||
checker,
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsConstant) {
|
||||
pep8_naming::rules::camelcase_imported_as_constant(
|
||||
checker,
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
&checker.settings.pep8_naming.ignore_names,
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::CamelcaseImportedAsAcronym) {
|
||||
if let Some(diagnostic) = pep8_naming::rules::camelcase_imported_as_acronym(
|
||||
pep8_naming::rules::camelcase_imported_as_acronym(
|
||||
&alias.name,
|
||||
asname,
|
||||
alias,
|
||||
stmt,
|
||||
checker,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if !checker.source_type.is_stub() {
|
||||
if checker.enabled(Rule::UselessImportAlias) {
|
||||
|
@ -981,23 +917,21 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
}
|
||||
if checker.enabled(Rule::ImportSelf) {
|
||||
if let Some(diagnostic) = pylint::rules::import_from_self(
|
||||
pylint::rules::import_from_self(
|
||||
checker,
|
||||
level,
|
||||
module,
|
||||
names,
|
||||
checker.module.qualified_name(),
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::BannedImportFrom) {
|
||||
if let Some(diagnostic) = flake8_import_conventions::rules::banned_import_from(
|
||||
flake8_import_conventions::rules::banned_import_from(
|
||||
checker,
|
||||
stmt,
|
||||
&helpers::format_import_from(level, module),
|
||||
&checker.settings.flake8_import_conventions.banned_from,
|
||||
) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
);
|
||||
}
|
||||
if checker.enabled(Rule::ByteStringUsage) {
|
||||
flake8_pyi::rules::bytestring_import(checker, import_from);
|
||||
|
@ -1212,7 +1146,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
) => {
|
||||
if !checker.semantic.in_type_checking_block() {
|
||||
if checker.enabled(Rule::Assert) {
|
||||
checker.report_diagnostic(flake8_bandit::rules::assert_used(stmt));
|
||||
flake8_bandit::rules::assert_used(checker, stmt);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::AssertTuple) {
|
||||
|
@ -1409,11 +1343,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
}
|
||||
if checker.enabled(Rule::DefaultExceptNotLast) {
|
||||
if let Some(diagnostic) =
|
||||
pyflakes::rules::default_except_not_last(handlers, checker.locator)
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pyflakes::rules::default_except_not_last(checker, handlers, checker.locator);
|
||||
}
|
||||
if checker.any_enabled(&[
|
||||
Rule::DuplicateHandlerException,
|
||||
|
@ -1508,9 +1438,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
);
|
||||
}
|
||||
if checker.enabled(Rule::PandasDfVariableName) {
|
||||
if let Some(diagnostic) = pandas_vet::rules::assignment_to_df(targets) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
pandas_vet::rules::assignment_to_df(checker, targets);
|
||||
}
|
||||
if checker
|
||||
.settings
|
||||
|
@ -1704,11 +1632,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
pylint::rules::named_expr_without_context(checker, value);
|
||||
}
|
||||
if checker.enabled(Rule::AsyncioDanglingTask) {
|
||||
if let Some(diagnostic) =
|
||||
ruff::rules::asyncio_dangling_task(value, checker.semantic())
|
||||
{
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
ruff::rules::asyncio_dangling_task(checker, value, checker.semantic());
|
||||
}
|
||||
if checker.enabled(Rule::RepeatedAppend) {
|
||||
refurb::rules::repeated_append(checker, stmt);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_semantic::Exceptions;
|
||||
use ruff_python_stdlib::builtins::version_builtin_was_added;
|
||||
|
||||
|
@ -15,12 +14,12 @@ pub(crate) fn unresolved_references(checker: &Checker) {
|
|||
for reference in checker.semantic.unresolved_references() {
|
||||
if reference.is_wildcard_import() {
|
||||
if checker.enabled(Rule::UndefinedLocalWithImportStarUsage) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::UndefinedLocalWithImportStarUsage {
|
||||
name: reference.name(checker.source()).to_string(),
|
||||
},
|
||||
reference.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::UndefinedName) {
|
||||
|
@ -42,13 +41,13 @@ pub(crate) fn unresolved_references(checker: &Checker) {
|
|||
|
||||
let symbol_name = reference.name(checker.source());
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
pyflakes::rules::UndefinedName {
|
||||
name: symbol_name.to_string(),
|
||||
minor_version_builtin_added: version_builtin_was_added(symbol_name),
|
||||
},
|
||||
reference.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ use ruff_python_parser::semantic_errors::{
|
|||
};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, IsolationLevel};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, IsolationLevel, Violation};
|
||||
use ruff_notebook::{CellOffsets, NotebookIndex};
|
||||
use ruff_python_ast::helpers::{collect_import_from_member, is_docstring_stmt, to_module_path};
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
|
@ -66,7 +66,7 @@ use crate::importer::{ImportRequest, Importer, ResolutionError};
|
|||
use crate::noqa::NoqaMapping;
|
||||
use crate::package::PackageRoot;
|
||||
use crate::preview::{is_semantic_errors_enabled, is_undefined_export_in_dunder_init_enabled};
|
||||
use crate::registry::Rule;
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rules::pyflakes::rules::{
|
||||
LateFutureImport, ReturnOutsideFunction, YieldOutsideFunction,
|
||||
};
|
||||
|
@ -379,10 +379,40 @@ impl<'a> Checker<'a> {
|
|||
self.indexer.comment_ranges()
|
||||
}
|
||||
|
||||
/// Push a new [`Diagnostic`] to the collection in the [`Checker`]
|
||||
pub(crate) fn report_diagnostic(&self, diagnostic: Diagnostic) {
|
||||
let mut diagnostics = self.diagnostics.borrow_mut();
|
||||
diagnostics.push(diagnostic);
|
||||
/// Return a [`DiagnosticGuard`] for reporting a diagnostic.
|
||||
///
|
||||
/// The guard derefs to a [`Diagnostic`], so it can be used to further modify the diagnostic
|
||||
/// before it is added to the collection in the checker on `Drop`.
|
||||
pub(crate) fn report_diagnostic<'chk, T: Violation>(
|
||||
&'chk self,
|
||||
kind: T,
|
||||
range: TextRange,
|
||||
) -> DiagnosticGuard<'chk, 'a> {
|
||||
DiagnosticGuard {
|
||||
checker: self,
|
||||
diagnostic: Some(Diagnostic::new(kind, range)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a [`DiagnosticGuard`] for reporting a diagnostic if the corresponding rule is
|
||||
/// enabled.
|
||||
///
|
||||
/// Prefer [`Checker::report_diagnostic`] in general because the conversion from a `Diagnostic`
|
||||
/// to a `Rule` is somewhat expensive.
|
||||
pub(crate) fn report_diagnostic_if_enabled<'chk, T: Violation>(
|
||||
&'chk self,
|
||||
kind: T,
|
||||
range: TextRange,
|
||||
) -> Option<DiagnosticGuard<'chk, 'a>> {
|
||||
let diagnostic = Diagnostic::new(kind, range);
|
||||
if self.enabled(diagnostic.rule()) {
|
||||
Some(DiagnosticGuard {
|
||||
checker: self,
|
||||
diagnostic: Some(diagnostic),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a [`TextRange`] to the set of ranges of variable names
|
||||
|
@ -508,9 +538,9 @@ impl<'a> Checker<'a> {
|
|||
}
|
||||
|
||||
/// Push `diagnostic` if the checker is not in a `@no_type_check` context.
|
||||
pub(crate) fn report_type_diagnostic(&self, diagnostic: Diagnostic) {
|
||||
pub(crate) fn report_type_diagnostic<T: Violation>(&self, kind: T, range: TextRange) {
|
||||
if !self.semantic.in_no_type_check() {
|
||||
self.report_diagnostic(diagnostic);
|
||||
self.report_diagnostic(kind, range);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,7 +625,7 @@ impl SemanticSyntaxContext for Checker<'_> {
|
|||
match error.kind {
|
||||
SemanticSyntaxErrorKind::LateFutureImport => {
|
||||
if self.settings.rules.enabled(Rule::LateFutureImport) {
|
||||
self.report_diagnostic(Diagnostic::new(LateFutureImport, error.range));
|
||||
self.report_diagnostic(LateFutureImport, error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::LoadBeforeGlobalDeclaration { name, start } => {
|
||||
|
@ -604,31 +634,28 @@ impl SemanticSyntaxContext for Checker<'_> {
|
|||
.rules
|
||||
.enabled(Rule::LoadBeforeGlobalDeclaration)
|
||||
{
|
||||
self.report_diagnostic(Diagnostic::new(
|
||||
self.report_diagnostic(
|
||||
LoadBeforeGlobalDeclaration {
|
||||
name,
|
||||
row: self.compute_source_row(start),
|
||||
},
|
||||
error.range,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::YieldOutsideFunction(kind) => {
|
||||
if self.settings.rules.enabled(Rule::YieldOutsideFunction) {
|
||||
self.report_diagnostic(Diagnostic::new(
|
||||
YieldOutsideFunction::new(kind),
|
||||
error.range,
|
||||
));
|
||||
self.report_diagnostic(YieldOutsideFunction::new(kind), error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::ReturnOutsideFunction => {
|
||||
if self.settings.rules.enabled(Rule::ReturnOutsideFunction) {
|
||||
self.report_diagnostic(Diagnostic::new(ReturnOutsideFunction, error.range));
|
||||
self.report_diagnostic(ReturnOutsideFunction, error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::AwaitOutsideAsyncFunction(_) => {
|
||||
if self.settings.rules.enabled(Rule::AwaitOutsideAsync) {
|
||||
self.report_diagnostic(Diagnostic::new(AwaitOutsideAsync, error.range));
|
||||
self.report_diagnostic(AwaitOutsideAsync, error.range);
|
||||
}
|
||||
}
|
||||
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
||||
|
@ -2717,12 +2744,12 @@ impl<'a> Checker<'a> {
|
|||
self.semantic.restore(snapshot);
|
||||
|
||||
if self.enabled(Rule::ForwardAnnotationSyntaxError) {
|
||||
self.report_type_diagnostic(Diagnostic::new(
|
||||
self.report_type_diagnostic(
|
||||
pyflakes::rules::ForwardAnnotationSyntaxError {
|
||||
parse_error: parse_error.error.to_string(),
|
||||
},
|
||||
string_expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3020,3 +3047,59 @@ pub(crate) fn check_ast(
|
|||
|
||||
(diagnostics.into_inner(), semantic_errors.into_inner())
|
||||
}
|
||||
|
||||
/// An abstraction for mutating a diagnostic.
|
||||
///
|
||||
/// Callers can build this guard by starting with `Checker::report_diagnostic`.
|
||||
///
|
||||
/// The primary function of this guard is to add the underlying diagnostic to the `Checker`'s list
|
||||
/// of diagnostics on `Drop`, while dereferencing to the underlying diagnostic for mutations like
|
||||
/// adding fixes or parent ranges.
|
||||
pub(crate) struct DiagnosticGuard<'a, 'b> {
|
||||
/// The parent checker that will receive the diagnostic on `Drop`.
|
||||
checker: &'a Checker<'b>,
|
||||
/// The diagnostic that we want to report.
|
||||
///
|
||||
/// This is always `Some` until the `Drop` (or `defuse`) call.
|
||||
diagnostic: Option<Diagnostic>,
|
||||
}
|
||||
|
||||
impl DiagnosticGuard<'_, '_> {
|
||||
/// Consume the underlying `Diagnostic` without emitting it.
|
||||
///
|
||||
/// In general you should avoid constructing diagnostics that may not be emitted, but this
|
||||
/// method can be used where this is unavoidable.
|
||||
pub(crate) fn defuse(mut self) {
|
||||
self.diagnostic = None;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for DiagnosticGuard<'_, '_> {
|
||||
type Target = Diagnostic;
|
||||
|
||||
fn deref(&self) -> &Diagnostic {
|
||||
// OK because `self.diagnostic` is only `None` within `Drop`.
|
||||
self.diagnostic.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a mutable borrow of the diagnostic in this guard.
|
||||
impl std::ops::DerefMut for DiagnosticGuard<'_, '_> {
|
||||
fn deref_mut(&mut self) -> &mut Diagnostic {
|
||||
// OK because `self.diagnostic` is only `None` within `Drop`.
|
||||
self.diagnostic.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DiagnosticGuard<'_, '_> {
|
||||
fn drop(&mut self) {
|
||||
if std::thread::panicking() {
|
||||
// Don't submit diagnostics when panicking because they might be incomplete.
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(diagnostic) = self.diagnostic.take() {
|
||||
self.checker.diagnostics.borrow_mut().push(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::Expr;
|
||||
use ruff_python_ast::{self as ast};
|
||||
|
@ -86,6 +86,5 @@ pub(crate) fn dag_no_schedule_argument(checker: &Checker, expr: &Expr) {
|
|||
}
|
||||
|
||||
// Produce a diagnostic when the `schedule` keyword argument is not found.
|
||||
let diagnostic = Diagnostic::new(AirflowDagNoScheduleArgument, expr.range());
|
||||
checker.report_diagnostic(diagnostic);
|
||||
checker.report_diagnostic(AirflowDagNoScheduleArgument, expr.range());
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::importer::ImportRequest;
|
||||
use crate::rules::airflow::helpers::{ProviderReplacement, is_guarded_by_try_except};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_python_ast::{Expr, ExprAttribute};
|
||||
use ruff_python_semantic::Modules;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -28,12 +29,12 @@ use crate::checkers::ast::Checker;
|
|||
/// from airflow.providers.fab.auth_manager.fab_auth_manage import FabAuthManager
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct Airflow3MovedToProvider {
|
||||
deprecated: String,
|
||||
pub(crate) struct Airflow3MovedToProvider<'a> {
|
||||
deprecated: QualifiedName<'a>,
|
||||
replacement: ProviderReplacement,
|
||||
}
|
||||
|
||||
impl Violation for Airflow3MovedToProvider {
|
||||
impl Violation for Airflow3MovedToProvider<'_> {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
|
||||
|
||||
#[derive_message_formats]
|
||||
|
@ -1197,34 +1198,42 @@ fn check_names_moved_to_provider(checker: &Checker, expr: &Expr, ranged: TextRan
|
|||
_ => return,
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
Airflow3MovedToProvider {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
ranged.range(),
|
||||
);
|
||||
|
||||
let semantic = checker.semantic();
|
||||
if let Some((module, name)) = match &replacement {
|
||||
ProviderReplacement::AutoImport { module, name, .. } => Some((module, *name)),
|
||||
let (module, name) = match &replacement {
|
||||
ProviderReplacement::AutoImport { module, name, .. } => (module, *name),
|
||||
ProviderReplacement::SourceModuleMovedToProvider { module, name, .. } => {
|
||||
Some((module, name.as_str()))
|
||||
(module, name.as_str())
|
||||
}
|
||||
ProviderReplacement::None => None,
|
||||
} {
|
||||
if is_guarded_by_try_except(expr, module, name, semantic) {
|
||||
ProviderReplacement::None => {
|
||||
checker.report_diagnostic(
|
||||
Airflow3MovedToProvider {
|
||||
deprecated: qualified_name,
|
||||
replacement,
|
||||
},
|
||||
ranged,
|
||||
);
|
||||
return;
|
||||
}
|
||||
diagnostic.try_set_fix(|| {
|
||||
};
|
||||
|
||||
if is_guarded_by_try_except(expr, module, name, checker.semantic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
checker
|
||||
.report_diagnostic(
|
||||
Airflow3MovedToProvider {
|
||||
deprecated: qualified_name,
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
ranged,
|
||||
)
|
||||
.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import_from(module, name),
|
||||
expr.start(),
|
||||
checker.semantic(),
|
||||
)?;
|
||||
let replacement_edit = Edit::range_replacement(binding, ranged.range());
|
||||
let replacement_edit = Edit::range_replacement(binding, ranged);
|
||||
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
|
||||
});
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::importer::ImportRequest;
|
|||
use crate::rules::airflow::helpers::{
|
||||
Replacement, is_airflow_builtin_or_provider, is_guarded_by_try_except,
|
||||
};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::map_callable;
|
||||
use ruff_python_ast::{
|
||||
|
@ -166,13 +166,13 @@ fn check_function_parameters(checker: &Checker, function_def: &StmtFunctionDef)
|
|||
for param in function_def.parameters.iter_non_variadic_params() {
|
||||
let param_name = param.name();
|
||||
if REMOVED_CONTEXT_KEYS.contains(¶m_name.as_str()) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: param_name.to_string(),
|
||||
replacement: Replacement::None,
|
||||
},
|
||||
param_name.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ fn check_call_arguments(checker: &Checker, qualified_name: &QualifiedName, argum
|
|||
segments => {
|
||||
if is_airflow_auth_manager(segments) {
|
||||
if !arguments.is_empty() {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: String::from("appbuilder"),
|
||||
replacement: Replacement::Message(
|
||||
|
@ -208,7 +208,7 @@ fn check_call_arguments(checker: &Checker, qualified_name: &QualifiedName, argum
|
|||
),
|
||||
},
|
||||
arguments.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
} else if is_airflow_task_handler(segments) {
|
||||
diagnostic_for_argument(checker, arguments, "filename_template", None);
|
||||
|
@ -305,7 +305,7 @@ fn check_class_attribute(checker: &Checker, attribute_expr: &ExprAttribute) {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: attr.to_string(),
|
||||
replacement,
|
||||
|
@ -315,7 +315,6 @@ fn check_class_attribute(checker: &Checker, attribute_expr: &ExprAttribute) {
|
|||
if let Some(fix) = fix {
|
||||
diagnostic.set_fix(fix);
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
/// Checks whether an Airflow 3.0–removed context key is used in a function decorated with `@task`.
|
||||
|
@ -382,13 +381,13 @@ fn check_context_key_usage_in_call(checker: &Checker, call_expr: &ExprCall) {
|
|||
continue;
|
||||
};
|
||||
if value == removed_key {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: removed_key.to_string(),
|
||||
replacement: Replacement::None,
|
||||
},
|
||||
*range,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,13 +422,13 @@ fn check_context_key_usage_in_subscript(checker: &Checker, subscript: &ExprSubsc
|
|||
}
|
||||
|
||||
if REMOVED_CONTEXT_KEYS.contains(&key.to_str()) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: key.to_string(),
|
||||
replacement: Replacement::None,
|
||||
},
|
||||
slice.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,7 +536,7 @@ fn check_method(checker: &Checker, call_expr: &ExprCall) {
|
|||
None
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: attr.to_string(),
|
||||
replacement,
|
||||
|
@ -547,7 +546,6 @@ fn check_method(checker: &Checker, call_expr: &ExprCall) {
|
|||
if let Some(fix) = fix {
|
||||
diagnostic.set_fix(fix);
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
/// Check whether a removed Airflow name is used.
|
||||
|
@ -966,26 +964,36 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
_ => return,
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
Airflow3Removal {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
range,
|
||||
);
|
||||
let semantic = checker.semantic();
|
||||
if let Some((module, name)) = match &replacement {
|
||||
Replacement::AutoImport { module, name } => Some((module, *name)),
|
||||
Replacement::SourceModuleMoved { module, name } => Some((module, name.as_str())),
|
||||
_ => None,
|
||||
} {
|
||||
if is_guarded_by_try_except(expr, module, name, semantic) {
|
||||
let (module, name) = match &replacement {
|
||||
Replacement::AutoImport { module, name } => (module, *name),
|
||||
Replacement::SourceModuleMoved { module, name } => (module, name.as_str()),
|
||||
_ => {
|
||||
checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
range,
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let import_target = name.split('.').next().unwrap_or(name);
|
||||
if is_guarded_by_try_except(expr, module, name, checker.semantic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
diagnostic.try_set_fix(|| {
|
||||
let import_target = name.split('.').next().unwrap_or(name);
|
||||
|
||||
checker
|
||||
.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
range,
|
||||
)
|
||||
.try_set_fix(|| {
|
||||
let (import_edit, _) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import_from(module, import_target),
|
||||
expr.start(),
|
||||
|
@ -994,9 +1002,6 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
let replacement_edit = Edit::range_replacement(name.to_string(), range);
|
||||
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
|
||||
});
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
/// Check whether a customized Airflow plugin contains removed extensions.
|
||||
|
@ -1028,7 +1033,7 @@ fn check_airflow_plugin_extension(
|
|||
)
|
||||
})
|
||||
}) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: name.to_string(),
|
||||
replacement: Replacement::Message(
|
||||
|
@ -1036,7 +1041,7 @@ fn check_airflow_plugin_extension(
|
|||
),
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1052,7 +1057,11 @@ fn diagnostic_for_argument(
|
|||
let Some(keyword) = arguments.find_keyword(deprecated) else {
|
||||
return;
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let range = keyword
|
||||
.arg
|
||||
.as_ref()
|
||||
.map_or_else(|| keyword.range(), Ranged::range);
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
Airflow3Removal {
|
||||
deprecated: deprecated.to_string(),
|
||||
replacement: match replacement {
|
||||
|
@ -1060,20 +1069,15 @@ fn diagnostic_for_argument(
|
|||
None => Replacement::None,
|
||||
},
|
||||
},
|
||||
keyword
|
||||
.arg
|
||||
.as_ref()
|
||||
.map_or_else(|| keyword.range(), Ranged::range),
|
||||
range,
|
||||
);
|
||||
|
||||
if let Some(replacement) = replacement {
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
replacement.to_string(),
|
||||
diagnostic.range,
|
||||
range,
|
||||
)));
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
/// Check whether the symbol is coming from the `secrets` builtin or provider module which ends
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::importer::ImportRequest;
|
||||
|
||||
use crate::rules::airflow::helpers::{ProviderReplacement, is_guarded_by_try_except};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_python_ast::{Expr, ExprAttribute};
|
||||
use ruff_python_semantic::Modules;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -30,12 +31,12 @@ use crate::checkers::ast::Checker;
|
|||
/// from airflow.providers.standard.operators.python import PythonOperator
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct Airflow3SuggestedToMoveToProvider {
|
||||
deprecated: String,
|
||||
pub(crate) struct Airflow3SuggestedToMoveToProvider<'a> {
|
||||
deprecated: QualifiedName<'a>,
|
||||
replacement: ProviderReplacement,
|
||||
}
|
||||
|
||||
impl Violation for Airflow3SuggestedToMoveToProvider {
|
||||
impl Violation for Airflow3SuggestedToMoveToProvider<'_> {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
|
@ -281,26 +282,36 @@ fn check_names_moved_to_provider(checker: &Checker, expr: &Expr, ranged: TextRan
|
|||
_ => return,
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
Airflow3SuggestedToMoveToProvider {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
ranged.range(),
|
||||
);
|
||||
|
||||
let semantic = checker.semantic();
|
||||
if let Some((module, name)) = match &replacement {
|
||||
ProviderReplacement::AutoImport { module, name, .. } => Some((module, *name)),
|
||||
let (module, name) = match &replacement {
|
||||
ProviderReplacement::AutoImport { module, name, .. } => (module, *name),
|
||||
ProviderReplacement::SourceModuleMovedToProvider { module, name, .. } => {
|
||||
Some((module, name.as_str()))
|
||||
(module, name.as_str())
|
||||
}
|
||||
ProviderReplacement::None => None,
|
||||
} {
|
||||
if is_guarded_by_try_except(expr, module, name, semantic) {
|
||||
ProviderReplacement::None => {
|
||||
checker.report_diagnostic(
|
||||
Airflow3SuggestedToMoveToProvider {
|
||||
deprecated: qualified_name,
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
ranged.range(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
diagnostic.try_set_fix(|| {
|
||||
};
|
||||
|
||||
if is_guarded_by_try_except(expr, module, name, checker.semantic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
checker
|
||||
.report_diagnostic(
|
||||
Airflow3SuggestedToMoveToProvider {
|
||||
deprecated: qualified_name,
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
ranged.range(),
|
||||
)
|
||||
.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import_from(module, name),
|
||||
expr.start(),
|
||||
|
@ -309,7 +320,4 @@ fn check_names_moved_to_provider(checker: &Checker, expr: &Expr, ranged: TextRan
|
|||
let replacement_edit = Edit::range_replacement(binding, ranged.range());
|
||||
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
|
||||
});
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::importer::ImportRequest;
|
|||
use crate::rules::airflow::helpers::{
|
||||
Replacement, is_airflow_builtin_or_provider, is_guarded_by_try_except,
|
||||
};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{Arguments, Expr, ExprAttribute, ExprCall, ExprName, name::QualifiedName};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -120,7 +120,11 @@ fn diagnostic_for_argument(
|
|||
let Some(keyword) = arguments.find_keyword(deprecated) else {
|
||||
return;
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let range = keyword
|
||||
.arg
|
||||
.as_ref()
|
||||
.map_or_else(|| keyword.range(), Ranged::range);
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
Airflow3SuggestedUpdate {
|
||||
deprecated: deprecated.to_string(),
|
||||
replacement: match replacement {
|
||||
|
@ -128,20 +132,15 @@ fn diagnostic_for_argument(
|
|||
None => Replacement::None,
|
||||
},
|
||||
},
|
||||
keyword
|
||||
.arg
|
||||
.as_ref()
|
||||
.map_or_else(|| keyword.range(), Ranged::range),
|
||||
range,
|
||||
);
|
||||
|
||||
if let Some(replacement) = replacement {
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
replacement.to_string(),
|
||||
diagnostic.range,
|
||||
range,
|
||||
)));
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
/// Check whether a removed Airflow argument is passed.
|
||||
///
|
||||
|
@ -284,24 +283,34 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
_ => return,
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
Airflow3SuggestedUpdate {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
range,
|
||||
);
|
||||
|
||||
let semantic = checker.semantic();
|
||||
if let Some((module, name)) = match &replacement {
|
||||
Replacement::AutoImport { module, name } => Some((module, *name)),
|
||||
Replacement::SourceModuleMoved { module, name } => Some((module, name.as_str())),
|
||||
_ => None,
|
||||
} {
|
||||
if is_guarded_by_try_except(expr, module, name, semantic) {
|
||||
let (module, name) = match &replacement {
|
||||
Replacement::AutoImport { module, name } => (module, *name),
|
||||
Replacement::SourceModuleMoved { module, name } => (module, name.as_str()),
|
||||
_ => {
|
||||
checker.report_diagnostic(
|
||||
Airflow3SuggestedUpdate {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
range,
|
||||
);
|
||||
return;
|
||||
}
|
||||
diagnostic.try_set_fix(|| {
|
||||
};
|
||||
|
||||
if is_guarded_by_try_except(expr, module, name, checker.semantic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
checker
|
||||
.report_diagnostic(
|
||||
Airflow3SuggestedUpdate {
|
||||
deprecated: qualified_name.to_string(),
|
||||
replacement: replacement.clone(),
|
||||
},
|
||||
range,
|
||||
)
|
||||
.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import_from(module, name),
|
||||
expr.start(),
|
||||
|
@ -310,7 +319,4 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
let replacement_edit = Edit::range_replacement(binding, range);
|
||||
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
|
||||
});
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::Expr;
|
||||
|
@ -110,11 +110,10 @@ pub(crate) fn variable_name_task_id(checker: &Checker, targets: &[Expr], value:
|
|||
return;
|
||||
}
|
||||
|
||||
let diagnostic = Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
AirflowVariableNameTaskIdMismatch {
|
||||
task_id: task_id.to_string(),
|
||||
},
|
||||
target.range(),
|
||||
);
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::helpers::map_callable;
|
||||
|
@ -237,7 +237,7 @@ fn create_diagnostic(
|
|||
return seen_default;
|
||||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
FastApiNonAnnotatedDependency {
|
||||
py_version: checker.target_version(),
|
||||
},
|
||||
|
@ -308,7 +308,5 @@ fn create_diagnostic(
|
|||
}
|
||||
diagnostic.try_set_optional_fix(|| fix);
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
|
||||
seen_default
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{Decorator, Expr, ExprCall, Keyword, StmtFunctionDef};
|
||||
use ruff_python_semantic::{Modules, SemanticModel};
|
||||
|
@ -85,7 +85,7 @@ pub(crate) fn fastapi_redundant_response_model(checker: &Checker, function_def:
|
|||
continue;
|
||||
};
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(FastApiRedundantResponseModel, response_model_arg.range());
|
||||
checker.report_diagnostic(FastApiRedundantResponseModel, response_model_arg.range());
|
||||
diagnostic.try_set_fix(|| {
|
||||
remove_argument(
|
||||
response_model_arg,
|
||||
|
@ -95,7 +95,6 @@ pub(crate) fn fastapi_redundant_response_model(checker: &Checker, function_def:
|
|||
)
|
||||
.map(Fix::unsafe_edit)
|
||||
});
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::ops::Range;
|
|||
use std::str::CharIndices;
|
||||
|
||||
use ruff_diagnostics::Fix;
|
||||
use ruff_diagnostics::{Diagnostic, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::{Arguments, Expr, ExprCall, ExprSubscript, Parameter, ParameterWithDefault};
|
||||
|
@ -186,7 +186,7 @@ pub(crate) fn fastapi_unused_path_parameter(
|
|||
.iter()
|
||||
.any(|param| param.name() == path_param);
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
FastApiUnusedPathParameter {
|
||||
arg_name: path_param.to_string(),
|
||||
function_name: function_def.name.to_string(),
|
||||
|
@ -204,7 +204,6 @@ pub(crate) fn fastapi_unused_path_parameter(
|
|||
checker.locator().contents(),
|
||||
)));
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, CmpOp, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -254,12 +254,12 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
) = (ops, comparators)
|
||||
{
|
||||
if *n == 3 && checker.enabled(Rule::SysVersionInfo0Eq3) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SysVersionInfo0Eq3 {
|
||||
eq: matches!(*operator, CmpOp::Eq),
|
||||
},
|
||||
left.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if *i == 1 {
|
||||
|
@ -274,10 +274,7 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
) = (ops, comparators)
|
||||
{
|
||||
if checker.enabled(Rule::SysVersionInfo1CmpInt) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
SysVersionInfo1CmpInt,
|
||||
left.range(),
|
||||
));
|
||||
checker.report_diagnostic(SysVersionInfo1CmpInt, left.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,10 +295,7 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
) = (ops, comparators)
|
||||
{
|
||||
if checker.enabled(Rule::SysVersionInfoMinorCmpInt) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
SysVersionInfoMinorCmpInt,
|
||||
left.range(),
|
||||
));
|
||||
checker.report_diagnostic(SysVersionInfoMinorCmpInt, left.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,10 +311,10 @@ pub(crate) fn compare(checker: &Checker, left: &Expr, ops: &[CmpOp], comparators
|
|||
{
|
||||
if value.len() == 1 {
|
||||
if checker.enabled(Rule::SysVersionCmpStr10) {
|
||||
checker.report_diagnostic(Diagnostic::new(SysVersionCmpStr10, left.range()));
|
||||
checker.report_diagnostic(SysVersionCmpStr10, left.range());
|
||||
}
|
||||
} else if checker.enabled(Rule::SysVersionCmpStr3) {
|
||||
checker.report_diagnostic(Diagnostic::new(SysVersionCmpStr3, left.range()));
|
||||
checker.report_diagnostic(SysVersionCmpStr3, left.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::Expr;
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -56,6 +56,6 @@ pub(crate) fn name_or_attribute(checker: &Checker, expr: &Expr) {
|
|||
.resolve_qualified_name(expr)
|
||||
.is_some_and(|qualified_name| matches!(qualified_name.segments(), ["six", "PY3"]))
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(SixPY3, expr.range()));
|
||||
checker.report_diagnostic(SixPY3, expr.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -183,9 +183,9 @@ pub(crate) fn subscript(checker: &Checker, value: &Expr, slice: &Expr) {
|
|||
}) = upper.as_ref()
|
||||
{
|
||||
if *i == 1 && checker.enabled(Rule::SysVersionSlice1) {
|
||||
checker.report_diagnostic(Diagnostic::new(SysVersionSlice1, value.range()));
|
||||
checker.report_diagnostic(SysVersionSlice1, value.range());
|
||||
} else if *i == 3 && checker.enabled(Rule::SysVersionSlice3) {
|
||||
checker.report_diagnostic(Diagnostic::new(SysVersionSlice3, value.range()));
|
||||
checker.report_diagnostic(SysVersionSlice3, value.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +195,9 @@ pub(crate) fn subscript(checker: &Checker, value: &Expr, slice: &Expr) {
|
|||
..
|
||||
}) => {
|
||||
if *i == 2 && checker.enabled(Rule::SysVersion2) {
|
||||
checker.report_diagnostic(Diagnostic::new(SysVersion2, value.range()));
|
||||
checker.report_diagnostic(SysVersion2, value.range());
|
||||
} else if *i == 0 && checker.enabled(Rule::SysVersion0) {
|
||||
checker.report_diagnostic(Diagnostic::new(SysVersion0, value.range()));
|
||||
checker.report_diagnostic(SysVersion0, value.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::ReturnStatementVisitor;
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
|
@ -9,7 +9,7 @@ use ruff_python_semantic::analyze::visibility;
|
|||
use ruff_python_stdlib::typing::simple_magic_return_type;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::checkers::ast::{Checker, DiagnosticGuard};
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::flake8_annotations::helpers::auto_return_type;
|
||||
use crate::rules::ruff::typing::type_hint_resolves_to_any;
|
||||
|
@ -529,11 +529,11 @@ fn is_none_returning(body: &[Stmt]) -> bool {
|
|||
}
|
||||
|
||||
/// ANN401
|
||||
fn check_dynamically_typed<F>(
|
||||
checker: &Checker,
|
||||
fn check_dynamically_typed<'a, 'b, F>(
|
||||
checker: &'a Checker<'b>,
|
||||
annotation: &Expr,
|
||||
func: F,
|
||||
diagnostics: &mut Vec<Diagnostic>,
|
||||
diagnostics: &mut Vec<DiagnosticGuard<'a, 'b>>,
|
||||
) where
|
||||
F: FnOnce() -> String,
|
||||
{
|
||||
|
@ -545,18 +545,14 @@ fn check_dynamically_typed<F>(
|
|||
checker,
|
||||
checker.target_version(),
|
||||
) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
AnyType { name: func() },
|
||||
annotation.range(),
|
||||
));
|
||||
diagnostics
|
||||
.push(checker.report_diagnostic(AnyType { name: func() }, annotation.range()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if type_hint_resolves_to_any(annotation, checker, checker.target_version()) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
AnyType { name: func() },
|
||||
annotation.range(),
|
||||
));
|
||||
diagnostics
|
||||
.push(checker.report_diagnostic(AnyType { name: func() }, annotation.range()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -655,7 +651,7 @@ pub(crate) fn definition(
|
|||
.is_match(parameter.name()))
|
||||
{
|
||||
if checker.enabled(Rule::MissingTypeFunctionArgument) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
diagnostics.push(checker.report_diagnostic(
|
||||
MissingTypeFunctionArgument {
|
||||
name: parameter.name().to_string(),
|
||||
},
|
||||
|
@ -681,7 +677,7 @@ pub(crate) fn definition(
|
|||
&& checker.settings.dummy_variable_rgx.is_match(&arg.name))
|
||||
{
|
||||
if checker.enabled(Rule::MissingTypeArgs) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
diagnostics.push(checker.report_diagnostic(
|
||||
MissingTypeArgs {
|
||||
name: arg.name.to_string(),
|
||||
},
|
||||
|
@ -712,7 +708,7 @@ pub(crate) fn definition(
|
|||
&& checker.settings.dummy_variable_rgx.is_match(&arg.name))
|
||||
{
|
||||
if checker.enabled(Rule::MissingTypeKwargs) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
diagnostics.push(checker.report_diagnostic(
|
||||
MissingTypeKwargs {
|
||||
name: arg.name.to_string(),
|
||||
},
|
||||
|
@ -745,7 +741,7 @@ pub(crate) fn definition(
|
|||
})
|
||||
.map(|(return_type, edits)| (checker.generator().expr(&return_type), edits))
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeClassMethod {
|
||||
name: name.to_string(),
|
||||
annotation: return_type.clone().map(|(return_type, ..)| return_type),
|
||||
|
@ -771,7 +767,7 @@ pub(crate) fn definition(
|
|||
})
|
||||
.map(|(return_type, edits)| (checker.generator().expr(&return_type), edits))
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeStaticMethod {
|
||||
name: name.to_string(),
|
||||
annotation: return_type.clone().map(|(return_type, ..)| return_type),
|
||||
|
@ -791,7 +787,7 @@ pub(crate) fn definition(
|
|||
// least one argument is typed.
|
||||
if checker.enabled(Rule::MissingReturnTypeSpecialMethod) {
|
||||
if !(checker.settings.flake8_annotations.mypy_init_return && has_any_typed_arg) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeSpecialMethod {
|
||||
name: name.to_string(),
|
||||
annotation: Some("None".to_string()),
|
||||
|
@ -808,7 +804,7 @@ pub(crate) fn definition(
|
|||
} else if is_method && visibility::is_magic(name) {
|
||||
if checker.enabled(Rule::MissingReturnTypeSpecialMethod) {
|
||||
let return_type = simple_magic_return_type(name);
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeSpecialMethod {
|
||||
name: name.to_string(),
|
||||
annotation: return_type.map(ToString::to_string),
|
||||
|
@ -839,7 +835,7 @@ pub(crate) fn definition(
|
|||
(checker.generator().expr(&return_type), edits)
|
||||
})
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypeUndocumentedPublicFunction {
|
||||
name: name.to_string(),
|
||||
annotation: return_type
|
||||
|
@ -874,7 +870,7 @@ pub(crate) fn definition(
|
|||
(checker.generator().expr(&return_type), edits)
|
||||
})
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
MissingReturnTypePrivateFunction {
|
||||
name: name.to_string(),
|
||||
annotation: return_type
|
||||
|
@ -901,7 +897,7 @@ pub(crate) fn definition(
|
|||
|
||||
// If settings say so, don't report any of the
|
||||
// diagnostics gathered here if there were no type annotations at all.
|
||||
if !checker.settings.flake8_annotations.ignore_fully_untyped
|
||||
let diagnostics_enabled = !checker.settings.flake8_annotations.ignore_fully_untyped
|
||||
|| has_any_typed_arg
|
||||
|| has_typed_return
|
||||
|| (is_method
|
||||
|
@ -910,10 +906,11 @@ pub(crate) fn definition(
|
|||
.posonlyargs
|
||||
.first()
|
||||
.or_else(|| parameters.args.first())
|
||||
.is_some_and(|first_param| first_param.annotation().is_some()))
|
||||
{
|
||||
.is_some_and(|first_param| first_param.annotation().is_some()));
|
||||
|
||||
if !diagnostics_enabled {
|
||||
for diagnostic in diagnostics {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
diagnostic.defuse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, Stmt};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -74,11 +74,11 @@ pub(crate) fn async_busy_wait(checker: &Checker, while_stmt: &ast::StmtWhile) {
|
|||
qualified_name.segments(),
|
||||
["trio" | "anyio", "sleep" | "sleep_until"] | ["asyncio", "sleep"]
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
AsyncBusyWait {
|
||||
module: AsyncModule::try_from(&qualified_name).unwrap(),
|
||||
},
|
||||
while_stmt.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -112,8 +112,5 @@ pub(crate) fn async_function_with_timeout(checker: &Checker, function_def: &ast:
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
AsyncFunctionWithTimeout { module },
|
||||
timeout.range(),
|
||||
));
|
||||
checker.report_diagnostic(AsyncFunctionWithTimeout { module }, timeout.range());
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, ExprCall, Int, Number};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -109,7 +109,7 @@ pub(crate) fn async_zero_sleep(checker: &Checker, call: &ExprCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(AsyncZeroSleep { module }, call.range());
|
||||
let mut diagnostic = checker.report_diagnostic(AsyncZeroSleep { module }, call.range());
|
||||
diagnostic.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import_from(&module.to_string(), "lowlevel"),
|
||||
|
@ -121,6 +121,5 @@ pub(crate) fn async_zero_sleep(checker: &Checker, call: &ExprCall) {
|
|||
let arg_edit = Edit::range_replacement("()".to_string(), call.arguments.range());
|
||||
Ok(Fix::safe_edits(import_edit, [reference_edit, arg_edit]))
|
||||
});
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::ExprCall;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -70,10 +70,7 @@ pub(crate) fn blocking_http_call(checker: &Checker, call: &ExprCall) {
|
|||
.as_ref()
|
||||
.is_some_and(is_blocking_http_call)
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
BlockingHttpCallInAsyncFunction,
|
||||
call.func.range(),
|
||||
));
|
||||
checker.report_diagnostic(BlockingHttpCallInAsyncFunction, call.func.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_semantic::{SemanticModel, analyze};
|
||||
|
@ -52,10 +52,7 @@ pub(crate) fn blocking_open_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
if is_open_call(&call.func, checker.semantic())
|
||||
|| is_open_call_from_pathlib(call.func.as_ref(), checker.semantic())
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
BlockingOpenCallInAsyncFunction,
|
||||
call.func.range(),
|
||||
));
|
||||
checker.report_diagnostic(BlockingOpenCallInAsyncFunction, call.func.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
|
@ -6,7 +6,6 @@ use ruff_python_semantic::analyze::typing::find_assigned_value;
|
|||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks that async functions do not create subprocesses with blocking methods.
|
||||
|
@ -125,17 +124,17 @@ pub(crate) fn blocking_process_invocation(checker: &Checker, call: &ast::ExprCal
|
|||
};
|
||||
|
||||
let range = call.func.range();
|
||||
let diagnostic = match qualified_name.segments() {
|
||||
match qualified_name.segments() {
|
||||
["subprocess", "Popen"] | ["os", "popen"] => {
|
||||
Diagnostic::new(CreateSubprocessInAsyncFunction, range)
|
||||
checker.report_diagnostic_if_enabled(CreateSubprocessInAsyncFunction, range)
|
||||
}
|
||||
["os", "system" | "posix_spawn" | "posix_spawnp"]
|
||||
| [
|
||||
"subprocess",
|
||||
"run" | "call" | "check_call" | "check_output" | "getoutput" | "getstatusoutput",
|
||||
] => Diagnostic::new(RunProcessInAsyncFunction, range),
|
||||
] => checker.report_diagnostic_if_enabled(RunProcessInAsyncFunction, range),
|
||||
["os", "wait" | "wait3" | "wait4" | "waitid" | "waitpid"] => {
|
||||
Diagnostic::new(WaitForProcessInAsyncFunction, range)
|
||||
checker.report_diagnostic_if_enabled(WaitForProcessInAsyncFunction, range)
|
||||
}
|
||||
[
|
||||
"os",
|
||||
|
@ -143,17 +142,13 @@ pub(crate) fn blocking_process_invocation(checker: &Checker, call: &ast::ExprCal
|
|||
| "spawnvpe",
|
||||
] => {
|
||||
if is_p_wait(call, checker.semantic()) {
|
||||
Diagnostic::new(RunProcessInAsyncFunction, range)
|
||||
checker.report_diagnostic_if_enabled(RunProcessInAsyncFunction, range)
|
||||
} else {
|
||||
Diagnostic::new(CreateSubprocessInAsyncFunction, range)
|
||||
checker.report_diagnostic_if_enabled(CreateSubprocessInAsyncFunction, range)
|
||||
}
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if checker.enabled(diagnostic.rule()) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_p_wait(call: &ast::ExprCall, semantic: &SemanticModel) -> bool {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::ExprCall;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -51,10 +51,7 @@ pub(crate) fn blocking_sleep(checker: &Checker, call: &ExprCall) {
|
|||
.as_ref()
|
||||
.is_some_and(is_blocking_sleep)
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
BlockingSleepInAsyncFunction,
|
||||
call.func.range(),
|
||||
));
|
||||
checker.report_diagnostic(BlockingSleepInAsyncFunction, call.func.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::{AwaitVisitor, any_over_body};
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
|
@ -100,8 +100,5 @@ pub(crate) fn cancel_scope_no_checkpoint(
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
CancelScopeNoCheckpoint { method_name },
|
||||
with_stmt.range,
|
||||
));
|
||||
checker.report_diagnostic(CancelScopeNoCheckpoint { method_name }, with_stmt.range);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{Expr, ExprCall, ExprNumberLiteral, Number};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -137,7 +137,7 @@ pub(crate) fn long_sleep_not_forever(checker: &Checker, call: &ExprCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(LongSleepNotForever { module }, call.range());
|
||||
let mut diagnostic = checker.report_diagnostic(LongSleepNotForever { module }, call.range());
|
||||
let replacement_function = "sleep_forever";
|
||||
diagnostic.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
|
@ -149,5 +149,4 @@ pub(crate) fn long_sleep_not_forever(checker: &Checker, call: &ExprCall) {
|
|||
let arg_edit = Edit::range_replacement("()".to_string(), call.arguments.range());
|
||||
Ok(Fix::unsafe_edits(import_edit, [reference_edit, arg_edit]))
|
||||
});
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{Expr, ExprCall};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -80,7 +80,7 @@ pub(crate) fn sync_call(checker: &Checker, call: &ExprCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(TrioSyncCall { method_name }, call.range);
|
||||
let mut diagnostic = checker.report_diagnostic(TrioSyncCall { method_name }, call.range);
|
||||
if checker.semantic().in_async_context() {
|
||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion(
|
||||
pad(
|
||||
|
@ -91,5 +91,4 @@ pub(crate) fn sync_call(checker: &Checker, call: &ExprCall) {
|
|||
call.func.start(),
|
||||
)));
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use ruff_python_ast::Stmt;
|
||||
use ruff_text_size::{TextLen, TextRange};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for uses of the `assert` keyword.
|
||||
///
|
||||
|
@ -41,6 +43,6 @@ impl Violation for Assert {
|
|||
}
|
||||
|
||||
/// S101
|
||||
pub(crate) fn assert_used(stmt: &Stmt) -> Diagnostic {
|
||||
Diagnostic::new(Assert, TextRange::at(stmt.start(), "assert".text_len()))
|
||||
pub(crate) fn assert_used(checker: &Checker, stmt: &Stmt) {
|
||||
checker.report_diagnostic(Assert, TextRange::at(stmt.start(), "assert".text_len()));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_python_ast::{self as ast, Expr, Operator};
|
||||
|
@ -78,22 +78,22 @@ pub(crate) fn bad_file_permissions(checker: &Checker, call: &ast::ExprCall) {
|
|||
// The mask is a valid integer value -- check for overly permissive permissions.
|
||||
Ok(Some(mask)) => {
|
||||
if (mask & WRITE_WORLD > 0) || (mask & EXECUTE_GROUP > 0) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
BadFilePermissions {
|
||||
reason: Reason::Permissive(mask),
|
||||
},
|
||||
mode_arg.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
// The mask is an invalid integer value (i.e., it's out of range).
|
||||
Err(_) => {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
BadFilePermissions {
|
||||
reason: Reason::Invalid,
|
||||
},
|
||||
mode_arg.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, ExprAttribute};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -54,7 +54,7 @@ pub(crate) fn django_extra(checker: &Checker, call: &ast::ExprCall) {
|
|||
}
|
||||
|
||||
if is_call_insecure(call) {
|
||||
checker.report_diagnostic(Diagnostic::new(DjangoExtra, call.arguments.range()));
|
||||
checker.report_diagnostic(DjangoExtra, call.arguments.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -55,7 +55,7 @@ pub(crate) fn django_raw_sql(checker: &Checker, call: &ast::ExprCall) {
|
|||
.find_argument_value("sql", 0)
|
||||
.is_some_and(Expr::is_string_literal_expr)
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(DjangoRawSql, call.func.range()));
|
||||
checker.report_diagnostic(DjangoRawSql, call.func.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::Expr;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -34,6 +34,6 @@ impl Violation for ExecBuiltin {
|
|||
/// S102
|
||||
pub(crate) fn exec_used(checker: &Checker, func: &Expr) {
|
||||
if checker.semantic().match_builtin_expr(func, "exec") {
|
||||
checker.report_diagnostic(Diagnostic::new(ExecBuiltin, func.range()));
|
||||
checker.report_diagnostic(ExecBuiltin, func.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::is_const_true;
|
||||
use ruff_python_ast::{Expr, ExprAttribute, ExprCall};
|
||||
|
@ -67,6 +67,6 @@ pub(crate) fn flask_debug_true(checker: &Checker, call: &ExprCall) {
|
|||
if typing::resolve_assignment(value, checker.semantic())
|
||||
.is_some_and(|qualified_name| matches!(qualified_name.segments(), ["flask", "Flask"]))
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(FlaskDebugTrue, debug_argument.range()));
|
||||
checker.report_diagnostic(FlaskDebugTrue, debug_argument.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, StringLike};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -41,8 +41,7 @@ pub(crate) fn hardcoded_bind_all_interfaces(checker: &Checker, string: StringLik
|
|||
match string {
|
||||
StringLike::String(ast::ExprStringLiteral { value, .. }) => {
|
||||
if value == "0.0.0.0" {
|
||||
checker
|
||||
.report_diagnostic(Diagnostic::new(HardcodedBindAllInterfaces, string.range()));
|
||||
checker.report_diagnostic(HardcodedBindAllInterfaces, string.range());
|
||||
}
|
||||
}
|
||||
StringLike::FString(ast::ExprFString { value, .. }) => {
|
||||
|
@ -50,19 +49,14 @@ pub(crate) fn hardcoded_bind_all_interfaces(checker: &Checker, string: StringLik
|
|||
match part {
|
||||
ast::FStringPart::Literal(literal) => {
|
||||
if &**literal == "0.0.0.0" {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
HardcodedBindAllInterfaces,
|
||||
literal.range(),
|
||||
));
|
||||
checker.report_diagnostic(HardcodedBindAllInterfaces, literal.range());
|
||||
}
|
||||
}
|
||||
ast::FStringPart::FString(f_string) => {
|
||||
for literal in f_string.elements.literals() {
|
||||
if &**literal == "0.0.0.0" {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
HardcodedBindAllInterfaces,
|
||||
literal.range(),
|
||||
));
|
||||
checker
|
||||
.report_diagnostic(HardcodedBindAllInterfaces, literal.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{Expr, Parameter, Parameters};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -54,18 +54,20 @@ impl Violation for HardcodedPasswordDefault {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_password_kwarg(parameter: &Parameter, default: &Expr) -> Option<Diagnostic> {
|
||||
string_literal(default).filter(|string| !string.is_empty())?;
|
||||
fn check_password_kwarg(checker: &Checker, parameter: &Parameter, default: &Expr) {
|
||||
if string_literal(default).is_none_or(str::is_empty) {
|
||||
return;
|
||||
}
|
||||
let kwarg_name = ¶meter.name;
|
||||
if !matches_password_name(kwarg_name) {
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
Some(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HardcodedPasswordDefault {
|
||||
name: kwarg_name.to_string(),
|
||||
},
|
||||
default.range(),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/// S107
|
||||
|
@ -74,8 +76,6 @@ pub(crate) fn hardcoded_password_default(checker: &Checker, parameters: &Paramet
|
|||
let Some(default) = parameter.default() else {
|
||||
continue;
|
||||
};
|
||||
if let Some(diagnostic) = check_password_kwarg(¶meter.parameter, default) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
check_password_kwarg(checker, ¶meter.parameter, default);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::Keyword;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -62,11 +62,11 @@ pub(crate) fn hardcoded_password_func_arg(checker: &Checker, keywords: &[Keyword
|
|||
if !matches_password_name(arg) {
|
||||
continue;
|
||||
}
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HardcodedPasswordFuncArg {
|
||||
name: arg.to_string(),
|
||||
},
|
||||
keyword.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -83,12 +83,12 @@ pub(crate) fn compare_to_hardcoded_password_string(
|
|||
let Some(name) = password_target(left) else {
|
||||
continue;
|
||||
};
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HardcodedPasswordString {
|
||||
name: name.to_string(),
|
||||
},
|
||||
comp.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,12 +100,12 @@ pub(crate) fn assign_hardcoded_password_string(checker: &Checker, value: &Expr,
|
|||
{
|
||||
for target in targets {
|
||||
if let Some(name) = password_target(target) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HardcodedPasswordString {
|
||||
name: name.to_string(),
|
||||
},
|
||||
value.range(),
|
||||
));
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::sync::LazyLock;
|
|||
|
||||
use regex::Regex;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::str::raw_contents;
|
||||
use ruff_python_ast::{self as ast, Expr, Operator};
|
||||
|
@ -113,7 +113,7 @@ pub(crate) fn hardcoded_sql_expression(checker: &Checker, expr: &Expr) {
|
|||
};
|
||||
|
||||
if SQL_REGEX.is_match(&content) {
|
||||
checker.report_diagnostic(Diagnostic::new(HardcodedSQLExpression, expr.range()));
|
||||
checker.report_diagnostic(HardcodedSQLExpression, expr.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast::{self as ast, Expr, StringLike};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
@ -102,10 +102,10 @@ fn check(checker: &Checker, value: &str, range: TextRange) {
|
|||
}
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HardcodedTempFile {
|
||||
string: value.to_string(),
|
||||
},
|
||||
range,
|
||||
));
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::is_const_false;
|
||||
use ruff_python_ast::{self as ast, Arguments};
|
||||
|
@ -141,23 +141,23 @@ fn detect_insecure_hashlib_calls(
|
|||
hash_func_name.to_ascii_lowercase().as_str(),
|
||||
"md4" | "md5" | "sha" | "sha1"
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HashlibInsecureHashFunction {
|
||||
library: "hashlib".to_string(),
|
||||
string: hash_func_name.to_string(),
|
||||
},
|
||||
name_arg.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
HashlibCall::WeakHash(func_name) => {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HashlibInsecureHashFunction {
|
||||
library: "hashlib".to_string(),
|
||||
string: (*func_name).to_string(),
|
||||
},
|
||||
call.func.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,13 +186,13 @@ fn detect_insecure_crypt_calls(checker: &Checker, call: &ast::ExprCall) {
|
|||
qualified_name.segments(),
|
||||
["crypt", "METHOD_CRYPT" | "METHOD_MD5" | "METHOD_BLOWFISH"]
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
HashlibInsecureHashFunction {
|
||||
library: "crypt".to_string(),
|
||||
string: qualified_name.to_string(),
|
||||
},
|
||||
method.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -70,23 +70,20 @@ pub(crate) fn jinja2_autoescape_false(checker: &Checker, call: &ast::ExprCall) {
|
|||
Expr::Call(ast::ExprCall { func, .. }) => {
|
||||
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
|
||||
if id != "select_autoescape" {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
Jinja2AutoescapeFalse { value: true },
|
||||
keyword.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => checker.report_diagnostic(Diagnostic::new(
|
||||
Jinja2AutoescapeFalse { value: true },
|
||||
keyword.range(),
|
||||
)),
|
||||
_ => {
|
||||
checker
|
||||
.report_diagnostic(Jinja2AutoescapeFalse { value: true }, keyword.range());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
Jinja2AutoescapeFalse { value: false },
|
||||
call.func.range(),
|
||||
));
|
||||
checker.report_diagnostic(Jinja2AutoescapeFalse { value: false }, call.func.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
@ -51,9 +51,6 @@ pub(crate) fn logging_config_insecure_listen(checker: &Checker, call: &ast::Expr
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
LoggingConfigInsecureListen,
|
||||
call.func.range(),
|
||||
));
|
||||
checker.report_diagnostic(LoggingConfigInsecureListen, call.func.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::checkers::ast::Checker;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -50,6 +50,6 @@ pub(crate) fn mako_templates(checker: &Checker, call: &ast::ExprCall) {
|
|||
matches!(qualified_name.segments(), ["mako", "template", "Template"])
|
||||
})
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(MakoTemplates, call.func.range()));
|
||||
checker.report_diagnostic(MakoTemplates, call.func.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::Expr;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -45,6 +45,6 @@ pub(crate) fn paramiko_call(checker: &Checker, func: &Expr) {
|
|||
matches!(qualified_name.segments(), ["paramiko", "exec_command"])
|
||||
})
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(ParamikoCall, func.range()));
|
||||
checker.report_diagnostic(ParamikoCall, func.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::helpers::is_const_false;
|
||||
|
@ -65,12 +65,12 @@ pub(crate) fn request_with_no_cert_validation(checker: &Checker, call: &ast::Exp
|
|||
{
|
||||
if let Some(keyword) = call.arguments.find_keyword("verify") {
|
||||
if is_const_false(&keyword.value) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
RequestWithNoCertValidation {
|
||||
string: target.to_string(),
|
||||
},
|
||||
keyword.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
|
||||
|
@ -70,22 +70,22 @@ pub(crate) fn request_without_timeout(checker: &Checker, call: &ast::ExprCall) {
|
|||
{
|
||||
if let Some(keyword) = call.arguments.find_keyword("timeout") {
|
||||
if keyword.value.is_none_literal_expr() {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
RequestWithoutTimeout {
|
||||
implicit: false,
|
||||
module: module.to_string(),
|
||||
},
|
||||
keyword.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
} else if module == "requests" {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
RequestWithoutTimeout {
|
||||
implicit: true,
|
||||
module: module.to_string(),
|
||||
},
|
||||
call.func.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Checks relating to shell injection.
|
||||
|
||||
use crate::preview::is_shell_injection_only_trusted_input_enabled;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::Truthiness;
|
||||
use ruff_python_ast::{self as ast, Arguments, Expr};
|
||||
|
@ -314,13 +314,13 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
truthiness: truthiness @ (Truthiness::True | Truthiness::Truthy),
|
||||
}) => {
|
||||
if checker.enabled(Rule::SubprocessPopenWithShellEqualsTrue) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SubprocessPopenWithShellEqualsTrue {
|
||||
safety: Safety::from(arg),
|
||||
is_exact: matches!(truthiness, Truthiness::True),
|
||||
},
|
||||
call.func.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
// S603
|
||||
|
@ -329,10 +329,10 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
|| !is_shell_injection_only_trusted_input_enabled(checker.settings)
|
||||
{
|
||||
if checker.enabled(Rule::SubprocessWithoutShellEqualsTrue) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SubprocessWithoutShellEqualsTrue,
|
||||
call.func.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,12 +344,12 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
{
|
||||
// S604
|
||||
if checker.enabled(Rule::CallWithShellEqualsTrue) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
CallWithShellEqualsTrue {
|
||||
is_exact: matches!(truthiness, Truthiness::True),
|
||||
},
|
||||
call.func.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,12 +357,12 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
if checker.enabled(Rule::StartProcessWithAShell) {
|
||||
if matches!(call_kind, Some(CallKind::Shell)) {
|
||||
if let Some(arg) = call.arguments.args.first() {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
StartProcessWithAShell {
|
||||
safety: Safety::from(arg),
|
||||
},
|
||||
call.func.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
// S606
|
||||
if checker.enabled(Rule::StartProcessWithNoShell) {
|
||||
if matches!(call_kind, Some(CallKind::NoShell)) {
|
||||
checker.report_diagnostic(Diagnostic::new(StartProcessWithNoShell, call.func.range()));
|
||||
checker.report_diagnostic(StartProcessWithNoShell, call.func.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,10 +379,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
if call_kind.is_some() {
|
||||
if let Some(arg) = call.arguments.args.first() {
|
||||
if is_partial_path(arg) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
StartProcessWithPartialPath,
|
||||
arg.range(),
|
||||
));
|
||||
checker.report_diagnostic(StartProcessWithPartialPath, arg.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,10 +400,7 @@ pub(crate) fn shell_injection(checker: &Checker, call: &ast::ExprCall) {
|
|||
{
|
||||
if let Some(arg) = call.arguments.args.first() {
|
||||
if is_wildcard_command(arg) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
UnixCommandWildcardInjection,
|
||||
arg.range(),
|
||||
));
|
||||
checker.report_diagnostic(UnixCommandWildcardInjection, arg.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, Int};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -60,7 +60,7 @@ pub(crate) fn snmp_insecure_version(checker: &Checker, call: &ast::ExprCall) {
|
|||
..
|
||||
})
|
||||
) {
|
||||
checker.report_diagnostic(Diagnostic::new(SnmpInsecureVersion, keyword.range()));
|
||||
checker.report_diagnostic(SnmpInsecureVersion, keyword.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -52,7 +52,7 @@ pub(crate) fn snmp_weak_cryptography(checker: &Checker, call: &ast::ExprCall) {
|
|||
)
|
||||
})
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(SnmpWeakCryptography, call.func.range()));
|
||||
checker.report_diagnostic(SnmpWeakCryptography, call.func.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::map_callable;
|
||||
use ruff_python_ast::{Expr, ExprAttribute, ExprCall};
|
||||
|
@ -78,9 +78,6 @@ pub(crate) fn ssh_no_host_key_verification(checker: &Checker, call: &ExprCall) {
|
|||
["paramiko", "client", "SSHClient"] | ["paramiko", "SSHClient"]
|
||||
)
|
||||
}) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
SSHNoHostKeyVerification,
|
||||
policy_argument.range(),
|
||||
));
|
||||
checker.report_diagnostic(SSHNoHostKeyVerification, policy_argument.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, ExprCall};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -68,22 +68,22 @@ pub(crate) fn ssl_insecure_version(checker: &Checker, call: &ExprCall) {
|
|||
match &keyword.value {
|
||||
Expr::Name(ast::ExprName { id, .. }) => {
|
||||
if is_insecure_protocol(id) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SslInsecureVersion {
|
||||
protocol: id.to_string(),
|
||||
},
|
||||
keyword.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
Expr::Attribute(ast::ExprAttribute { attr, .. }) => {
|
||||
if is_insecure_protocol(attr) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SslInsecureVersion {
|
||||
protocol: attr.to_string(),
|
||||
},
|
||||
keyword.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, StmtFunctionDef};
|
||||
|
||||
|
@ -57,22 +57,22 @@ pub(crate) fn ssl_with_bad_defaults(checker: &Checker, function_def: &StmtFuncti
|
|||
match default {
|
||||
Expr::Name(ast::ExprName { id, range, .. }) => {
|
||||
if is_insecure_protocol(id.as_str()) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SslWithBadDefaults {
|
||||
protocol: id.to_string(),
|
||||
},
|
||||
*range,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
Expr::Attribute(ast::ExprAttribute { attr, range, .. }) => {
|
||||
if is_insecure_protocol(attr.as_str()) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
SslWithBadDefaults {
|
||||
protocol: attr.to_string(),
|
||||
},
|
||||
*range,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::ExprCall;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -43,7 +43,7 @@ pub(crate) fn ssl_with_no_version(checker: &Checker, call: &ExprCall) {
|
|||
.is_some_and(|qualified_name| matches!(qualified_name.segments(), ["ssl", "wrap_socket"]))
|
||||
{
|
||||
if call.arguments.find_keyword("ssl_version").is_none() {
|
||||
checker.report_diagnostic(Diagnostic::new(SslWithNoVersion, call.range()));
|
||||
checker.report_diagnostic(SslWithNoVersion, call.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
//!
|
||||
//! See: <https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html>
|
||||
use itertools::Either;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr, ExprCall, Operator};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::preview::is_suspicious_function_reference_enabled;
|
||||
use crate::registry::AsRule;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for calls to `pickle` functions or modules that wrap them.
|
||||
|
@ -1035,16 +1034,20 @@ fn suspicious_function(
|
|||
return;
|
||||
};
|
||||
|
||||
let diagnostic = match qualified_name.segments() {
|
||||
match qualified_name.segments() {
|
||||
// Pickle
|
||||
["pickle" | "dill", "load" | "loads" | "Unpickler"]
|
||||
| ["shelve", "open" | "DbfilenameShelf"]
|
||||
| ["jsonpickle", "decode"]
|
||||
| ["jsonpickle", "unpickler", "decode"]
|
||||
| ["pandas", "read_pickle"] => Diagnostic::new(SuspiciousPickleUsage, range),
|
||||
| ["pandas", "read_pickle"] => {
|
||||
checker.report_diagnostic_if_enabled(SuspiciousPickleUsage, range)
|
||||
}
|
||||
|
||||
// Marshal
|
||||
["marshal", "load" | "loads"] => Diagnostic::new(SuspiciousMarshalUsage, range),
|
||||
["marshal", "load" | "loads"] => {
|
||||
checker.report_diagnostic_if_enabled(SuspiciousMarshalUsage, range)
|
||||
}
|
||||
|
||||
// InsecureHash
|
||||
[
|
||||
|
@ -1059,7 +1062,7 @@ fn suspicious_function(
|
|||
"primitives",
|
||||
"hashes",
|
||||
"SHA1" | "MD5",
|
||||
] => Diagnostic::new(SuspiciousInsecureHashUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousInsecureHashUsage, range),
|
||||
|
||||
// InsecureCipher
|
||||
[
|
||||
|
@ -1075,7 +1078,7 @@ fn suspicious_function(
|
|||
"ciphers",
|
||||
"algorithms",
|
||||
"ARC4" | "Blowfish" | "IDEA",
|
||||
] => Diagnostic::new(SuspiciousInsecureCipherUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousInsecureCipherUsage, range),
|
||||
|
||||
// InsecureCipherMode
|
||||
[
|
||||
|
@ -1085,13 +1088,17 @@ fn suspicious_function(
|
|||
"ciphers",
|
||||
"modes",
|
||||
"ECB",
|
||||
] => Diagnostic::new(SuspiciousInsecureCipherModeUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousInsecureCipherModeUsage, range),
|
||||
|
||||
// Mktemp
|
||||
["tempfile", "mktemp"] => Diagnostic::new(SuspiciousMktempUsage, range),
|
||||
["tempfile", "mktemp"] => {
|
||||
checker.report_diagnostic_if_enabled(SuspiciousMktempUsage, range)
|
||||
}
|
||||
|
||||
// Eval
|
||||
["" | "builtins", "eval"] => Diagnostic::new(SuspiciousEvalUsage, range),
|
||||
["" | "builtins", "eval"] => {
|
||||
checker.report_diagnostic_if_enabled(SuspiciousEvalUsage, range)
|
||||
}
|
||||
|
||||
// MarkSafe
|
||||
["django", "utils", "safestring" | "html", "mark_safe"] => {
|
||||
|
@ -1102,7 +1109,7 @@ fn suspicious_function(
|
|||
}
|
||||
}
|
||||
}
|
||||
Diagnostic::new(SuspiciousMarkSafeUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousMarkSafeUsage, range)
|
||||
}
|
||||
|
||||
// URLOpen (`Request`)
|
||||
|
@ -1124,7 +1131,7 @@ fn suspicious_function(
|
|||
}
|
||||
}
|
||||
}
|
||||
Diagnostic::new(SuspiciousURLOpenUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousURLOpenUsage, range)
|
||||
}
|
||||
|
||||
// URLOpen (`urlopen`, `urlretrieve`)
|
||||
|
@ -1176,7 +1183,7 @@ fn suspicious_function(
|
|||
}
|
||||
}
|
||||
}
|
||||
Diagnostic::new(SuspiciousURLOpenUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousURLOpenUsage, range)
|
||||
}
|
||||
|
||||
// URLOpen (`URLopener`, `FancyURLopener`)
|
||||
|
@ -1187,18 +1194,18 @@ fn suspicious_function(
|
|||
"urllib",
|
||||
"request",
|
||||
"URLopener" | "FancyURLopener",
|
||||
] => Diagnostic::new(SuspiciousURLOpenUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousURLOpenUsage, range),
|
||||
|
||||
// NonCryptographicRandom
|
||||
[
|
||||
"random",
|
||||
"Random" | "random" | "randrange" | "randint" | "choice" | "choices" | "uniform"
|
||||
| "triangular" | "randbytes",
|
||||
] => Diagnostic::new(SuspiciousNonCryptographicRandomUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousNonCryptographicRandomUsage, range),
|
||||
|
||||
// UnverifiedContext
|
||||
["ssl", "_create_unverified_context"] => {
|
||||
Diagnostic::new(SuspiciousUnverifiedContextUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousUnverifiedContextUsage, range)
|
||||
}
|
||||
|
||||
// XMLCElementTree
|
||||
|
@ -1207,7 +1214,7 @@ fn suspicious_function(
|
|||
"etree",
|
||||
"cElementTree",
|
||||
"parse" | "iterparse" | "fromstring" | "XMLParser",
|
||||
] => Diagnostic::new(SuspiciousXMLCElementTreeUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousXMLCElementTreeUsage, range),
|
||||
|
||||
// XMLElementTree
|
||||
[
|
||||
|
@ -1215,31 +1222,31 @@ fn suspicious_function(
|
|||
"etree",
|
||||
"ElementTree",
|
||||
"parse" | "iterparse" | "fromstring" | "XMLParser",
|
||||
] => Diagnostic::new(SuspiciousXMLElementTreeUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousXMLElementTreeUsage, range),
|
||||
|
||||
// XMLExpatReader
|
||||
["xml", "sax", "expatreader", "create_parser"] => {
|
||||
Diagnostic::new(SuspiciousXMLExpatReaderUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXMLExpatReaderUsage, range)
|
||||
}
|
||||
|
||||
// XMLExpatBuilder
|
||||
["xml", "dom", "expatbuilder", "parse" | "parseString"] => {
|
||||
Diagnostic::new(SuspiciousXMLExpatBuilderUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXMLExpatBuilderUsage, range)
|
||||
}
|
||||
|
||||
// XMLSax
|
||||
["xml", "sax", "parse" | "parseString" | "make_parser"] => {
|
||||
Diagnostic::new(SuspiciousXMLSaxUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXMLSaxUsage, range)
|
||||
}
|
||||
|
||||
// XMLMiniDOM
|
||||
["xml", "dom", "minidom", "parse" | "parseString"] => {
|
||||
Diagnostic::new(SuspiciousXMLMiniDOMUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXMLMiniDOMUsage, range)
|
||||
}
|
||||
|
||||
// XMLPullDOM
|
||||
["xml", "dom", "pulldom", "parse" | "parseString"] => {
|
||||
Diagnostic::new(SuspiciousXMLPullDOMUsage, range)
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXMLPullDOMUsage, range)
|
||||
}
|
||||
|
||||
// XMLETree
|
||||
|
@ -1248,20 +1255,16 @@ fn suspicious_function(
|
|||
"etree",
|
||||
"parse" | "fromstring" | "RestrictedElement" | "GlobalParserTLS" | "getDefaultParser"
|
||||
| "check_docinfo",
|
||||
] => Diagnostic::new(SuspiciousXMLETreeUsage, range),
|
||||
] => checker.report_diagnostic_if_enabled(SuspiciousXMLETreeUsage, range),
|
||||
|
||||
// Telnet
|
||||
["telnetlib", ..] => Diagnostic::new(SuspiciousTelnetUsage, range),
|
||||
["telnetlib", ..] => checker.report_diagnostic_if_enabled(SuspiciousTelnetUsage, range),
|
||||
|
||||
// FTPLib
|
||||
["ftplib", ..] => Diagnostic::new(SuspiciousFTPLibUsage, range),
|
||||
["ftplib", ..] => checker.report_diagnostic_if_enabled(SuspiciousFTPLibUsage, range),
|
||||
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if checker.enabled(diagnostic.rule()) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
/// S308
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
//! Check for imports of or from suspicious modules.
|
||||
//!
|
||||
//! See: <https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html>
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Stmt};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for imports of the `telnetlib` module.
|
||||
|
@ -362,42 +361,47 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
for name in names {
|
||||
match name.name.as_str() {
|
||||
"telnetlib" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousTelnetlibImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousTelnetlibImport, name.range);
|
||||
}
|
||||
"ftplib" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousFtplibImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousFtplibImport, name.range);
|
||||
}
|
||||
"pickle" | "cPickle" | "dill" | "shelve" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousPickleImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousPickleImport, name.range);
|
||||
}
|
||||
"subprocess" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousSubprocessImport, name.range);
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousSubprocessImport, name.range);
|
||||
}
|
||||
"xml.etree.cElementTree" | "xml.etree.ElementTree" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlEtreeImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXmlEtreeImport, name.range);
|
||||
}
|
||||
"xml.sax" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlSaxImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXmlSaxImport, name.range);
|
||||
}
|
||||
"xml.dom.expatbuilder" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlExpatImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXmlExpatImport, name.range);
|
||||
}
|
||||
"xml.dom.minidom" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlMinidomImport, name.range);
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousXmlMinidomImport, name.range);
|
||||
}
|
||||
"xml.dom.pulldom" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlPulldomImport, name.range);
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousXmlPulldomImport, name.range);
|
||||
}
|
||||
"lxml" => {
|
||||
checker.report_diagnostic_if_enabled(SuspiciousLxmlImport, name.range);
|
||||
}
|
||||
"lxml" => check_and_push_diagnostic(checker, SuspiciousLxmlImport, name.range),
|
||||
"xmlrpc" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlrpcImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousXmlrpcImport, name.range);
|
||||
}
|
||||
"Crypto.Cipher" | "Crypto.Hash" | "Crypto.IO" | "Crypto.Protocol"
|
||||
| "Crypto.PublicKey" | "Crypto.Random" | "Crypto.Signature" | "Crypto.Util" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousPycryptoImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousPycryptoImport, name.range);
|
||||
}
|
||||
"pyghmi" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousPyghmiImport, name.range);
|
||||
checker.report_diagnostic_if_enabled(SuspiciousPyghmiImport, name.range);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -406,27 +410,30 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
Stmt::ImportFrom(ast::StmtImportFrom { module, names, .. }) => {
|
||||
let Some(identifier) = module else { return };
|
||||
match identifier.as_str() {
|
||||
"telnetlib" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousTelnetlibImport,
|
||||
identifier.range(),
|
||||
),
|
||||
"telnetlib" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousTelnetlibImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
"ftplib" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousFtplibImport, identifier.range());
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousFtplibImport, identifier.range());
|
||||
}
|
||||
"pickle" | "cPickle" | "dill" | "shelve" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousPickleImport, identifier.range());
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousPickleImport, identifier.range());
|
||||
}
|
||||
"subprocess" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousSubprocessImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
"subprocess" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousSubprocessImport,
|
||||
identifier.range(),
|
||||
),
|
||||
"xml.etree" => {
|
||||
for name in names {
|
||||
if matches!(name.name.as_str(), "cElementTree" | "ElementTree") {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlEtreeImport,
|
||||
identifier.range(),
|
||||
);
|
||||
|
@ -434,17 +441,13 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
}
|
||||
}
|
||||
"xml.etree.cElementTree" | "xml.etree.ElementTree" => {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlEtreeImport,
|
||||
identifier.range(),
|
||||
);
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousXmlEtreeImport, identifier.range());
|
||||
}
|
||||
"xml" => {
|
||||
for name in names {
|
||||
if name.name.as_str() == "sax" {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlSaxImport,
|
||||
identifier.range(),
|
||||
);
|
||||
|
@ -452,58 +455,61 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
}
|
||||
}
|
||||
"xml.sax" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlSaxImport, identifier.range());
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousXmlSaxImport, identifier.range());
|
||||
}
|
||||
"xml.dom" => {
|
||||
for name in names {
|
||||
match name.name.as_str() {
|
||||
"expatbuilder" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlExpatImport,
|
||||
identifier.range(),
|
||||
),
|
||||
"minidom" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlMinidomImport,
|
||||
identifier.range(),
|
||||
),
|
||||
"pulldom" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlPulldomImport,
|
||||
identifier.range(),
|
||||
),
|
||||
_ => (),
|
||||
"expatbuilder" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlExpatImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
"minidom" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlMinidomImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
"pulldom" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlPulldomImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
"xml.dom.expatbuilder" => {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlExpatImport,
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousXmlExpatImport, identifier.range());
|
||||
}
|
||||
"xml.dom.minidom" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlMinidomImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
"xml.dom.pulldom" => {
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousXmlPulldomImport,
|
||||
identifier.range(),
|
||||
);
|
||||
}
|
||||
"xml.dom.minidom" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlMinidomImport,
|
||||
identifier.range(),
|
||||
),
|
||||
"xml.dom.pulldom" => check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousXmlPulldomImport,
|
||||
identifier.range(),
|
||||
),
|
||||
"lxml" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousLxmlImport, identifier.range());
|
||||
checker.report_diagnostic_if_enabled(SuspiciousLxmlImport, identifier.range());
|
||||
}
|
||||
"xmlrpc" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousXmlrpcImport, identifier.range());
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousXmlrpcImport, identifier.range());
|
||||
}
|
||||
"wsgiref.handlers" => {
|
||||
for name in names {
|
||||
if name.name.as_str() == "CGIHandler" {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousHttpoxyImport,
|
||||
identifier.range(),
|
||||
);
|
||||
|
@ -513,8 +519,7 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
"twisted.web.twcgi" => {
|
||||
for name in names {
|
||||
if name.name.as_str() == "CGIScript" {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousHttpoxyImport,
|
||||
identifier.range(),
|
||||
);
|
||||
|
@ -534,8 +539,7 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
| "Signature"
|
||||
| "Util"
|
||||
) {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
checker.report_diagnostic_if_enabled(
|
||||
SuspiciousPycryptoImport,
|
||||
identifier.range(),
|
||||
);
|
||||
|
@ -544,14 +548,12 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
}
|
||||
"Crypto.Cipher" | "Crypto.Hash" | "Crypto.IO" | "Crypto.Protocol"
|
||||
| "Crypto.PublicKey" | "Crypto.Random" | "Crypto.Signature" | "Crypto.Util" => {
|
||||
check_and_push_diagnostic(
|
||||
checker,
|
||||
SuspiciousPycryptoImport,
|
||||
identifier.range(),
|
||||
);
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousPycryptoImport, identifier.range());
|
||||
}
|
||||
"pyghmi" => {
|
||||
check_and_push_diagnostic(checker, SuspiciousPyghmiImport, identifier.range());
|
||||
checker
|
||||
.report_diagnostic_if_enabled(SuspiciousPyghmiImport, identifier.range());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -559,10 +561,3 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
_ => panic!("Expected Stmt::Import | Stmt::ImportFrom"),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_and_push_diagnostic<T: Violation>(checker: &Checker, diagnostic: T, range: TextRange) {
|
||||
let diagnostic = Diagnostic::new(diagnostic, range);
|
||||
if checker.enabled(diagnostic.rule()) {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::checkers::ast::Checker;
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast};
|
||||
|
@ -70,5 +69,5 @@ pub(crate) fn tarfile_unsafe_members(checker: &Checker, call: &ast::ExprCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(TarfileUnsafeMembers, call.func.range()));
|
||||
checker.report_diagnostic(TarfileUnsafeMembers, call.func.range());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{ExceptHandler, Expr, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -64,7 +64,7 @@ pub(crate) fn try_except_continue(
|
|||
) {
|
||||
if matches!(body, [Stmt::Continue(_)]) {
|
||||
if check_typed_exception || is_untyped_exception(type_, checker.semantic()) {
|
||||
checker.report_diagnostic(Diagnostic::new(TryExceptContinue, except_handler.range()));
|
||||
checker.report_diagnostic(TryExceptContinue, except_handler.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{ExceptHandler, Expr, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -60,7 +60,7 @@ pub(crate) fn try_except_pass(
|
|||
) {
|
||||
if matches!(body, [Stmt::Pass(_)]) {
|
||||
if check_typed_exception || is_untyped_exception(type_, checker.semantic()) {
|
||||
checker.report_diagnostic(Diagnostic::new(TryExceptPass, except_handler.range()));
|
||||
checker.report_diagnostic(TryExceptPass, except_handler.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{Expr, ExprCall};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
use ruff_python_semantic::{Modules, SemanticModel};
|
||||
|
@ -112,12 +112,12 @@ pub(crate) fn unsafe_markup_call(checker: &Checker, call: &ExprCall) {
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
UnsafeMarkupUse {
|
||||
name: qualified_name.to_string(),
|
||||
},
|
||||
call.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
fn is_markup_call(qualified_name: &QualifiedName, settings: &LinterSettings) -> bool {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -82,16 +82,10 @@ pub(crate) fn unsafe_yaml_load(checker: &Checker, call: &ast::ExprCall) {
|
|||
Expr::Name(ast::ExprName { id, .. }) => Some(id.to_string()),
|
||||
_ => None,
|
||||
};
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
UnsafeYAMLLoad { loader },
|
||||
loader_arg.range(),
|
||||
));
|
||||
checker.report_diagnostic(UnsafeYAMLLoad { loader }, loader_arg.range());
|
||||
}
|
||||
} else {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
UnsafeYAMLLoad { loader: None },
|
||||
call.func.range(),
|
||||
));
|
||||
checker.report_diagnostic(UnsafeYAMLLoad { loader: None }, call.func.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, ExprAttribute, ExprCall};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
@ -55,10 +55,7 @@ pub(crate) fn weak_cryptographic_key(checker: &Checker, call: &ExprCall) {
|
|||
};
|
||||
|
||||
if cryptographic_key.is_vulnerable() {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
WeakCryptographicKey { cryptographic_key },
|
||||
range,
|
||||
));
|
||||
checker.report_diagnostic(WeakCryptographicKey { cryptographic_key }, range);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::is_const_true;
|
||||
use ruff_python_ast::statement_visitor::{StatementVisitor, walk_stmt};
|
||||
|
@ -107,12 +107,12 @@ pub(crate) fn blind_except(
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
BlindExcept {
|
||||
name: builtin_exception_type.to_string(),
|
||||
},
|
||||
type_.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
/// A visitor to detect whether the exception with the given name was re-raised.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
use ruff_python_ast::name::UnqualifiedName;
|
||||
|
@ -131,10 +131,7 @@ pub(crate) fn boolean_default_value_positional_argument(
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
BooleanDefaultValuePositionalArgument,
|
||||
param.identifier(),
|
||||
));
|
||||
checker.report_diagnostic(BooleanDefaultValuePositionalArgument, param.identifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -61,6 +61,6 @@ pub(crate) fn boolean_positional_value_in_call(checker: &Checker, call: &ast::Ex
|
|||
.iter()
|
||||
.filter(|arg| arg.is_boolean_literal_expr())
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(BooleanPositionalValueInCall, arg.range()));
|
||||
checker.report_diagnostic(BooleanPositionalValueInCall, arg.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
|
@ -158,10 +157,7 @@ pub(crate) fn boolean_type_hint_positional_argument(
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
BooleanTypeHintPositionalArgument,
|
||||
parameter.identifier(),
|
||||
));
|
||||
checker.report_diagnostic(BooleanTypeHintPositionalArgument, parameter.identifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
|
@ -196,22 +196,22 @@ pub(crate) fn abstract_base_class(
|
|||
&& is_empty_body(body)
|
||||
&& !is_overload(decorator_list, checker.semantic())
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
EmptyMethodWithoutAbstractDecorator {
|
||||
name: format!("{name}.{method_name}"),
|
||||
},
|
||||
stmt.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
if checker.enabled(Rule::AbstractBaseClassWithoutAbstractMethod) {
|
||||
if !has_abstract_method {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
AbstractBaseClassWithoutAbstractMethod {
|
||||
name: name.to_string(),
|
||||
},
|
||||
stmt.identifier(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Stmt};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::is_const_false;
|
||||
|
||||
|
@ -79,10 +79,9 @@ pub(crate) fn assert_false(checker: &Checker, stmt: &Stmt, test: &Expr, msg: Opt
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(AssertFalse, test.range());
|
||||
let mut diagnostic = checker.report_diagnostic(AssertFalse, test.range());
|
||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
||||
checker.generator().stmt(&assertion_error(msg)),
|
||||
stmt.range(),
|
||||
)));
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr, WithItem};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -99,9 +99,6 @@ pub(crate) fn assert_raises_exception(checker: &Checker, items: &[WithItem]) {
|
|||
continue;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
AssertRaisesException { exception },
|
||||
item.range(),
|
||||
));
|
||||
checker.report_diagnostic(AssertRaisesException { exception }, item.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Expr};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -66,5 +66,5 @@ pub(crate) fn assignment_to_os_environ(checker: &Checker, targets: &[Expr]) {
|
|||
if id != "os" {
|
||||
return;
|
||||
}
|
||||
checker.report_diagnostic(Diagnostic::new(AssignmentToOsEnviron, target.range()));
|
||||
checker.report_diagnostic(AssignmentToOsEnviron, target.range());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_bugbear::rules::is_infinite_iterable;
|
||||
use ruff_diagnostics::{Diagnostic, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::ExprCall;
|
||||
use ruff_python_ast::PythonVersion;
|
||||
|
@ -86,6 +86,5 @@ pub(crate) fn batched_without_explicit_strict(checker: &Checker, call: &ExprCall
|
|||
return;
|
||||
}
|
||||
|
||||
let diagnostic = Diagnostic::new(BatchedWithoutExplicitStrict, call.range);
|
||||
checker.report_diagnostic(diagnostic);
|
||||
checker.report_diagnostic(BatchedWithoutExplicitStrict, call.range);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::map_callable;
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
|
@ -102,7 +102,7 @@ pub(crate) fn cached_instance_method(checker: &Checker, function_def: &ast::Stmt
|
|||
return;
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(CachedInstanceMethod, decorator.range()));
|
||||
checker.report_diagnostic(CachedInstanceMethod, decorator.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast};
|
||||
use ruff_python_semantic::analyze::visibility::{self, Visibility::Public};
|
||||
|
@ -105,7 +105,7 @@ pub(crate) fn class_as_data_structure(checker: &Checker, class_def: &ast::StmtCl
|
|||
}
|
||||
|
||||
if has_dunder_init && public_methods == 1 {
|
||||
checker.report_diagnostic(Diagnostic::new(ClassAsDataStructure, class_def.range()));
|
||||
checker.report_diagnostic(ClassAsDataStructure, class_def.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
|||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Violation};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||
use ruff_diagnostics::{Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::UnqualifiedName;
|
||||
use ruff_python_ast::{self as ast, ExceptHandler, Expr, ExprContext};
|
||||
|
@ -141,7 +141,7 @@ fn duplicate_handler_exceptions<'a>(
|
|||
if checker.enabled(Rule::DuplicateHandlerException) {
|
||||
// TODO(charlie): Handle "BaseException" and redundant exception aliases.
|
||||
if !duplicates.is_empty() {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
DuplicateHandlerException {
|
||||
names: duplicates
|
||||
.into_iter()
|
||||
|
@ -167,7 +167,6 @@ fn duplicate_handler_exceptions<'a>(
|
|||
},
|
||||
expr.range(),
|
||||
)));
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,13 +216,13 @@ pub(crate) fn duplicate_exceptions(checker: &Checker, handlers: &[ExceptHandler]
|
|||
.current_statement()
|
||||
.as_try_stmt()
|
||||
.is_some_and(|try_stmt| try_stmt.is_star);
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
DuplicateTryBlockException {
|
||||
name: name.segments().join("."),
|
||||
is_star,
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::{Context, Result};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::Expr;
|
||||
|
@ -60,7 +60,7 @@ pub(crate) fn duplicate_value(checker: &Checker, set: &ast::ExprSet) {
|
|||
for (index, value) in set.iter().enumerate() {
|
||||
if value.is_literal_expr() {
|
||||
if let Some(existing) = seen_values.insert(HashableExpr::from(value), value) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
DuplicateValue {
|
||||
value: checker.generator().expr(value),
|
||||
existing: checker.generator().expr(existing),
|
||||
|
@ -71,8 +71,6 @@ pub(crate) fn duplicate_value(checker: &Checker, set: &ast::ExprSet) {
|
|||
diagnostic.try_set_fix(|| {
|
||||
remove_member(set, index, checker.locator().contents()).map(Fix::safe_edit)
|
||||
});
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast::{self as ast};
|
||||
use ruff_python_ast::{ExceptHandler, Expr};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -66,9 +66,6 @@ pub(crate) fn except_with_empty_tuple(checker: &Checker, except_handler: &Except
|
|||
.current_statement()
|
||||
.as_try_stmt()
|
||||
.is_some_and(|try_stmt| try_stmt.is_star);
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
ExceptWithEmptyTuple { is_star },
|
||||
except_handler.range(),
|
||||
));
|
||||
checker.report_diagnostic(ExceptWithEmptyTuple { is_star }, except_handler.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::VecDeque;
|
|||
|
||||
use ruff_python_ast::{self as ast, ExceptHandler, Expr, Operator};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -69,10 +69,7 @@ pub(crate) fn except_with_non_exception_classes(checker: &Checker, except_handle
|
|||
.current_statement()
|
||||
.as_try_stmt()
|
||||
.is_some_and(|try_stmt| try_stmt.is_star);
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
ExceptWithNonExceptionClasses { is_star },
|
||||
expr.range(),
|
||||
));
|
||||
checker.report_diagnostic(ExceptWithNonExceptionClasses { is_star }, expr.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
|
||||
|
@ -51,5 +51,5 @@ pub(crate) fn f_string_docstring(checker: &Checker, body: &[Stmt]) {
|
|||
if !value.is_f_string_expr() {
|
||||
return;
|
||||
}
|
||||
checker.report_diagnostic(Diagnostic::new(FStringDocstring, stmt.identifier()));
|
||||
checker.report_diagnostic(FStringDocstring, stmt.identifier());
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Expr, Parameters};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::{QualifiedName, UnqualifiedName};
|
||||
|
@ -113,12 +112,12 @@ impl Visitor<'_> for ArgumentDefaultVisitor<'_, '_> {
|
|||
)
|
||||
})
|
||||
{
|
||||
self.checker.report_diagnostic(Diagnostic::new(
|
||||
self.checker.report_diagnostic(
|
||||
FunctionCallInDefaultArgument {
|
||||
name: UnqualifiedName::from_expr(func).map(|name| name.to_string()),
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
visitor::walk_expr(self, expr);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::types::Node;
|
||||
use ruff_python_ast::visitor;
|
||||
|
@ -305,12 +305,12 @@ pub(crate) fn function_uses_loop_variable(checker: &Checker, node: &Node) {
|
|||
for name in suspicious_variables {
|
||||
if reassigned_in_loop.contains(&name.id.as_str()) {
|
||||
if checker.insert_flake8_bugbear_range(name.range()) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
FunctionUsesLoopVariable {
|
||||
name: name.id.to_string(),
|
||||
},
|
||||
name.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_stdlib::identifiers::{is_identifier, is_mangled_private};
|
||||
|
@ -68,7 +68,7 @@ pub(crate) fn getattr_with_constant(checker: &Checker, expr: &Expr, func: &Expr,
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(GetAttrWithConstant, expr.range());
|
||||
let mut diagnostic = checker.report_diagnostic(GetAttrWithConstant, expr.range());
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
pad(
|
||||
if matches!(
|
||||
|
@ -88,5 +88,4 @@ pub(crate) fn getattr_with_constant(checker: &Checker, expr: &Expr, func: &Expr,
|
|||
),
|
||||
expr.range(),
|
||||
)));
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -56,7 +56,7 @@ impl Violation for JumpStatementInFinally {
|
|||
fn walk_stmt(checker: &Checker, body: &[Stmt], f: fn(&Stmt) -> bool) {
|
||||
for stmt in body {
|
||||
if f(stmt) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
JumpStatementInFinally {
|
||||
name: match stmt {
|
||||
Stmt::Break(_) => "break",
|
||||
|
@ -67,7 +67,7 @@ fn walk_stmt(checker: &Checker, body: &[Stmt], f: fn(&Stmt) -> bool) {
|
|||
.to_owned(),
|
||||
},
|
||||
stmt.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
match stmt {
|
||||
Stmt::While(ast::StmtWhile { body, .. }) | Stmt::For(ast::StmtFor { body, .. }) => {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::comparable::ComparableExpr;
|
||||
|
@ -110,7 +109,7 @@ pub(crate) fn loop_iterator_mutation(checker: &Checker, stmt_for: &StmtFor) {
|
|||
let name = UnqualifiedName::from_expr(iter)
|
||||
.map(|name| name.to_string())
|
||||
.map(SourceCodeSnippet::new);
|
||||
checker.report_diagnostic(Diagnostic::new(LoopIteratorMutation { name }, *mutation));
|
||||
checker.report_diagnostic(LoopIteratorMutation { name }, *mutation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast::{self as ast, Expr};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::visitor;
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
|
@ -64,12 +64,12 @@ pub(crate) fn loop_variable_overrides_iterator(checker: &Checker, target: &Expr,
|
|||
|
||||
for (name, expr) in target_names {
|
||||
if iter_names.contains_key(name) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
LoopVariableOverridesIterator {
|
||||
name: name.to_string(),
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::is_docstring_stmt;
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
|
@ -111,7 +111,7 @@ pub(crate) fn mutable_argument_default(checker: &Checker, function_def: &ast::St
|
|||
is_immutable_annotation(expr, checker.semantic(), extend_immutable_calls.as_slice())
|
||||
})
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(MutableArgumentDefault, default.range());
|
||||
let mut diagnostic = checker.report_diagnostic(MutableArgumentDefault, default.range());
|
||||
|
||||
// If the function body is on the same line as the function def, do not fix
|
||||
if let Some(fix) = move_initialization(
|
||||
|
@ -126,7 +126,6 @@ pub(crate) fn mutable_argument_default(checker: &Checker, function_def: &ast::St
|
|||
) {
|
||||
diagnostic.set_fix(fix);
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::map_subscript;
|
||||
use ruff_python_ast::name::QualifiedName;
|
||||
|
@ -102,6 +102,6 @@ pub(crate) fn mutable_contextvar_default(checker: &Checker, call: &ast::ExprCall
|
|||
matches!(qualified_name.segments(), ["contextvars", "ContextVar"])
|
||||
})
|
||||
{
|
||||
checker.report_diagnostic(Diagnostic::new(MutableContextvarDefault, default.range()));
|
||||
checker.report_diagnostic(MutableContextvarDefault, default.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -85,7 +85,7 @@ pub(crate) fn no_explicit_stacklevel(checker: &Checker, call: &ast::ExprCall) {
|
|||
{
|
||||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(NoExplicitStacklevel, call.func.range());
|
||||
let mut diagnostic = checker.report_diagnostic(NoExplicitStacklevel, call.func.range());
|
||||
|
||||
let edit = add_argument(
|
||||
"stacklevel=2",
|
||||
|
@ -95,8 +95,6 @@ pub(crate) fn no_explicit_stacklevel(checker: &Checker, call: &ast::ExprCall) {
|
|||
);
|
||||
|
||||
diagnostic.set_fix(Fix::unsafe_edit(edit));
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
/// Returns `true` if `skip_file_prefixes` is set to its non-default value.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::Expr;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -39,6 +39,6 @@ impl Violation for RaiseLiteral {
|
|||
/// B016
|
||||
pub(crate) fn raise_literal(checker: &Checker, expr: &Expr) {
|
||||
if expr.is_literal_expr() {
|
||||
checker.report_diagnostic(Diagnostic::new(RaiseLiteral, expr.range()));
|
||||
checker.report_diagnostic(RaiseLiteral, expr.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::Stmt;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::RaiseStatementVisitor;
|
||||
use ruff_python_ast::statement_visitor::StatementVisitor;
|
||||
|
@ -106,10 +106,7 @@ pub(crate) fn raise_without_from_inside_except(
|
|||
.as_try_stmt()
|
||||
.is_some_and(|try_stmt| try_stmt.is_star);
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
RaiseWithoutFromInsideExcept { is_star },
|
||||
range,
|
||||
));
|
||||
checker.report_diagnostic(RaiseWithoutFromInsideExcept { is_star }, range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt;
|
|||
|
||||
use ruff_python_ast::{self as ast};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_semantic::Modules;
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -75,10 +75,7 @@ pub(crate) fn re_sub_positional_args(checker: &Checker, call: &ast::ExprCall) {
|
|||
};
|
||||
|
||||
if call.arguments.args.len() > method.num_args() {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
ReSubPositionalArgs { method },
|
||||
call.range(),
|
||||
));
|
||||
checker.report_diagnostic(ReSubPositionalArgs { method }, call.range());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{self as ast, ExceptHandler, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -79,7 +79,7 @@ pub(crate) fn redundant_tuple_in_exception_handler(checker: &Checker, handlers:
|
|||
if elt.is_starred_expr() {
|
||||
continue;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
RedundantTupleInExceptionHandler {
|
||||
name: checker.generator().expr(elt),
|
||||
},
|
||||
|
@ -100,6 +100,5 @@ pub(crate) fn redundant_tuple_in_exception_handler(checker: &Checker, handlers:
|
|||
),
|
||||
type_.range(),
|
||||
)));
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::statement_visitor;
|
||||
|
@ -101,7 +100,7 @@ pub(crate) fn return_in_generator(checker: &Checker, function_def: &StmtFunction
|
|||
|
||||
if visitor.has_yield {
|
||||
if let Some(return_) = visitor.return_ {
|
||||
checker.report_diagnostic(Diagnostic::new(ReturnInGenerator, return_));
|
||||
checker.report_diagnostic(ReturnInGenerator, return_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Comprehension, Expr, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::visitor::{self, Visitor};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -339,6 +339,6 @@ pub(crate) fn reuse_of_groupby_generator(
|
|||
finder.visit_stmt(stmt);
|
||||
}
|
||||
for expr in finder.exprs {
|
||||
checker.report_diagnostic(Diagnostic::new(ReuseOfGroupbyGenerator, expr.range()));
|
||||
checker.report_diagnostic(ReuseOfGroupbyGenerator, expr.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_python_ast::{self as ast, Expr, ExprContext, Identifier, Stmt};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_codegen::Generator;
|
||||
use ruff_python_stdlib::identifiers::{is_identifier, is_mangled_private};
|
||||
|
@ -90,12 +90,11 @@ pub(crate) fn setattr_with_constant(checker: &Checker, expr: &Expr, func: &Expr,
|
|||
}) = checker.semantic().current_statement()
|
||||
{
|
||||
if expr == child.as_ref() {
|
||||
let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range());
|
||||
let mut diagnostic = checker.report_diagnostic(SetAttrWithConstant, expr.range());
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
assignment(obj, name.to_str(), value, checker.generator()),
|
||||
expr.range(),
|
||||
)));
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{Expr, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -71,9 +71,6 @@ pub(crate) fn star_arg_unpacking_after_keyword_arg(
|
|||
if arg.start() <= keyword.start() {
|
||||
continue;
|
||||
}
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
StarArgUnpackingAfterKeywordArg,
|
||||
arg.range(),
|
||||
));
|
||||
checker.report_diagnostic(StarArgUnpackingAfterKeywordArg, arg.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc_hash::FxHashMap;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::helpers::StoredNameFinder;
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
|
@ -58,12 +58,12 @@ pub(crate) fn static_key_dict_comprehension(checker: &Checker, dict_comp: &ast::
|
|||
};
|
||||
|
||||
if is_constant(&dict_comp.key, &names) {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
StaticKeyDictComprehension {
|
||||
key: SourceCodeSnippet::from_str(checker.locator().slice(dict_comp.key.as_ref())),
|
||||
},
|
||||
dict_comp.key.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use itertools::Itertools;
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -73,6 +73,6 @@ pub(crate) fn strip_with_multi_characters(
|
|||
};
|
||||
|
||||
if value.chars().count() > 1 && !value.chars().all_unique() {
|
||||
checker.report_diagnostic(Diagnostic::new(StripWithMultiCharacters, expr.range()));
|
||||
checker.report_diagnostic(StripWithMultiCharacters, expr.range());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_python_ast::{self as ast, Expr, UnaryOp};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -61,20 +61,20 @@ pub(crate) fn unary_prefix_increment_decrement(
|
|||
};
|
||||
match (op, nested_op) {
|
||||
(UnaryOp::UAdd, UnaryOp::UAdd) => {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
UnaryPrefixIncrementDecrement {
|
||||
operator: UnaryPrefixOperatorType::Increment,
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
(UnaryOp::USub, UnaryOp::USub) => {
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
checker.report_diagnostic(
|
||||
UnaryPrefixIncrementDecrement {
|
||||
operator: UnaryPrefixOperatorType::Decrement,
|
||||
},
|
||||
expr.range(),
|
||||
));
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue