diff --git a/crates/red_knot_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md b/crates/red_knot_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md index 7426e4c887..4c54139cc4 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md +++ b/crates/red_knot_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md @@ -106,13 +106,13 @@ reveal_type(ChainMapSubclass.__mro__) class CounterSubclass(typing.Counter): ... # TODO: Should be (CounterSubclass, Counter, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object) -# revealed: tuple[Literal[CounterSubclass], Literal[Counter], Unknown, Literal[object]] +# revealed: tuple[Literal[CounterSubclass], Literal[Counter], @Todo(GenericAlias instance), @Todo(`Generic[]` subscript), Literal[object]] reveal_type(CounterSubclass.__mro__) class DefaultDictSubclass(typing.DefaultDict): ... # TODO: Should be (DefaultDictSubclass, defaultdict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object) -# revealed: tuple[Literal[DefaultDictSubclass], Literal[defaultdict], Unknown, Literal[object]] +# revealed: tuple[Literal[DefaultDictSubclass], Literal[defaultdict], @Todo(GenericAlias instance), Literal[object]] reveal_type(DefaultDictSubclass.__mro__) class DequeSubclass(typing.Deque): ... @@ -124,6 +124,6 @@ reveal_type(DequeSubclass.__mro__) class OrderedDictSubclass(typing.OrderedDict): ... # TODO: Should be (OrderedDictSubclass, OrderedDict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object) -# revealed: tuple[Literal[OrderedDictSubclass], Literal[OrderedDict], Unknown, Literal[object]] +# revealed: tuple[Literal[OrderedDictSubclass], Literal[OrderedDict], @Todo(GenericAlias instance), Literal[object]] reveal_type(OrderedDictSubclass.__mro__) ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md b/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md index 6359978660..295b44827d 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md +++ b/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md @@ -326,8 +326,6 @@ class Sub(Base[Sub]): ... ## Another cyclic case ```pyi -# TODO no error (generics) -# error: [invalid-base] class Derived[T](list[Derived[T]]): ... ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md index 005e3da1ea..04b39d1f50 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md @@ -81,13 +81,11 @@ python-version = "3.9" ``` ```py -# TODO: `tuple[int, str]` is a valid base (generics) -# error: [invalid-base] "Invalid class base with type `GenericAlias` (all bases must be a class, `Any`, `Unknown` or `Todo`)" class A(tuple[int, str]): ... # Runtime value: `(A, tuple, object)` # TODO: Generics -reveal_type(A.__mro__) # revealed: tuple[Literal[A], Unknown, Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[Literal[A], @Todo(GenericAlias instance), Literal[object]] ``` ## `typing.Tuple` diff --git a/crates/red_knot_python_semantic/resources/mdtest/type_of/basic.md b/crates/red_knot_python_semantic/resources/mdtest/type_of/basic.md index 1e5f4bdc5b..fc7f9f450b 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/type_of/basic.md +++ b/crates/red_knot_python_semantic/resources/mdtest/type_of/basic.md @@ -145,12 +145,10 @@ _: type[A, B] ## As a base class ```py -# TODO: this is a false positive -# error: [invalid-base] "Invalid class base with type `GenericAlias` (all bases must be a class, `Any`, `Unknown` or `Todo`)" class Foo(type[int]): ... # TODO: should be `tuple[Literal[Foo], Literal[type], Literal[object]] -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], @Todo(GenericAlias instance), Literal[object]] ``` ## `@final` classes diff --git a/crates/red_knot_python_semantic/src/types/class_base.rs b/crates/red_knot_python_semantic/src/types/class_base.rs index 6142cd322f..fa5175a0ab 100644 --- a/crates/red_knot_python_semantic/src/types/class_base.rs +++ b/crates/red_knot_python_semantic/src/types/class_base.rs @@ -78,6 +78,9 @@ impl<'db> ClassBase<'db> { Self::Class(literal.default_specialization(db)) }), Type::GenericAlias(generic) => Some(Self::Class(ClassType::Generic(generic))), + Type::Instance(instance) if instance.class().is_known(db, KnownClass::GenericAlias) => { + Self::try_from_type(db, todo_type!("GenericAlias instance")) + } Type::Union(_) => None, // TODO -- forces consideration of multiple possible MROs? Type::Intersection(_) => None, // TODO -- probably incorrect? Type::Instance(_) => None, // TODO -- handle `__mro_entries__`?