[ty] Fix broken property tests for disjointness (#18384)

This commit is contained in:
Alex Waygood 2025-05-30 16:49:20 +01:00 committed by GitHub
parent e730f27f80
commit 77c8ddf101
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 11 deletions

View file

@ -454,15 +454,23 @@ static_assert(is_disjoint_from(bool, Callable[..., Any]))
static_assert(is_disjoint_from(C, Callable[..., Any]))
static_assert(is_disjoint_from(bool | C, Callable[..., Any]))
static_assert(is_disjoint_from(Callable[..., Any], bool))
static_assert(is_disjoint_from(Callable[..., Any], C))
static_assert(is_disjoint_from(Callable[..., Any], bool | C))
static_assert(not is_disjoint_from(str, Callable[..., Any]))
static_assert(not is_disjoint_from(bool | str, Callable[..., Any]))
static_assert(not is_disjoint_from(Callable[..., Any], str))
static_assert(not is_disjoint_from(Callable[..., Any], bool | str))
def bound_with_valid_type():
@final
class D:
def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
static_assert(not is_disjoint_from(D, Callable[..., Any]))
static_assert(not is_disjoint_from(Callable[..., Any], D))
def possibly_unbound_with_valid_type(flag: bool):
@final
@ -471,6 +479,7 @@ def possibly_unbound_with_valid_type(flag: bool):
def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
static_assert(not is_disjoint_from(E, Callable[..., Any]))
static_assert(not is_disjoint_from(Callable[..., Any], E))
def bound_with_invalid_type():
@final
@ -478,6 +487,7 @@ def bound_with_invalid_type():
__call__: int = 1
static_assert(is_disjoint_from(F, Callable[..., Any]))
static_assert(is_disjoint_from(Callable[..., Any], F))
def possibly_unbound_with_invalid_type(flag: bool):
@final
@ -486,4 +496,5 @@ def possibly_unbound_with_invalid_type(flag: bool):
__call__: int = 1
static_assert(is_disjoint_from(G, Callable[..., Any]))
static_assert(is_disjoint_from(Callable[..., Any], G))
```

View file

@ -2180,23 +2180,22 @@ impl<'db> Type<'db> {
(
Type::Callable(_) | Type::DataclassDecorator(_) | Type::DataclassTransformer(_),
Type::NominalInstance(instance),
instance @ Type::NominalInstance(NominalInstanceType { class, .. }),
)
| (
Type::NominalInstance(instance),
instance @ Type::NominalInstance(NominalInstanceType { class, .. }),
Type::Callable(_) | Type::DataclassDecorator(_) | Type::DataclassTransformer(_),
) if instance.class.is_final(db) => {
let member = self.member_lookup_with_policy(
) if class.is_final(db) => instance
.member_lookup_with_policy(
db,
Name::new_static("__call__"),
MemberLookupPolicy::NO_INSTANCE_FALLBACK,
);
match member.symbol {
// TODO: ideally this would check disjointness of the `__call__` signature and the callable signature
Symbol::Type(ty, _) => !ty.is_assignable_to(db, CallableType::unknown(db)),
Symbol::Unbound => true,
}
}
)
.symbol
.ignore_possibly_unbound()
.is_none_or(|dunder_call| {
!dunder_call.is_assignable_to(db, CallableType::unknown(db))
}),
(
Type::Callable(_) | Type::DataclassDecorator(_) | Type::DataclassTransformer(_),