mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:34:57 +00:00
[ty] minor TypedDict fixes (#20146)
## Summary In `is_disjoint_from_impl`, we should unpack type aliases before we check `TypedDict`. This change probably doesn't have any visible effect until we have a more discriminating implementation of disjointness for `TypedDict`, but making the change now can avoid some confusion/bugs in future. In `type_ordering.rs`, we should order `TypedDict` near more similar types, and leave Union/Intersection together at the end of the list. This is not necessary for correctness, but it's more consistent and it could have saved me some confusion trying to figure out why I was only getting an unreachable panic when my code example included a `TypedDict` type. ## Test Plan None besides existing tests.
This commit is contained in:
parent
8223fea062
commit
fa7798ddd9
2 changed files with 13 additions and 11 deletions
|
@ -1986,11 +1986,6 @@ impl<'db> Type<'db> {
|
||||||
|
|
||||||
(Type::Dynamic(_), _) | (_, Type::Dynamic(_)) => C::unsatisfiable(db),
|
(Type::Dynamic(_), _) | (_, Type::Dynamic(_)) => C::unsatisfiable(db),
|
||||||
|
|
||||||
(Type::TypedDict(_), _) | (_, Type::TypedDict(_)) => {
|
|
||||||
// TODO: Implement disjointness for TypedDict
|
|
||||||
C::unsatisfiable(db)
|
|
||||||
}
|
|
||||||
|
|
||||||
(Type::TypeAlias(alias), _) => {
|
(Type::TypeAlias(alias), _) => {
|
||||||
let self_alias_ty = alias.value_type(db);
|
let self_alias_ty = alias.value_type(db);
|
||||||
visitor.visit((self_alias_ty, other), || {
|
visitor.visit((self_alias_ty, other), || {
|
||||||
|
@ -2005,6 +2000,11 @@ impl<'db> Type<'db> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(Type::TypedDict(_), _) | (_, Type::TypedDict(_)) => {
|
||||||
|
// TODO: Implement disjointness for TypedDict
|
||||||
|
C::unsatisfiable(db)
|
||||||
|
}
|
||||||
|
|
||||||
// A typevar is never disjoint from itself, since all occurrences of the typevar must
|
// A typevar is never disjoint from itself, since all occurrences of the typevar must
|
||||||
// be specialized to the same type. (This is an important difference between typevars
|
// be specialized to the same type. (This is an important difference between typevars
|
||||||
// and `Any`!) Different typevars might be disjoint, depending on their bounds and
|
// and `Any`!) Different typevars might be disjoint, depending on their bounds and
|
||||||
|
@ -5924,6 +5924,8 @@ impl<'db> Type<'db> {
|
||||||
Type::AlwaysTruthy | Type::AlwaysFalsy => KnownClass::Type.to_instance(db),
|
Type::AlwaysTruthy | Type::AlwaysFalsy => KnownClass::Type.to_instance(db),
|
||||||
Type::BoundSuper(_) => KnownClass::Super.to_class_literal(db),
|
Type::BoundSuper(_) => KnownClass::Super.to_class_literal(db),
|
||||||
Type::ProtocolInstance(protocol) => protocol.to_meta_type(db),
|
Type::ProtocolInstance(protocol) => protocol.to_meta_type(db),
|
||||||
|
// `TypedDict` instances are instances of `dict` at runtime, but its important that we
|
||||||
|
// understand a more specific meta type in order to correctly handle `__getitem__`.
|
||||||
Type::TypedDict(typed_dict) => SubclassOfType::from(db, typed_dict.defining_class()),
|
Type::TypedDict(typed_dict) => SubclassOfType::from(db, typed_dict.defining_class()),
|
||||||
Type::TypeAlias(alias) => alias.value_type(db).to_meta_type(db),
|
Type::TypeAlias(alias) => alias.value_type(db).to_meta_type(db),
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,12 @@ pub(super) fn union_or_intersection_elements_ordering<'db>(
|
||||||
(Type::TypeAlias(_), _) => Ordering::Less,
|
(Type::TypeAlias(_), _) => Ordering::Less,
|
||||||
(_, Type::TypeAlias(_)) => Ordering::Greater,
|
(_, Type::TypeAlias(_)) => Ordering::Greater,
|
||||||
|
|
||||||
|
(Type::TypedDict(left), Type::TypedDict(right)) => {
|
||||||
|
left.defining_class().cmp(&right.defining_class())
|
||||||
|
}
|
||||||
|
(Type::TypedDict(_), _) => Ordering::Less,
|
||||||
|
(_, Type::TypedDict(_)) => Ordering::Greater,
|
||||||
|
|
||||||
(Type::Union(_), _) | (_, Type::Union(_)) => {
|
(Type::Union(_), _) | (_, Type::Union(_)) => {
|
||||||
unreachable!("our type representation does not permit nested unions");
|
unreachable!("our type representation does not permit nested unions");
|
||||||
}
|
}
|
||||||
|
@ -243,12 +249,6 @@ pub(super) fn union_or_intersection_elements_ordering<'db>(
|
||||||
|
|
||||||
unreachable!("Two equal, normalized intersections should share the same Salsa ID")
|
unreachable!("Two equal, normalized intersections should share the same Salsa ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
(Type::TypedDict(left), Type::TypedDict(right)) => {
|
|
||||||
left.defining_class().cmp(&right.defining_class())
|
|
||||||
}
|
|
||||||
(Type::TypedDict(_), _) => Ordering::Less,
|
|
||||||
(_, Type::TypedDict(_)) => Ordering::Greater,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue