Skip to content

Commit c7bf47a

Browse files
committed
[red-knot] GenericAlias instances as a base class
1 parent 3fae176 commit c7bf47a

File tree

6 files changed

+9
-11
lines changed

6 files changed

+9
-11
lines changed

crates/red_knot_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ reveal_type(ChainMapSubclass.__mro__)
106106
class CounterSubclass(typing.Counter): ...
107107

108108
# TODO: Should be (CounterSubclass, Counter, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
109-
# revealed: tuple[Literal[CounterSubclass], Literal[Counter], Unknown, Literal[object]]
109+
# revealed: tuple[Literal[CounterSubclass], Literal[Counter], @Todo(GenericAlias instance), @Todo(`Generic[]` subscript), Literal[object]]
110110
reveal_type(CounterSubclass.__mro__)
111111

112112
class DefaultDictSubclass(typing.DefaultDict): ...
113113

114114
# TODO: Should be (DefaultDictSubclass, defaultdict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
115-
# revealed: tuple[Literal[DefaultDictSubclass], Literal[defaultdict], Unknown, Literal[object]]
115+
# revealed: tuple[Literal[DefaultDictSubclass], Literal[defaultdict], @Todo(GenericAlias instance), Literal[object]]
116116
reveal_type(DefaultDictSubclass.__mro__)
117117

118118
class DequeSubclass(typing.Deque): ...
@@ -124,6 +124,6 @@ reveal_type(DequeSubclass.__mro__)
124124
class OrderedDictSubclass(typing.OrderedDict): ...
125125

126126
# TODO: Should be (OrderedDictSubclass, OrderedDict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
127-
# revealed: tuple[Literal[OrderedDictSubclass], Literal[OrderedDict], Unknown, Literal[object]]
127+
# revealed: tuple[Literal[OrderedDictSubclass], Literal[OrderedDict], @Todo(GenericAlias instance), Literal[object]]
128128
reveal_type(OrderedDictSubclass.__mro__)
129129
```

crates/red_knot_python_semantic/resources/mdtest/generics/classes.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,6 @@ class Sub(Base[Sub]): ...
326326
## Another cyclic case
327327

328328
```pyi
329-
# TODO no error (generics)
330-
# error: [invalid-base]
331329
class Derived[T](list[Derived[T]]): ...
332330
```
333331

crates/red_knot_python_semantic/resources/mdtest/mdtest_custom_typeshed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ We can then place custom stub files in `/typeshed/stdlib`, for example:
2222
`/typeshed/stdlib/builtins.pyi`:
2323

2424
```pyi
25+
class object: ...
2526
class BuiltinClass: ...
2627

2728
builtin_symbol: BuiltinClass

crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,11 @@ python-version = "3.9"
8181
```
8282

8383
```py
84-
# TODO: `tuple[int, str]` is a valid base (generics)
85-
# error: [invalid-base] "Invalid class base with type `GenericAlias` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
8684
class A(tuple[int, str]): ...
8785

8886
# Runtime value: `(A, tuple, object)`
8987
# TODO: Generics
90-
reveal_type(A.__mro__) # revealed: tuple[Literal[A], Unknown, Literal[object]]
88+
reveal_type(A.__mro__) # revealed: tuple[Literal[A], @Todo(GenericAlias instance), Literal[object]]
9189
```
9290

9391
## `typing.Tuple`

crates/red_knot_python_semantic/resources/mdtest/type_of/basic.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,10 @@ _: type[A, B]
145145
## As a base class
146146

147147
```py
148-
# TODO: this is a false positive
149-
# error: [invalid-base] "Invalid class base with type `GenericAlias` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
150148
class Foo(type[int]): ...
151149

152150
# TODO: should be `tuple[Literal[Foo], Literal[type], Literal[object]]
153-
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
151+
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], @Todo(GenericAlias instance), Literal[object]]
154152
```
155153

156154
## `@final` classes

crates/red_knot_python_semantic/src/types/class_base.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ impl<'db> ClassBase<'db> {
7878
Self::Class(literal.default_specialization(db))
7979
}),
8080
Type::GenericAlias(generic) => Some(Self::Class(ClassType::Generic(generic))),
81+
Type::Instance(instance) if instance.class().is_known(db, KnownClass::GenericAlias) => {
82+
Self::try_from_type(db, todo_type!("GenericAlias instance"))
83+
}
8184
Type::Union(_) => None, // TODO -- forces consideration of multiple possible MROs?
8285
Type::Intersection(_) => None, // TODO -- probably incorrect?
8386
Type::Instance(_) => None, // TODO -- handle `__mro_entries__`?

0 commit comments

Comments
 (0)