From bd06cbe0c5f8d03ea9fe52b96482bcf0c6ae279d Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 13 Oct 2023 15:44:16 -0400 Subject: [PATCH] Respect subscripted base classes in type-checking rules (#7954) Closes https://github.com/astral-sh/ruff/issues/7945. --- .../runtime_evaluated_base_classes_3.py | 7 +++++++ .../src/rules/flake8_type_checking/helpers.rs | 14 ++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py index 1bd948a83f655..98527b019dee0 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py @@ -22,3 +22,10 @@ class C: class D(C): x: UUID + + +import collections + + +class E(BaseModel[int]): + x: collections.Awaitable diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs index 31b5c6d2c3c86..b2f0e456e3804 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs @@ -1,5 +1,5 @@ use ruff_python_ast::call_path::from_qualified_name; -use ruff_python_ast::helpers::map_callable; +use ruff_python_ast::helpers::{map_callable, map_subscript}; use ruff_python_semantic::{Binding, BindingKind, ScopeKind, SemanticModel}; pub(crate) fn is_valid_runtime_import(binding: &Binding, semantic: &SemanticModel) -> bool { @@ -40,11 +40,13 @@ fn runtime_evaluated_base_class(base_classes: &[String], semantic: &SemanticMode }; class_def.bases().iter().any(|base| { - semantic.resolve_call_path(base).is_some_and(|call_path| { - base_classes - .iter() - .any(|base_class| from_qualified_name(base_class) == call_path) - }) + semantic + .resolve_call_path(map_subscript(base)) + .is_some_and(|call_path| { + base_classes + .iter() + .any(|base_class| from_qualified_name(base_class) == call_path) + }) }) }