Skip to content

Commit 88991ae

Browse files
committed
[ty] Make Any a subtype of Any
1 parent eb6154f commit 88991ae

File tree

5 files changed

+20
-72
lines changed

5 files changed

+20
-72
lines changed

crates/ty_python_semantic/resources/mdtest/generics/legacy/variance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static_assert(not is_subtype_of(C[A], C[Any]))
5959
static_assert(not is_subtype_of(C[B], C[Any]))
6060
static_assert(not is_subtype_of(C[Any], C[A]))
6161
static_assert(not is_subtype_of(C[Any], C[B]))
62-
static_assert(not is_subtype_of(C[Any], C[Any]))
62+
static_assert(is_subtype_of(C[Any], C[Any]))
6363

6464
static_assert(is_subtype_of(D[B], C[A]))
6565
static_assert(not is_subtype_of(D[A], C[B]))

crates/ty_python_semantic/resources/mdtest/generics/pep695/variance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ static_assert(not is_subtype_of(C[A], C[Any]))
302302
static_assert(not is_subtype_of(C[B], C[Any]))
303303
static_assert(not is_subtype_of(C[Any], C[A]))
304304
static_assert(not is_subtype_of(C[Any], C[B]))
305-
static_assert(not is_subtype_of(C[Any], C[Any]))
305+
static_assert(is_subtype_of(C[Any], C[Any]))
306306

307307
static_assert(is_subtype_of(D[B], C[A]))
308308
static_assert(is_subtype_of(D[A], C[B]))

crates/ty_python_semantic/resources/mdtest/type_properties/is_subtype_of.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ Its subtyping follows the general rule for subtyping of gradual types.
348348
from typing import Any, Never
349349
from ty_extensions import static_assert, is_subtype_of
350350

351-
static_assert(not is_subtype_of(tuple[Any, ...], tuple[Any, ...]))
351+
static_assert(is_subtype_of(tuple[Any, ...], tuple[Any, ...]))
352352
static_assert(not is_subtype_of(tuple[Any, ...], tuple[Any]))
353353
static_assert(not is_subtype_of(tuple[Any, ...], tuple[Any, Any]))
354354
static_assert(not is_subtype_of(tuple[Any, ...], tuple[int, ...]))
@@ -361,7 +361,7 @@ static_assert(is_subtype_of(tuple[Never, ...], tuple[Any, ...]))
361361
Same applies when `tuple[Any, ...]` is unpacked into a mixed tuple.
362362

363363
```py
364-
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[int, *tuple[Any, ...]]))
364+
static_assert(is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[int, *tuple[Any, ...]]))
365365
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[Any, ...]))
366366
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[Any]))
367367
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[Any, Any]))
@@ -370,7 +370,7 @@ static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[int, ...]))
370370
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[int]))
371371
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...]], tuple[int, int]))
372372

373-
static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[*tuple[Any, ...], int]))
373+
static_assert(is_subtype_of(tuple[*tuple[Any, ...], int], tuple[*tuple[Any, ...], int]))
374374
static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[Any, ...]))
375375
static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[Any]))
376376
static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[Any, Any]))
@@ -379,7 +379,7 @@ static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[int, ...]))
379379
static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[int]))
380380
static_assert(not is_subtype_of(tuple[*tuple[Any, ...], int], tuple[int, int]))
381381

382-
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...], int], tuple[int, *tuple[Any, ...], int]))
382+
static_assert(is_subtype_of(tuple[int, *tuple[Any, ...], int], tuple[int, *tuple[Any, ...], int]))
383383
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...], int], tuple[Any, ...]))
384384
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...], int], tuple[Any]))
385385
static_assert(not is_subtype_of(tuple[int, *tuple[Any, ...], int], tuple[Any, Any]))
@@ -647,10 +647,10 @@ from typing_extensions import TypeGuard, TypeIs
647647
# TODO: TypeGuard
648648
# static_assert(is_subtype_of(TypeGuard[int], TypeGuard[int]))
649649
# static_assert(is_subtype_of(TypeGuard[bool], TypeGuard[int]))
650+
# static_assert(not is_subtype_of(TypeGuard[int], TypeGuard[bool]))
650651
static_assert(is_subtype_of(TypeIs[int], TypeIs[int]))
651652
static_assert(is_subtype_of(TypeIs[int], TypeIs[int]))
652653

653-
static_assert(not is_subtype_of(TypeGuard[int], TypeGuard[bool]))
654654
static_assert(not is_subtype_of(TypeIs[bool], TypeIs[int]))
655655
static_assert(not is_subtype_of(TypeIs[int], TypeIs[bool]))
656656
```
@@ -821,7 +821,7 @@ represented by a materialization of the second type.
821821
from ty_extensions import Unknown, is_subtype_of, static_assert, Intersection
822822
from typing_extensions import Any
823823

824-
static_assert(not is_subtype_of(Any, Any))
824+
static_assert(is_subtype_of(Any, Any))
825825
static_assert(not is_subtype_of(Any, int))
826826
static_assert(not is_subtype_of(int, Any))
827827
static_assert(is_subtype_of(Any, object))
@@ -835,7 +835,7 @@ static_assert(not is_subtype_of(tuple[int, int], tuple[int, Any]))
835835
The same for `Unknown`:
836836

837837
```py
838-
static_assert(not is_subtype_of(Unknown, Unknown))
838+
static_assert(is_subtype_of(Unknown, Unknown))
839839
static_assert(not is_subtype_of(Unknown, int))
840840
static_assert(not is_subtype_of(int, Unknown))
841841
static_assert(is_subtype_of(Unknown, object))
@@ -870,7 +870,7 @@ static_assert(is_subtype_of(InheritsAny, object))
870870
Similar for subclass-of types:
871871

872872
```py
873-
static_assert(not is_subtype_of(type[Any], type[Any]))
873+
static_assert(is_subtype_of(type[Any], type[Any]))
874874
static_assert(not is_subtype_of(type[object], type[Any]))
875875
static_assert(not is_subtype_of(type[Any], type[Arbitrary]))
876876
static_assert(is_subtype_of(type[Any], type[object]))

