Adjust line numbers when reporting rules in f-strings (#244)

This commit is contained in:
Charlie Marsh 2022-09-21 13:42:58 -04:00 committed by GitHub
parent 1e171ce0e8
commit 65d29d9734
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 151 additions and 87 deletions

View file

@ -82,3 +82,10 @@ class Ticket:
def update_tomato(): def update_tomato():
print(TOMATO) print(TOMATO)
TOMATO = "cherry tomato" TOMATO = "cherry tomato"
A = f'{B}'
A = (
f'B'
f'{B}'
)

View file

@ -7,7 +7,7 @@ use rustpython_parser::ast::{
}; };
use crate::ast::operations::SourceCodeLocator; use crate::ast::operations::SourceCodeLocator;
use crate::ast::types::{Binding, BindingKind, FunctionScope, Scope, ScopeKind}; use crate::ast::types::{Binding, BindingKind, CheckLocator, FunctionScope, Scope, ScopeKind};
use crate::autofix::{fixer, fixes}; use crate::autofix::{fixer, fixes};
use crate::checks::{Check, CheckKind, Fix, RejectedCmpop}; use crate::checks::{Check, CheckKind, Fix, RejectedCmpop};
@ -37,6 +37,7 @@ pub fn check_not_tests(
operand: &Expr, operand: &Expr,
check_not_in: bool, check_not_in: bool,
check_not_is: bool, check_not_is: bool,
locator: &dyn CheckLocator,
) -> Vec<Check> { ) -> Vec<Check> {
let mut checks: Vec<Check> = vec![]; let mut checks: Vec<Check> = vec![];
@ -46,12 +47,18 @@ pub fn check_not_tests(
match op { match op {
Cmpop::In => { Cmpop::In => {
if check_not_in { if check_not_in {
checks.push(Check::new(CheckKind::NotInTest, operand.location)); checks.push(Check::new(
CheckKind::NotInTest,
locator.locate_check(operand.location),
));
} }
} }
Cmpop::Is => { Cmpop::Is => {
if check_not_is { if check_not_is {
checks.push(Check::new(CheckKind::NotIsTest, operand.location)); checks.push(Check::new(
CheckKind::NotIsTest,
locator.locate_check(operand.location),
));
} }
} }
_ => {} _ => {}
@ -64,7 +71,7 @@ pub fn check_not_tests(
} }
/// Check UnusedVariable compliance. /// Check UnusedVariable compliance.
pub fn check_unused_variables(scope: &Scope) -> Vec<Check> { pub fn check_unused_variables(scope: &Scope, locator: &dyn CheckLocator) -> Vec<Check> {
let mut checks: Vec<Check> = vec![]; let mut checks: Vec<Check> = vec![];
if matches!( if matches!(
@ -85,7 +92,7 @@ pub fn check_unused_variables(scope: &Scope) -> Vec<Check> {
{ {
checks.push(Check::new( checks.push(Check::new(
CheckKind::UnusedVariable(name.to_string()), CheckKind::UnusedVariable(name.to_string()),
binding.location, locator.locate_check(binding.location),
)); ));
} }
} }
@ -299,6 +306,7 @@ pub fn check_repeated_keys(
keys: &Vec<Expr>, keys: &Vec<Expr>,
check_repeated_literals: bool, check_repeated_literals: bool,
check_repeated_variables: bool, check_repeated_variables: bool,
locator: &dyn CheckLocator,
) -> Vec<Check> { ) -> Vec<Check> {
let mut checks: Vec<Check> = vec![]; let mut checks: Vec<Check> = vec![];
@ -313,7 +321,7 @@ pub fn check_repeated_keys(
if check_repeated_literals && v1 == v2 { if check_repeated_literals && v1 == v2 {
checks.push(Check::new( checks.push(Check::new(
CheckKind::MultiValueRepeatedKeyLiteral, CheckKind::MultiValueRepeatedKeyLiteral,
k2.location, locator.locate_check(k2.location),
)) ))
} }
} }
@ -321,7 +329,7 @@ pub fn check_repeated_keys(
if check_repeated_variables && v1 == v2 { if check_repeated_variables && v1 == v2 {
checks.push(Check::new( checks.push(Check::new(
CheckKind::MultiValueRepeatedKeyVariable((*v2).to_string()), CheckKind::MultiValueRepeatedKeyVariable((*v2).to_string()),
k2.location, locator.locate_check(k2.location),
)) ))
} }
} }
@ -340,6 +348,7 @@ pub fn check_literal_comparisons(
comparators: &Vec<Expr>, comparators: &Vec<Expr>,
check_none_comparisons: bool, check_none_comparisons: bool,
check_true_false_comparisons: bool, check_true_false_comparisons: bool,
locator: &dyn CheckLocator,
) -> Vec<Check> { ) -> Vec<Check> {
let mut checks: Vec<Check> = vec![]; let mut checks: Vec<Check> = vec![];
@ -359,13 +368,13 @@ pub fn check_literal_comparisons(
if matches!(op, Cmpop::Eq) { if matches!(op, Cmpop::Eq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::NoneComparison(RejectedCmpop::Eq), CheckKind::NoneComparison(RejectedCmpop::Eq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
if matches!(op, Cmpop::NotEq) { if matches!(op, Cmpop::NotEq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::NoneComparison(RejectedCmpop::NotEq), CheckKind::NoneComparison(RejectedCmpop::NotEq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
} }
@ -379,13 +388,13 @@ pub fn check_literal_comparisons(
if matches!(op, Cmpop::Eq) { if matches!(op, Cmpop::Eq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::TrueFalseComparison(value, RejectedCmpop::Eq), CheckKind::TrueFalseComparison(value, RejectedCmpop::Eq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
if matches!(op, Cmpop::NotEq) { if matches!(op, Cmpop::NotEq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::TrueFalseComparison(value, RejectedCmpop::NotEq), CheckKind::TrueFalseComparison(value, RejectedCmpop::NotEq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
} }
@ -405,13 +414,13 @@ pub fn check_literal_comparisons(
if matches!(op, Cmpop::Eq) { if matches!(op, Cmpop::Eq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::NoneComparison(RejectedCmpop::Eq), CheckKind::NoneComparison(RejectedCmpop::Eq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
if matches!(op, Cmpop::NotEq) { if matches!(op, Cmpop::NotEq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::NoneComparison(RejectedCmpop::NotEq), CheckKind::NoneComparison(RejectedCmpop::NotEq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
} }
@ -425,13 +434,13 @@ pub fn check_literal_comparisons(
if matches!(op, Cmpop::Eq) { if matches!(op, Cmpop::Eq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::TrueFalseComparison(value, RejectedCmpop::Eq), CheckKind::TrueFalseComparison(value, RejectedCmpop::Eq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
if matches!(op, Cmpop::NotEq) { if matches!(op, Cmpop::NotEq) {
checks.push(Check::new( checks.push(Check::new(
CheckKind::TrueFalseComparison(value, RejectedCmpop::NotEq), CheckKind::TrueFalseComparison(value, RejectedCmpop::NotEq),
comparator.location, locator.locate_check(comparator.location),
)); ));
} }
} }
@ -528,9 +537,9 @@ pub fn check_type_comparison(
/// Check TwoStarredExpressions and TooManyExpressionsInStarredAssignment compliance. /// Check TwoStarredExpressions and TooManyExpressionsInStarredAssignment compliance.
pub fn check_starred_expressions( pub fn check_starred_expressions(
elts: &[Expr], elts: &[Expr],
location: Location,
check_too_many_expressions: bool, check_too_many_expressions: bool,
check_two_starred_expressions: bool, check_two_starred_expressions: bool,
location: Location,
) -> Option<Check> { ) -> Option<Check> {
let mut has_starred: bool = false; let mut has_starred: bool = false;
let mut starred_index: Option<usize> = None; let mut starred_index: Option<usize> = None;
@ -563,6 +572,7 @@ pub fn check_break_outside_loop(
stmt: &Stmt, stmt: &Stmt,
parents: &[&Stmt], parents: &[&Stmt],
parent_stack: &[usize], parent_stack: &[usize],
locator: &dyn CheckLocator,
) -> Option<Check> { ) -> Option<Check> {
let mut allowed: bool = false; let mut allowed: bool = false;
let mut parent = stmt; let mut parent = stmt;
@ -589,7 +599,10 @@ pub fn check_break_outside_loop(
} }
if !allowed { if !allowed {
Some(Check::new(CheckKind::BreakOutsideLoop, stmt.location)) Some(Check::new(
CheckKind::BreakOutsideLoop,
locator.locate_check(stmt.location),
))
} else { } else {
None None
} }
@ -600,6 +613,7 @@ pub fn check_continue_outside_loop(
stmt: &Stmt, stmt: &Stmt,
parents: &[&Stmt], parents: &[&Stmt],
parent_stack: &[usize], parent_stack: &[usize],
locator: &dyn CheckLocator,
) -> Option<Check> { ) -> Option<Check> {
let mut allowed: bool = false; let mut allowed: bool = false;
let mut parent = stmt; let mut parent = stmt;
@ -626,7 +640,10 @@ pub fn check_continue_outside_loop(
} }
if !allowed { if !allowed {
Some(Check::new(CheckKind::ContinueOutsideLoop, stmt.location)) Some(Check::new(
CheckKind::ContinueOutsideLoop,
locator.locate_check(stmt.location),
))
} else { } else {
None None
} }

View file

@ -65,3 +65,7 @@ pub struct Binding {
/// last used. /// last used.
pub used: Option<(usize, Location)>, pub used: Option<(usize, Location)>,
} }
pub trait CheckLocator {
fn locate_check(&self, default: Location) -> Location;
}

View file

@ -9,7 +9,7 @@ use rustpython_parser::parser;
use crate::ast::operations::{extract_all_names, SourceCodeLocator}; use crate::ast::operations::{extract_all_names, SourceCodeLocator};
use crate::ast::relocate::relocate_expr; use crate::ast::relocate::relocate_expr;
use crate::ast::types::{Binding, BindingKind, FunctionScope, Scope, ScopeKind}; use crate::ast::types::{Binding, BindingKind, CheckLocator, FunctionScope, Scope, ScopeKind};
use crate::ast::visitor::{walk_excepthandler, Visitor}; use crate::ast::visitor::{walk_excepthandler, Visitor};
use crate::ast::{checks, operations, visitor}; use crate::ast::{checks, operations, visitor};
use crate::autofix::fixer; use crate::autofix::fixer;
@ -42,7 +42,7 @@ struct Checker<'a> {
deferred_lambdas: Vec<(&'a Expr, Vec<usize>, Vec<usize>)>, deferred_lambdas: Vec<(&'a Expr, Vec<usize>, Vec<usize>)>,
deferred_assignments: Vec<usize>, deferred_assignments: Vec<usize>,
// Derivative state. // Derivative state.
in_f_string: bool, in_f_string: Option<Location>,
in_annotation: bool, in_annotation: bool,
in_literal: bool, in_literal: bool,
seen_non_import: bool, seen_non_import: bool,
@ -74,7 +74,7 @@ impl<'a> Checker<'a> {
deferred_functions: vec![], deferred_functions: vec![],
deferred_lambdas: vec![], deferred_lambdas: vec![],
deferred_assignments: vec![], deferred_assignments: vec![],
in_f_string: false, in_f_string: None,
in_annotation: false, in_annotation: false,
in_literal: false, in_literal: false,
seen_non_import: false, seen_non_import: false,
@ -171,7 +171,6 @@ where
// Pre-visit. // Pre-visit.
match &stmt.node { match &stmt.node {
StmtKind::Global { names } | StmtKind::Nonlocal { names } => { StmtKind::Global { names } | StmtKind::Nonlocal { names } => {
// TODO(charlie): Handle doctests.
let global_scope_id = self.scopes[GLOBAL_SCOPE_INDEX].id; let global_scope_id = self.scopes[GLOBAL_SCOPE_INDEX].id;
let current_scope = let current_scope =
@ -193,25 +192,34 @@ where
} }
if self.settings.select.contains(&CheckCode::E741) { if self.settings.select.contains(&CheckCode::E741) {
self.checks.extend(names.iter().filter_map(|name| { let location = self.locate_check(stmt.location);
checks::check_ambiguous_variable_name(name, stmt.location) self.checks.extend(
})); names.iter().filter_map(|name| {
checks::check_ambiguous_variable_name(name, location)
}),
);
} }
} }
StmtKind::Break => { StmtKind::Break => {
if self.settings.select.contains(&CheckCode::F701) { if self.settings.select.contains(&CheckCode::F701) {
if let Some(check) = if let Some(check) = checks::check_break_outside_loop(
checks::check_break_outside_loop(stmt, &self.parents, &self.parent_stack) stmt,
{ &self.parents,
&self.parent_stack,
self,
) {
self.checks.push(check); self.checks.push(check);
} }
} }
} }
StmtKind::Continue => { StmtKind::Continue => {
if self.settings.select.contains(&CheckCode::F702) { if self.settings.select.contains(&CheckCode::F702) {
if let Some(check) = if let Some(check) = checks::check_continue_outside_loop(
checks::check_continue_outside_loop(stmt, &self.parents, &self.parent_stack) stmt,
{ &self.parents,
&self.parent_stack,
self,
) {
self.checks.push(check); self.checks.push(check);
} }
} }
@ -231,8 +239,10 @@ where
.. ..
} => { } => {
if self.settings.select.contains(&CheckCode::E743) { if self.settings.select.contains(&CheckCode::E743) {
if let Some(check) = checks::check_ambiguous_function_name(name, stmt.location) if let Some(check) = checks::check_ambiguous_function_name(
{ name,
self.locate_check(stmt.location),
) {
self.checks.push(check); self.checks.push(check);
} }
} }
@ -293,7 +303,7 @@ where
ScopeKind::Class | ScopeKind::Module => { ScopeKind::Class | ScopeKind::Module => {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ReturnOutsideFunction, CheckKind::ReturnOutsideFunction,
stmt.location, self.locate_check(stmt.location),
)); ));
} }
_ => {} _ => {}
@ -325,7 +335,9 @@ where
} }
if self.settings.select.contains(&CheckCode::E742) { if self.settings.select.contains(&CheckCode::E742) {
if let Some(check) = checks::check_ambiguous_class_name(name, stmt.location) { if let Some(check) =
checks::check_ambiguous_class_name(name, self.locate_check(stmt.location))
{
self.checks.push(check); self.checks.push(check);
} }
} }
@ -351,7 +363,7 @@ where
{ {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ModuleImportNotAtTopOfFile, CheckKind::ModuleImportNotAtTopOfFile,
stmt.location, self.locate_check(stmt.location),
)); ));
} }
@ -405,7 +417,7 @@ where
{ {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ModuleImportNotAtTopOfFile, CheckKind::ModuleImportNotAtTopOfFile,
stmt.location, self.locate_check(stmt.location),
)); ));
} }
@ -441,14 +453,16 @@ where
{ {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::FutureFeatureNotDefined(alias.node.name.to_string()), CheckKind::FutureFeatureNotDefined(alias.node.name.to_string()),
stmt.location, self.locate_check(stmt.location),
)); ));
} }
if self.settings.select.contains(&CheckCode::F404) && !self.futures_allowed if self.settings.select.contains(&CheckCode::F404) && !self.futures_allowed
{ {
self.checks self.checks.push(Check::new(
.push(Check::new(CheckKind::LateFutureImport, stmt.location)); CheckKind::LateFutureImport,
self.locate_check(stmt.location),
));
} }
} else if alias.node.name == "*" { } else if alias.node.name == "*" {
let module_name = format!( let module_name = format!(
@ -472,7 +486,7 @@ where
if !matches!(scope.kind, ScopeKind::Module) { if !matches!(scope.kind, ScopeKind::Module) {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ImportStarNotPermitted(module_name.to_string()), CheckKind::ImportStarNotPermitted(module_name.to_string()),
stmt.location, self.locate_check(stmt.location),
)); ));
} }
} }
@ -480,7 +494,7 @@ where
if self.settings.select.contains(&CheckCode::F403) { if self.settings.select.contains(&CheckCode::F403) {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ImportStarUsed(module_name.to_string()), CheckKind::ImportStarUsed(module_name.to_string()),
stmt.location, self.locate_check(stmt.location),
)); ));
} }
@ -516,14 +530,18 @@ where
} }
StmtKind::If { test, .. } => { StmtKind::If { test, .. } => {
if self.settings.select.contains(&CheckCode::F634) { if self.settings.select.contains(&CheckCode::F634) {
if let Some(check) = checks::check_if_tuple(test, stmt.location) { if let Some(check) =
checks::check_if_tuple(test, self.locate_check(stmt.location))
{
self.checks.push(check); self.checks.push(check);
} }
} }
} }
StmtKind::Assert { test, .. } => { StmtKind::Assert { test, .. } => {
if self.settings.select.contains(CheckKind::AssertTuple.code()) { if self.settings.select.contains(CheckKind::AssertTuple.code()) {
if let Some(check) = checks::check_assert_tuple(test, stmt.location) { if let Some(check) =
checks::check_assert_tuple(test, self.locate_check(stmt.location))
{
self.checks.push(check); self.checks.push(check);
} }
} }
@ -537,7 +555,9 @@ where
} }
StmtKind::Assign { value, .. } => { StmtKind::Assign { value, .. } => {
if self.settings.select.contains(&CheckCode::E731) { if self.settings.select.contains(&CheckCode::E731) {
if let Some(check) = checks::check_do_not_assign_lambda(value, stmt.location) { if let Some(check) =
checks::check_do_not_assign_lambda(value, self.locate_check(stmt.location))
{
self.checks.push(check); self.checks.push(check);
} }
} }
@ -545,9 +565,10 @@ where
StmtKind::AnnAssign { value, .. } => { StmtKind::AnnAssign { value, .. } => {
if self.settings.select.contains(&CheckCode::E731) { if self.settings.select.contains(&CheckCode::E731) {
if let Some(value) = value { if let Some(value) = value {
if let Some(check) = if let Some(check) = checks::check_do_not_assign_lambda(
checks::check_do_not_assign_lambda(value, stmt.location) value,
{ self.locate_check(stmt.location),
) {
self.checks.push(check); self.checks.push(check);
} }
} }
@ -628,9 +649,9 @@ where
self.settings.select.contains(&CheckCode::F622); self.settings.select.contains(&CheckCode::F622);
if let Some(check) = checks::check_starred_expressions( if let Some(check) = checks::check_starred_expressions(
elts, elts,
expr.location,
check_too_many_expressions, check_too_many_expressions,
check_two_starred_expressions, check_two_starred_expressions,
self.locate_check(expr.location),
) { ) {
self.checks.push(check); self.checks.push(check);
} }
@ -640,9 +661,10 @@ where
ExprContext::Load => self.handle_node_load(expr), ExprContext::Load => self.handle_node_load(expr),
ExprContext::Store => { ExprContext::Store => {
if self.settings.select.contains(&CheckCode::E741) { if self.settings.select.contains(&CheckCode::E741) {
if let Some(check) = if let Some(check) = checks::check_ambiguous_variable_name(
checks::check_ambiguous_variable_name(id, expr.location) id,
{ self.locate_check(expr.location),
) {
self.checks.push(check); self.checks.push(check);
} }
} }
@ -673,18 +695,6 @@ where
} }
} }
} }
//
// if id == "locals" {
// let scope = &self.scopes
// [*(self.scope_stack.last().expect("No current scope found."))];
// if matches!(scope.kind, ScopeKind::Function(_)) {
// let parent =
// self.parents[*(self.parent_stack.last().expect("No parent found."))];
// if matches!(parent.node, StmtKind::Call)
// }
//
// }
} }
ExprKind::Dict { keys, .. } => { ExprKind::Dict { keys, .. } => {
let check_repeated_literals = self.settings.select.contains(&CheckCode::F601); let check_repeated_literals = self.settings.select.contains(&CheckCode::F601);
@ -694,6 +704,7 @@ where
keys, keys,
check_repeated_literals, check_repeated_literals,
check_repeated_variables, check_repeated_variables,
self,
)); ));
} }
} }
@ -706,12 +717,14 @@ where
.contains(CheckKind::YieldOutsideFunction.code()) .contains(CheckKind::YieldOutsideFunction.code())
&& matches!(scope.kind, ScopeKind::Class | ScopeKind::Module) && matches!(scope.kind, ScopeKind::Class | ScopeKind::Module)
{ {
self.checks self.checks.push(Check::new(
.push(Check::new(CheckKind::YieldOutsideFunction, expr.location)); CheckKind::YieldOutsideFunction,
self.locate_check(expr.location),
));
} }
} }
ExprKind::JoinedStr { values } => { ExprKind::JoinedStr { values } => {
if !self.in_f_string if self.in_f_string.is_none()
&& self && self
.settings .settings
.select .select
@ -722,10 +735,10 @@ where
{ {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::FStringMissingPlaceholders, CheckKind::FStringMissingPlaceholders,
expr.location, self.locate_check(expr.location),
)); ));
} }
self.in_f_string = true; self.in_f_string = Some(expr.location);
} }
ExprKind::BinOp { ExprKind::BinOp {
left, left,
@ -758,6 +771,7 @@ where
operand, operand,
check_not_in, check_not_in,
check_not_is, check_not_is,
self,
)); ));
} }
} }
@ -775,6 +789,7 @@ where
comparators, comparators,
check_none_comparisons, check_none_comparisons,
check_true_false_comparisons, check_true_false_comparisons,
self,
)); ));
} }
@ -783,7 +798,7 @@ where
left, left,
ops, ops,
comparators, comparators,
expr.location, self.locate_check(expr.location),
)); ));
} }
@ -791,7 +806,7 @@ where
self.checks.extend(checks::check_type_comparison( self.checks.extend(checks::check_type_comparison(
ops, ops,
comparators, comparators,
expr.location, self.locate_check(expr.location),
)); ));
} }
} }
@ -956,9 +971,10 @@ where
match name { match name {
Some(name) => { Some(name) => {
if self.settings.select.contains(&CheckCode::E741) { if self.settings.select.contains(&CheckCode::E741) {
if let Some(check) = if let Some(check) = checks::check_ambiguous_variable_name(
checks::check_ambiguous_variable_name(name, excepthandler.location) name,
{ self.locate_check(excepthandler.location),
) {
self.checks.push(check); self.checks.push(check);
} }
} }
@ -1058,14 +1074,22 @@ where
); );
if self.settings.select.contains(&CheckCode::E741) { if self.settings.select.contains(&CheckCode::E741) {
if let Some(check) = checks::check_ambiguous_variable_name(&arg.node.arg, arg.location) if let Some(check) = checks::check_ambiguous_variable_name(
{ &arg.node.arg,
self.locate_check(arg.location),
) {
self.checks.push(check); self.checks.push(check);
} }
} }
} }
} }
impl CheckLocator for Checker<'_> {
fn locate_check(&self, default: Location) -> Location {
self.in_f_string.unwrap_or(default)
}
}
impl<'a> Checker<'a> { impl<'a> Checker<'a> {
fn push_parent(&mut self, parent: &'a Stmt) { fn push_parent(&mut self, parent: &'a Stmt) {
self.parent_stack.push(self.parents.len()); self.parent_stack.push(self.parents.len());
@ -1185,7 +1209,7 @@ impl<'a> Checker<'a> {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ImportStarUsage(id.clone(), from_list.join(", ")), CheckKind::ImportStarUsage(id.clone(), from_list.join(", ")),
expr.location, self.locate_check(expr.location),
)); ));
} }
return; return;
@ -1198,7 +1222,7 @@ impl<'a> Checker<'a> {
} }
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::UndefinedName(id.clone()), CheckKind::UndefinedName(id.clone()),
expr.location, self.locate_check(expr.location),
)) ))
} }
} }
@ -1220,7 +1244,7 @@ impl<'a> Checker<'a> {
if scope_id == current.id { if scope_id == current.id {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::UndefinedLocal(id.clone()), CheckKind::UndefinedLocal(id.clone()),
location, self.locate_check(location),
)); ));
} }
} }
@ -1313,7 +1337,7 @@ impl<'a> Checker<'a> {
{ {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::UndefinedName(id.clone()), CheckKind::UndefinedName(id.clone()),
expr.location, self.locate_check(expr.location),
)) ))
} }
} }
@ -1338,7 +1362,7 @@ impl<'a> Checker<'a> {
} else if self.settings.select.contains(&CheckCode::F722) { } else if self.settings.select.contains(&CheckCode::F722) {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ForwardAnnotationSyntaxError(expression.to_string()), CheckKind::ForwardAnnotationSyntaxError(expression.to_string()),
location, self.locate_check(location),
)); ));
} }
} }
@ -1390,10 +1414,10 @@ impl<'a> Checker<'a> {
} }
fn check_deferred_assignments(&mut self) { fn check_deferred_assignments(&mut self) {
while let Some(index) = self.deferred_assignments.pop() { if self.settings.select.contains(&CheckCode::F841) {
if self.settings.select.contains(&CheckCode::F841) { while let Some(index) = self.deferred_assignments.pop() {
self.checks self.checks
.extend(checks::check_unused_variables(&self.scopes[index])); .extend(checks::check_unused_variables(&self.scopes[index], self));
} }
} }
} }
@ -1425,7 +1449,7 @@ impl<'a> Checker<'a> {
if !scope.values.contains_key(name) { if !scope.values.contains_key(name) {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::UndefinedExport(name.to_string()), CheckKind::UndefinedExport(name.to_string()),
all_binding.location, self.locate_check(all_binding.location),
)); ));
} }
} }
@ -1448,7 +1472,7 @@ impl<'a> Checker<'a> {
if !scope.values.contains_key(name) { if !scope.values.contains_key(name) {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::ImportStarUsage(name.clone(), from_list.join(", ")), CheckKind::ImportStarUsage(name.clone(), from_list.join(", ")),
all_binding.location, self.locate_check(all_binding.location),
)); ));
} }
} }
@ -1469,7 +1493,7 @@ impl<'a> Checker<'a> {
| BindingKind::SubmoduleImportation(full_name) => { | BindingKind::SubmoduleImportation(full_name) => {
self.checks.push(Check::new( self.checks.push(Check::new(
CheckKind::UnusedImport(full_name.to_string()), CheckKind::UnusedImport(full_name.to_string()),
binding.location, self.locate_check(binding.location),
)); ));
} }
_ => {} _ => {}

View file

@ -38,4 +38,16 @@ expression: checks
row: 83 row: 83
column: 11 column: 11
fix: ~ fix: ~
- kind:
UndefinedName: B
location:
row: 87
column: 7
fix: ~
- kind:
UndefinedName: B
location:
row: 89
column: 7
fix: ~