diff --git a/src/check_ast.rs b/src/check_ast.rs index f1a43b2e2d086..d3ace5bd27121 100644 --- a/src/check_ast.rs +++ b/src/check_ast.rs @@ -2115,15 +2115,27 @@ impl<'a> Checker<'a> { None }; - let mut check = Check::new( - CheckKind::UnusedImport(full_names.into_iter().map(String::from).collect()), - self.locate_check(Range::from_located(child)), - ); - if let Some(fix) = fix { - check.amend(fix); + if self.path.ends_with("__init__.py") { + self.checks.push(Check::new( + CheckKind::UnusedImport( + full_names.into_iter().map(String::from).collect(), + true, + ), + self.locate_check(Range::from_located(child)), + )); + } else { + let mut check = Check::new( + CheckKind::UnusedImport( + full_names.into_iter().map(String::from).collect(), + false, + ), + self.locate_check(Range::from_located(child)), + ); + if let Some(fix) = fix { + check.amend(fix); + } + self.checks.push(check); } - - self.checks.push(check); } } } diff --git a/src/checks.rs b/src/checks.rs index 41bdd4a085c26..838c682074238 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -265,7 +265,7 @@ pub enum CheckKind { UndefinedExport(String), UndefinedLocal(String), UndefinedName(String), - UnusedImport(Vec), + UnusedImport(Vec, bool), UnusedVariable(String), YieldOutsideFunction, // flake8-builtins @@ -402,7 +402,7 @@ impl CheckCode { CheckCode::W292 => CheckKind::NoNewLineAtEndOfFile, CheckCode::W605 => CheckKind::InvalidEscapeSequence('c'), // pyflakes - CheckCode::F401 => CheckKind::UnusedImport(vec!["...".to_string()]), + CheckCode::F401 => CheckKind::UnusedImport(vec!["...".to_string()], false), CheckCode::F402 => CheckKind::ImportShadowedByLoopVar("...".to_string(), 1), CheckCode::F403 => CheckKind::ImportStarUsed("...".to_string()), CheckCode::F404 => CheckKind::LateFutureImport, @@ -751,7 +751,7 @@ impl CheckKind { CheckKind::UndefinedExport(_) => &CheckCode::F822, CheckKind::UndefinedLocal(_) => &CheckCode::F823, CheckKind::UndefinedName(_) => &CheckCode::F821, - CheckKind::UnusedImport(_) => &CheckCode::F401, + CheckKind::UnusedImport(_, _) => &CheckCode::F401, CheckKind::UnusedVariable(_) => &CheckCode::F841, CheckKind::YieldOutsideFunction => &CheckCode::F704, // pycodestyle warnings @@ -980,9 +980,13 @@ impl CheckKind { CheckKind::UndefinedName(name) => { format!("Undefined name `{name}`") } - CheckKind::UnusedImport(names) => { + CheckKind::UnusedImport(names, in_init_py) => { let names = names.iter().map(|name| format!("`{name}`")).join(", "); - format!("{names} imported but unused") + if *in_init_py { + format!("{names} imported but unused and missing from `__all__`") + } else { + format!("{names} imported but unused") + } } CheckKind::UnusedVariable(name) => { format!("Local variable `{name}` is assigned to but never used") @@ -1338,7 +1342,7 @@ impl CheckKind { | CheckKind::SuperCallWithParameters | CheckKind::TypeOfPrimitive(_) | CheckKind::UnnecessaryAbspath - | CheckKind::UnusedImport(_) + | CheckKind::UnusedImport(_, false) | CheckKind::UnusedLoopControlVariable(_) | CheckKind::UnusedNOQA(_) | CheckKind::UsePEP585Annotation(_) diff --git a/src/snapshots/ruff__linter__tests__F401_F401_0.py.snap b/src/snapshots/ruff__linter__tests__F401_F401_0.py.snap index 6de4b710433b3..ebb868f184c09 100644 --- a/src/snapshots/ruff__linter__tests__F401_F401_0.py.snap +++ b/src/snapshots/ruff__linter__tests__F401_F401_0.py.snap @@ -4,7 +4,8 @@ expression: checks --- - kind: UnusedImport: - - functools + - - functools + - false location: row: 2 column: 1 @@ -23,7 +24,8 @@ expression: checks applied: false - kind: UnusedImport: - - collections.OrderedDict + - - collections.OrderedDict + - false location: row: 4 column: 1 @@ -42,7 +44,8 @@ expression: checks applied: false - kind: UnusedImport: - - logging.handlers + - - logging.handlers + - false location: row: 12 column: 1 @@ -61,7 +64,8 @@ expression: checks applied: false - kind: UnusedImport: - - shelve + - - shelve + - false location: row: 33 column: 5 @@ -80,7 +84,8 @@ expression: checks applied: false - kind: UnusedImport: - - importlib + - - importlib + - false location: row: 34 column: 5 @@ -99,7 +104,8 @@ expression: checks applied: false - kind: UnusedImport: - - pathlib + - - pathlib + - false location: row: 38 column: 5 @@ -118,7 +124,8 @@ expression: checks applied: false - kind: UnusedImport: - - pickle + - - pickle + - false location: row: 53 column: 9 diff --git a/src/snapshots/ruff__linter__tests__F401_F401_5.py.snap b/src/snapshots/ruff__linter__tests__F401_F401_5.py.snap index f4b486eed6fe6..a63e16abb578d 100644 --- a/src/snapshots/ruff__linter__tests__F401_F401_5.py.snap +++ b/src/snapshots/ruff__linter__tests__F401_F401_5.py.snap @@ -4,7 +4,8 @@ expression: checks --- - kind: UnusedImport: - - a.b.c + - - a.b.c + - false location: row: 2 column: 1 @@ -23,7 +24,8 @@ expression: checks applied: false - kind: UnusedImport: - - d.e.f + - - d.e.f + - false location: row: 3 column: 1 @@ -42,7 +44,8 @@ expression: checks applied: false - kind: UnusedImport: - - h.i + - - h.i + - false location: row: 4 column: 1 @@ -61,7 +64,8 @@ expression: checks applied: false - kind: UnusedImport: - - j.k + - - j.k + - false location: row: 5 column: 1 diff --git a/src/snapshots/ruff__linter__tests__future_annotations.snap b/src/snapshots/ruff__linter__tests__future_annotations.snap index a22583a54d56a..5a328515ef082 100644 --- a/src/snapshots/ruff__linter__tests__future_annotations.snap +++ b/src/snapshots/ruff__linter__tests__future_annotations.snap @@ -4,7 +4,8 @@ expression: checks --- - kind: UnusedImport: - - models.Nut + - - models.Nut + - false location: row: 5 column: 1