diff --git a/crates/ty_python_semantic/resources/mdtest/type_of/basic.md b/crates/ty_python_semantic/resources/mdtest/type_of/basic.md index b95e5154aa..159395ce23 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_of/basic.md +++ b/crates/ty_python_semantic/resources/mdtest/type_of/basic.md @@ -151,6 +151,28 @@ class Foo(type[int]): ... reveal_type(Foo.__mro__) # revealed: tuple[, @Todo(GenericAlias instance), ] ``` +## Display of generic `type[]` types + +```toml +[environment] +python-version = "3.12" +``` + +```py +from typing import Generic, TypeVar + +class Foo[T]: ... + +S = TypeVar("S") + +class Bar(Generic[S]): ... + +def _(x: Foo[int], y: Bar[str], z: list[bytes]): + reveal_type(type(x)) # revealed: type[Foo[int]] + reveal_type(type(y)) # revealed: type[Bar[str]] + reveal_type(type(z)) # revealed: type[list[bytes]] +``` + ## `@final` classes `type[]` types are eagerly converted to class-literal types if a class decorated with `@final` is diff --git a/crates/ty_python_semantic/src/types/display.rs b/crates/ty_python_semantic/src/types/display.rs index 1495cfc0bd..62ea9e9e5e 100644 --- a/crates/ty_python_semantic/src/types/display.rs +++ b/crates/ty_python_semantic/src/types/display.rs @@ -109,9 +109,12 @@ impl Display for DisplayRepresentation<'_> { } Type::GenericAlias(generic) => write!(f, "", generic.display(self.db)), Type::SubclassOf(subclass_of_ty) => match subclass_of_ty.subclass_of() { - // Only show the bare class name here; ClassBase::display would render this as - // type[] instead of type[Foo]. - SubclassOfInner::Class(class) => write!(f, "type[{}]", class.name(self.db)), + SubclassOfInner::Class(ClassType::NonGeneric(class)) => { + write!(f, "type[{}]", class.name(self.db)) + } + SubclassOfInner::Class(ClassType::Generic(alias)) => { + write!(f, "type[{}]", alias.display(self.db)) + } SubclassOfInner::Dynamic(dynamic) => write!(f, "type[{dynamic}]"), }, Type::SpecialForm(special_form) => special_form.fmt(f),