diff --git a/crates/ty_python_semantic/resources/mdtest/type_properties/is_assignable_to.md b/crates/ty_python_semantic/resources/mdtest/type_properties/is_assignable_to.md index f9f85641f7..f2e38485c5 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_properties/is_assignable_to.md +++ b/crates/ty_python_semantic/resources/mdtest/type_properties/is_assignable_to.md @@ -1338,6 +1338,40 @@ def g3(obj: Foo[tuple[A]]): f3(obj) ``` +## Generic aliases + +```py +from typing import final +from ty_extensions import static_assert, is_assignable_to, TypeOf + +class GenericClass[T]: + x: T # invariant + +static_assert(is_assignable_to(TypeOf[GenericClass], type[GenericClass])) +static_assert(is_assignable_to(TypeOf[GenericClass[int]], type[GenericClass])) +static_assert(is_assignable_to(TypeOf[GenericClass], type[GenericClass[int]])) +static_assert(is_assignable_to(TypeOf[GenericClass[int]], type[GenericClass[int]])) +static_assert(not is_assignable_to(TypeOf[GenericClass[str]], type[GenericClass[int]])) + +class GenericClassIntBound[T: int]: + x: T # invariant + +static_assert(is_assignable_to(TypeOf[GenericClassIntBound], type[GenericClassIntBound])) +static_assert(is_assignable_to(TypeOf[GenericClassIntBound[int]], type[GenericClassIntBound])) +static_assert(is_assignable_to(TypeOf[GenericClassIntBound], type[GenericClassIntBound[int]])) +static_assert(is_assignable_to(TypeOf[GenericClassIntBound[int]], type[GenericClassIntBound[int]])) + +@final +class GenericFinalClass[T]: + x: T # invariant + +static_assert(is_assignable_to(TypeOf[GenericFinalClass], type[GenericFinalClass])) +static_assert(is_assignable_to(TypeOf[GenericFinalClass[int]], type[GenericFinalClass])) +static_assert(is_assignable_to(TypeOf[GenericFinalClass], type[GenericFinalClass[int]])) +static_assert(is_assignable_to(TypeOf[GenericFinalClass[int]], type[GenericFinalClass[int]])) +static_assert(not is_assignable_to(TypeOf[GenericFinalClass[str]], type[GenericFinalClass[int]])) +``` + ## `TypeGuard` and `TypeIs` `TypeGuard[...]` and `TypeIs[...]` are always assignable to `bool`. diff --git a/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md b/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md index db4b0f5f98..166d67edd0 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md +++ b/crates/ty_python_semantic/resources/mdtest/type_properties/is_disjoint_from.md @@ -666,6 +666,48 @@ static_assert(is_disjoint_from(Path, tuple[Path | None, str, int])) static_assert(is_disjoint_from(Path, Path2)) ``` +## Generic aliases + +```toml +[environment] +python-version = "3.12" +``` + +```py +from typing import final +from ty_extensions import static_assert, is_disjoint_from, TypeOf + +class GenericClass[T]: + x: T # invariant + +static_assert(not is_disjoint_from(TypeOf[GenericClass], type[GenericClass])) +# TODO: these should not error +static_assert(not is_disjoint_from(TypeOf[GenericClass[int]], type[GenericClass])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericClass], type[GenericClass[int]])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericClass[int]], type[GenericClass[int]])) +static_assert(is_disjoint_from(TypeOf[GenericClass[str]], type[GenericClass[int]])) + +class GenericClassIntBound[T: int]: + x: T # invariant + +static_assert(not is_disjoint_from(TypeOf[GenericClassIntBound], type[GenericClassIntBound])) +# TODO: these should not error +static_assert(not is_disjoint_from(TypeOf[GenericClassIntBound[int]], type[GenericClassIntBound])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericClassIntBound], type[GenericClassIntBound[int]])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericClassIntBound[int]], type[GenericClassIntBound[int]])) + +@final +class GenericFinalClass[T]: + x: T # invariant + +# TODO: these should not error +static_assert(not is_disjoint_from(TypeOf[GenericFinalClass], type[GenericFinalClass])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericFinalClass[int]], type[GenericFinalClass])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericFinalClass], type[GenericFinalClass[int]])) # error: [static-assert-error] +static_assert(not is_disjoint_from(TypeOf[GenericFinalClass[int]], type[GenericFinalClass[int]])) +static_assert(is_disjoint_from(TypeOf[GenericFinalClass[str]], type[GenericFinalClass[int]])) +``` + ## Callables No two callable types are disjoint because there exists a non-empty callable type