crates/ty_python_semantic/src/types.rs

Lines changed: 9 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,55 +1129,6 @@ impl<'db> Type<'db> {
11291129
}
11301130
}
11311131

1132-
/// Return `true` if subtyping is always reflexive for this type; `T <: T` is always true for
1133-
/// any `T` of this type.
1134-
///
1135-
/// This is true for fully static types, but also for some types that may not be fully static.
1136-
/// For example, a `ClassLiteral` may inherit `Any`, but its subtyping is still reflexive.
1137-
///
1138-
/// This method may have false negatives, but it should not have false positives. It should be
1139-
/// a cheap shallow check, not an exhaustive recursive check.
1140-
fn subtyping_is_always_reflexive(self) -> bool {
1141-
match self {
1142-
Type::Never
1143-
| Type::FunctionLiteral(..)
1144-
| Type::BoundMethod(_)
1145-
| Type::WrapperDescriptor(_)
1146-
| Type::MethodWrapper(_)
1147-
| Type::DataclassDecorator(_)
1148-
| Type::DataclassTransformer(_)
1149-
| Type::ModuleLiteral(..)
1150-
| Type::IntLiteral(_)
1151-
| Type::BooleanLiteral(_)
1152-
| Type::StringLiteral(_)
1153-
| Type::LiteralString
1154-
| Type::BytesLiteral(_)
1155-
| Type::EnumLiteral(_)
1156-
| Type::SpecialForm(_)
1157-
| Type::KnownInstance(_)
1158-
| Type::AlwaysFalsy
1159-
| Type::AlwaysTruthy
1160-
| Type::PropertyInstance(_)
1161-
// might inherit `Any`, but subtyping is still reflexive
1162-
| Type::ClassLiteral(_)
1163-
=> true,
1164-
Type::Dynamic(_)
1165-
| Type::NominalInstance(_)
1166-
| Type::ProtocolInstance(_)
1167-
| Type::GenericAlias(_)
1168-
| Type::SubclassOf(_)
1169-
| Type::Union(_)
1170-
| Type::Intersection(_)
1171-
| Type::Callable(_)
1172-
| Type::NonInferableTypeVar(_)
1173-
| Type::TypeVar(_)
1174-
| Type::BoundSuper(_)
1175-
| Type::TypeIs(_)
1176-
| Type::TypedDict(_)
1177-
| Type::TypeAlias(_) => false,
1178-
}
1179-
}
1180-
11811132
pub(crate) fn into_callable(self, db: &'db dyn Db) -> Option<Type<'db>> {
11821133
match self {
11831134
Type::Callable(_) => Some(self),
@@ -1334,27 +1285,26 @@ impl<'db> Type<'db> {
13341285
relation: TypeRelation,
13351286
visitor: &HasRelationToVisitor<'db, C>,
13361287
) -> C {
1337-
// Subtyping implies assignability, so if subtyping is reflexive and the two types are
1338-
// equal, it is both a subtype and assignable. Assignability is always reflexive.
1339-
//
13401288
// Note that we could do a full equivalence check here, but that would be both expensive
13411289
// and unnecessary. This early return is only an optimisation.
1342-
if (relation.is_assignability() || self.subtyping_is_always_reflexive()) && self == target {
1290+
if self == target {
13431291
return C::always_satisfiable(db);
13441292
}
13451293

13461294
match (self, target) {
1295+
// `Never` is the bottom type, the empty set.
1296+
// It is a subtype of all other types.
1297+
(Type::Never, _) => C::always_satisfiable(db),
1298+
1299+
(Type::Dynamic(_), Type::Dynamic(_)) => C::always_satisfiable(db),
1300+
13471301
// Everything is a subtype of `object`.
13481302
(_, Type::NominalInstance(instance)) if instance.is_object(db) => {
13491303
C::always_satisfiable(db)
13501304
}
13511305

1352-
// `Never` is the bottom type, the empty set.
1353-
// It is a subtype of all other types.
1354-
(Type::Never, _) => C::always_satisfiable(db),
1355-
1356-
// Dynamic is only a subtype of `object` and only a supertype of `Never`; both were
1357-
// handled above. It's always assignable, though.
1306+
// Dynamic is only a subtype of `object` and itself, and only a supertype of `Never` and itself;
1307+
// both were handled above. It's always assignable, though.
13581308
(Type::Dynamic(_), _) | (_, Type::Dynamic(_)) => {
13591309
C::from_bool(db, relation.is_assignability())
13601310
}

crates/ty_python_semantic/src/types/subclass_of.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,7 @@ impl<'db> SubclassOfType<'db> {
137137
visitor: &HasRelationToVisitor<'db, C>,
138138
) -> C {
139139
match (self.subclass_of, other.subclass_of) {
140-
(SubclassOfInner::Dynamic(_), SubclassOfInner::Dynamic(_)) => {
141-
C::from_bool(db, relation.is_assignability())
142-
}
140+
(SubclassOfInner::Dynamic(_), SubclassOfInner::Dynamic(_)) => C::always_satisfiable(db),
143141
(SubclassOfInner::Dynamic(_), SubclassOfInner::Class(other_class)) => {
144142
C::from_bool(db, other_class.is_object(db) || relation.is_assignability())
145143
}

0 commit comments

Comments
 (0)