diff --git a/crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi b/crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi new file mode 100644 index 0000000000000..6ceec8c51edf5 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi @@ -0,0 +1,3 @@ +from typing import Tuple + +x: Tuple diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index f9a939afd537d..046eb5c80ccef 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -4709,30 +4709,33 @@ impl<'a> Checker<'a> { } fn check_dead_scopes(&mut self) { + let enforce_typing_imports = !self.is_interface_definition + && (self + .settings + .rules + .enabled(&Rule::GlobalVariableNotAssigned) + || self + .settings + .rules + .enabled(&Rule::RuntimeImportInTypeCheckingBlock) + || self + .settings + .rules + .enabled(&Rule::TypingOnlyFirstPartyImport) + || self + .settings + .rules + .enabled(&Rule::TypingOnlyThirdPartyImport) + || self + .settings + .rules + .enabled(&Rule::TypingOnlyStandardLibraryImport)); + if !(self.settings.rules.enabled(&Rule::UnusedImport) || self.settings.rules.enabled(&Rule::ImportStarUsage) || self.settings.rules.enabled(&Rule::RedefinedWhileUnused) || self.settings.rules.enabled(&Rule::UndefinedExport) - || self - .settings - .rules - .enabled(&Rule::GlobalVariableNotAssigned) - || self - .settings - .rules - .enabled(&Rule::RuntimeImportInTypeCheckingBlock) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyFirstPartyImport) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyThirdPartyImport) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyStandardLibraryImport)) + || enforce_typing_imports) { return; } @@ -4781,26 +4784,10 @@ impl<'a> Checker<'a> { // Identify any valid runtime imports. If a module is imported at runtime, and // used at runtime, then by default, we avoid flagging any other // imports from that model as typing-only. - let runtime_imports: Vec> = if self.settings.flake8_type_checking.strict { - vec![] - } else { - if self - .settings - .rules - .enabled(&Rule::RuntimeImportInTypeCheckingBlock) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyFirstPartyImport) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyThirdPartyImport) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyStandardLibraryImport) - { + let runtime_imports: Vec> = if enforce_typing_imports { + if self.settings.flake8_type_checking.strict { + vec![] + } else { self.ctx .scopes .iter() @@ -4815,9 +4802,9 @@ impl<'a> Checker<'a> { .collect::>() }) .collect::>() - } else { - vec![] } + } else { + vec![] }; let mut diagnostics: Vec = vec![]; @@ -4939,23 +4926,7 @@ impl<'a> Checker<'a> { } } - if self - .settings - .rules - .enabled(&Rule::RuntimeImportInTypeCheckingBlock) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyFirstPartyImport) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyThirdPartyImport) - || self - .settings - .rules - .enabled(&Rule::TypingOnlyStandardLibraryImport) - { + if enforce_typing_imports { let runtime_imports: Vec<&Binding> = if self.settings.flake8_type_checking.strict { vec![] } else { diff --git a/crates/ruff/src/rules/flake8_type_checking/mod.rs b/crates/ruff/src/rules/flake8_type_checking/mod.rs index d53a6ab9fb86a..ff59575f234d4 100644 --- a/crates/ruff/src/rules/flake8_type_checking/mod.rs +++ b/crates/ruff/src/rules/flake8_type_checking/mod.rs @@ -32,6 +32,7 @@ mod tests { #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_11.py"); "TCH004_11")] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_12.py"); "TCH004_12")] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_13.py"); "TCH004_13")] + #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_14.pyi"); "TCH004_14")] #[test_case(Rule::EmptyTypeCheckingBlock, Path::new("TCH005.py"); "TCH005")] #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("strict.py"); "strict")] fn rules(rule_code: Rule, path: &Path) -> Result<()> { diff --git a/crates/ruff/src/rules/flake8_type_checking/snapshots/ruff__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_14.pyi.snap b/crates/ruff/src/rules/flake8_type_checking/snapshots/ruff__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_14.pyi.snap new file mode 100644 index 0000000000000..b308635bbdd2e --- /dev/null +++ b/crates/ruff/src/rules/flake8_type_checking/snapshots/ruff__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_14.pyi.snap @@ -0,0 +1,6 @@ +--- +source: crates/ruff/src/rules/flake8_type_checking/mod.rs +expression: diagnostics +--- +[] +