[flake8-type-checking] Apply TC008 more eagerly in TYPE_CHECKING blocks and disapply it in stubs (#15180)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
David Salvisberg 2025-01-08 13:09:06 +01:00 committed by GitHub
parent 235fdfc57a
commit 339167d372
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 387 additions and 20 deletions

View file

@ -710,8 +710,17 @@ impl<'a> SemanticModel<'a> {
///
/// References from within an [`ast::Comprehension`] can produce incorrect
/// results when referring to a [`BindingKind::NamedExprAssignment`].
pub fn simulate_runtime_load(&self, name: &ast::ExprName) -> Option<BindingId> {
self.simulate_runtime_load_at_location_in_scope(name.id.as_str(), name.range, self.scope_id)
pub fn simulate_runtime_load(
&self,
name: &ast::ExprName,
typing_only_bindings_status: TypingOnlyBindingsStatus,
) -> Option<BindingId> {
self.simulate_runtime_load_at_location_in_scope(
name.id.as_str(),
name.range,
self.scope_id,
typing_only_bindings_status,
)
}
/// Simulates a runtime load of the given symbol.
@ -743,6 +752,7 @@ impl<'a> SemanticModel<'a> {
symbol: &str,
symbol_range: TextRange,
scope_id: ScopeId,
typing_only_bindings_status: TypingOnlyBindingsStatus,
) -> Option<BindingId> {
let mut seen_function = false;
let mut class_variables_visible = true;
@ -785,7 +795,9 @@ impl<'a> SemanticModel<'a> {
// runtime binding with a source-order inaccurate one
for shadowed_id in scope.shadowed_bindings(binding_id) {
let binding = &self.bindings[shadowed_id];
if binding.context.is_typing() {
if typing_only_bindings_status.is_disallowed()
&& binding.context.is_typing()
{
continue;
}
if let BindingKind::Annotation
@ -820,7 +832,9 @@ impl<'a> SemanticModel<'a> {
_ => binding_id,
};
if self.bindings[candidate_id].context.is_typing() {
if typing_only_bindings_status.is_disallowed()
&& self.bindings[candidate_id].context.is_typing()
{
continue;
}
@ -2058,6 +2072,32 @@ impl ShadowedBinding {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TypingOnlyBindingsStatus {
Allowed,
Disallowed,
}
impl TypingOnlyBindingsStatus {
pub const fn is_allowed(self) -> bool {
matches!(self, TypingOnlyBindingsStatus::Allowed)
}
pub const fn is_disallowed(self) -> bool {
matches!(self, TypingOnlyBindingsStatus::Disallowed)
}
}
impl From<bool> for TypingOnlyBindingsStatus {
fn from(value: bool) -> Self {
if value {
TypingOnlyBindingsStatus::Allowed
} else {
TypingOnlyBindingsStatus::Disallowed
}
}
}
bitflags! {
/// A select list of Python modules that the semantic model can explicitly track.
#[derive(Debug)]