[red-knot] Add explicit TODO branches for many typing special forms and qualifiers (#14936)

This commit is contained in:
Alex Waygood 2024-12-12 17:57:26 +00:00 committed by GitHub
parent 58930905eb
commit 71239f248e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 471 additions and 22 deletions

View file

@ -0,0 +1,83 @@
# Typing-module aliases to other stdlib classes
The `typing` module has various aliases to other stdlib classes. These are a legacy feature, but
still need to be supported by a type checker.
## Currently unsupported
Support for most of these symbols is currently a TODO:
```py
import typing
def f(
a: typing.List,
b: typing.List[int],
c: typing.Dict,
d: typing.Dict[int, str],
e: typing.DefaultDict,
f: typing.DefaultDict[str, int],
g: typing.Set,
h: typing.Set[int],
i: typing.FrozenSet,
j: typing.FrozenSet[str],
k: typing.OrderedDict,
l: typing.OrderedDict[int, str],
m: typing.Counter,
n: typing.Counter[int],
):
reveal_type(a) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(b) # revealed: @Todo(typing.List alias)
reveal_type(c) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(d) # revealed: @Todo(typing.Dict alias)
reveal_type(e) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(f) # revealed: @Todo(typing.DefaultDict[] alias)
reveal_type(g) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(h) # revealed: @Todo(typing.Set alias)
reveal_type(i) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(j) # revealed: @Todo(typing.FrozenSet alias)
reveal_type(k) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(l) # revealed: @Todo(typing.OrderedDict alias)
reveal_type(m) # revealed: @Todo(Unsupported or invalid type in a type expression)
reveal_type(n) # revealed: @Todo(typing.Counter[] alias)
```
## Inheritance
The aliases can be inherited from. Some of these are still partially or wholly TODOs.
```py
import typing
class A(typing.Dict): ...
# TODO: should have `Generic`, should not have `Unknown`
reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[dict], Unknown, Literal[object]]
class B(typing.List): ...
# TODO: should have `Generic`, should not have `Unknown`
reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[list], Unknown, Literal[object]]
class C(typing.Set): ...
# TODO: should have `Generic`, should not have `Unknown`
reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[set], Unknown, Literal[object]]
class D(typing.FrozenSet): ...
# TODO: should have `Generic`, should not have `Unknown`
reveal_type(D.__mro__) # revealed: tuple[Literal[D], Literal[frozenset], Unknown, Literal[object]]
class E(typing.DefaultDict): ...
reveal_type(E.__mro__) # revealed: tuple[Literal[E], @Todo(Support for more typing aliases as base classes), Literal[object]]
class F(typing.OrderedDict): ...
reveal_type(F.__mro__) # revealed: tuple[Literal[F], @Todo(Support for more typing aliases as base classes), Literal[object]]
class G(typing.Counter): ...
reveal_type(G.__mro__) # revealed: tuple[Literal[G], @Todo(Support for more typing aliases as base classes), Literal[object]]
```

View file

@ -0,0 +1,71 @@
# Unsupported special forms
## Not yet supported
Several special forms are unsupported by red-knot currently. However, we also don't emit
false-positive errors if you use one in an annotation:
```py
from typing_extensions import Self, TypeVarTuple, Unpack, TypeGuard, TypeIs, Concatenate, ParamSpec, TypeAlias, Callable, TypeVar
P = ParamSpec("P")
Ts = TypeVarTuple("Ts")
R_co = TypeVar("R_co", covariant=True)
Alias: TypeAlias = int
def f(*args: Unpack[Ts]) -> tuple[Unpack[Ts]]:
# TODO: should understand the annotation
reveal_type(args) # revealed: tuple
reveal_type(Alias) # revealed: @Todo(Unsupported or invalid type in a type expression)
def g() -> TypeGuard[int]: ...
def h() -> TypeIs[int]: ...
def i(callback: Callable[Concatenate[int, P], R_co], *args: P.args, **kwargs: P.kwargs) -> R_co:
# TODO: should understand the annotation
reveal_type(args) # revealed: tuple
# TODO: should understand the annotation
reveal_type(kwargs) # revealed: dict
return callback(42, *args, **kwargs)
class Foo:
def method(self, x: Self):
reveal_type(x) # revealed: @Todo(Unsupported or invalid type in a type expression)
```
## Inheritance
You can't inherit from most of these. `typing.Callable` is an exception.
```py
from typing import Callable
from typing_extensions import Self, Unpack, TypeGuard, TypeIs, Concatenate
class A(Self): ... # error: [invalid-base]
class B(Unpack): ... # error: [invalid-base]
class C(TypeGuard): ... # error: [invalid-base]
class D(TypeIs): ... # error: [invalid-base]
class E(Concatenate): ... # error: [invalid-base]
class F(Callable): ...
reveal_type(F.__mro__) # revealed: tuple[Literal[F], @Todo(Support for more typing aliases as base classes), Literal[object]]
```
## Subscriptability
Some of these are not subscriptable:
```py
from typing_extensions import Self, TypeAlias
X: TypeAlias[T] = int # error: [invalid-type-parameter]
class Foo[T]:
# error: [invalid-type-parameter] "Special form `typing.Self` expected no type parameter"
# error: [invalid-type-parameter] "Special form `typing.Self` expected no type parameter"
def method(self: Self[int]) -> Self[int]:
reveal_type(self) # revealed: Unknown
```

View file

@ -0,0 +1,37 @@
# Unsupported type qualifiers
## Not yet supported
Several type qualifiers are unsupported by red-knot currently. However, we also don't emit
false-positive errors if you use one in an annotation:
```py
from typing_extensions import Final, ClassVar, Required, NotRequired, ReadOnly, TypedDict
X: Final = 42
Y: Final[int] = 42
class Foo:
A: ClassVar[int] = 42
# TODO: `TypedDict` is actually valid as a base
# error: [invalid-base]
class Bar(TypedDict):
x: Required[int]
y: NotRequired[str]
z: ReadOnly[bytes]
```
## Inheritance
You can't inherit from a type qualifier.
```py
from typing_extensions import Final, ClassVar, Required, NotRequired, ReadOnly
class A(Final): ... # error: [invalid-base]
class B(ClassVar): ... # error: [invalid-base]
class C(Required): ... # error: [invalid-base]
class D(NotRequired): ... # error: [invalid-base]
class E(ReadOnly): ... # error: [invalid-base]
```

View file

@ -1255,6 +1255,7 @@ impl<'db> Type<'db> {
| KnownClass::List
| KnownClass::Tuple
| KnownClass::Set
| KnownClass::FrozenSet
| KnownClass::Dict
| KnownClass::Slice
| KnownClass::BaseException
@ -1263,6 +1264,7 @@ impl<'db> Type<'db> {
| KnownClass::ModuleType
| KnownClass::FunctionType
| KnownClass::SpecialForm
| KnownClass::StdlibAlias
| KnownClass::TypeVar,
) => false,
None => false,
@ -1782,7 +1784,8 @@ impl<'db> Type<'db> {
}
Type::KnownInstance(KnownInstanceType::LiteralString) => Type::LiteralString,
Type::KnownInstance(KnownInstanceType::Any) => Type::Any,
_ => todo_type!(),
Type::Todo(_) => *self,
_ => todo_type!("Unsupported or invalid type in a type expression"),
}
}
@ -1934,6 +1937,7 @@ pub enum KnownClass {
List,
Tuple,
Set,
FrozenSet,
Dict,
Slice,
BaseException,
@ -1945,6 +1949,7 @@ pub enum KnownClass {
// Typeshed
NoneType, // Part of `types` for Python >= 3.10
// Typing
StdlibAlias,
SpecialForm,
TypeVar,
TypeAliasType,
@ -1962,6 +1967,7 @@ impl<'db> KnownClass {
Self::Tuple => "tuple",
Self::Int => "int",
Self::Float => "float",
Self::FrozenSet => "frozenset",
Self::Str => "str",
Self::Set => "set",
Self::Dict => "dict",
@ -1978,6 +1984,8 @@ impl<'db> KnownClass {
Self::TypeVar => "TypeVar",
Self::TypeAliasType => "TypeAliasType",
Self::NoDefaultType => "_NoDefaultType",
// For example, `typing.List` is defined as `List = _Alias()` in typeshed
Self::StdlibAlias => "_Alias",
// This is the name the type of `sys.version_info` has in typeshed,
// which is different to what `type(sys.version_info).__name__` is at runtime.
// (At runtime, `type(sys.version_info).__name__ == "version_info"`,
@ -2016,6 +2024,7 @@ impl<'db> KnownClass {
| Self::List
| Self::Tuple
| Self::Set
| Self::FrozenSet
| Self::Dict
| Self::BaseException
| Self::BaseExceptionGroup
@ -2023,7 +2032,9 @@ impl<'db> KnownClass {
Self::VersionInfo => CoreStdlibModule::Sys,
Self::GenericAlias | Self::ModuleType | Self::FunctionType => CoreStdlibModule::Types,
Self::NoneType => CoreStdlibModule::Typeshed,
Self::SpecialForm | Self::TypeVar | Self::TypeAliasType => CoreStdlibModule::Typing,
Self::SpecialForm | Self::TypeVar | Self::TypeAliasType | Self::StdlibAlias => {
CoreStdlibModule::Typing
}
Self::NoDefaultType => {
let python_version = Program::get(db).target_version(db);
@ -2054,6 +2065,7 @@ impl<'db> KnownClass {
| Self::Float
| Self::Str
| Self::Set
| Self::FrozenSet
| Self::Dict
| Self::List
| Self::Type
@ -2062,6 +2074,7 @@ impl<'db> KnownClass {
| Self::ModuleType
| Self::FunctionType
| Self::SpecialForm
| Self::StdlibAlias
| Self::BaseException
| Self::BaseExceptionGroup
| Self::TypeVar => false,
@ -2082,6 +2095,7 @@ impl<'db> KnownClass {
"float" => Self::Float,
"str" => Self::Str,
"set" => Self::Set,
"frozenset" => Self::FrozenSet,
"dict" => Self::Dict,
"list" => Self::List,
"slice" => Self::Slice,
@ -2092,6 +2106,7 @@ impl<'db> KnownClass {
"ModuleType" => Self::ModuleType,
"FunctionType" => Self::FunctionType,
"TypeAliasType" => Self::TypeAliasType,
"_Alias" => Self::StdlibAlias,
"_SpecialForm" => Self::SpecialForm,
"_NoDefaultType" => Self::NoDefaultType,
"_version_info" => Self::VersionInfo,
@ -2118,9 +2133,11 @@ impl<'db> KnownClass {
| Self::List
| Self::Tuple
| Self::Set
| Self::FrozenSet
| Self::Dict
| Self::Slice
| Self::GenericAlias
| Self::StdlibAlias // no equivalent class exists in typing_extensions, nor ever will
| Self::ModuleType
| Self::VersionInfo
| Self::BaseException
@ -2159,6 +2176,30 @@ pub enum KnownInstanceType<'db> {
TypeVar(TypeVarInstance<'db>),
/// A single instance of `typing.TypeAliasType` (PEP 695 type alias)
TypeAliasType(TypeAliasType<'db>),
// Various special forms, special aliases and type qualifiers that we don't yet understand
// (all currently inferred as TODO in most contexts):
TypingSelf,
Final,
ClassVar,
Callable,
Concatenate,
Unpack,
Required,
NotRequired,
TypeAlias,
TypeGuard,
TypeIs,
List,
Dict,
DefaultDict,
Set,
FrozenSet,
Counter,
Deque,
ChainMap,
OrderedDict,
ReadOnly,
// TODO: fill this enum out with more special forms, etc.
}
@ -2176,6 +2217,27 @@ impl<'db> KnownInstanceType<'db> {
Self::Tuple => "Tuple",
Self::Type => "Type",
Self::TypeAliasType(_) => "TypeAliasType",
Self::TypingSelf => "Self",
Self::Final => "Final",
Self::ClassVar => "ClassVar",
Self::Callable => "Callable",
Self::Concatenate => "Concatenate",
Self::Unpack => "Unpack",
Self::Required => "Required",
Self::NotRequired => "NotRequired",
Self::TypeAlias => "TypeAlias",
Self::TypeGuard => "TypeGuard",
Self::TypeIs => "TypeIs",
Self::List => "List",
Self::Dict => "Dict",
Self::DefaultDict => "DefaultDict",
Self::Set => "Set",
Self::FrozenSet => "FrozenSet",
Self::Counter => "Counter",
Self::Deque => "Deque",
Self::ChainMap => "ChainMap",
Self::OrderedDict => "OrderedDict",
Self::ReadOnly => "ReadOnly",
}
}
@ -2192,6 +2254,27 @@ impl<'db> KnownInstanceType<'db> {
| Self::Any
| Self::Tuple
| Self::Type
| Self::TypingSelf
| Self::Final
| Self::ClassVar
| Self::Callable
| Self::Concatenate
| Self::Unpack
| Self::Required
| Self::NotRequired
| Self::TypeAlias
| Self::TypeGuard
| Self::TypeIs
| Self::List
| Self::Dict
| Self::DefaultDict
| Self::Set
| Self::FrozenSet
| Self::Counter
| Self::Deque
| Self::ChainMap
| Self::OrderedDict
| Self::ReadOnly
| Self::TypeAliasType(_) => Truthiness::AlwaysTrue,
}
}
@ -2208,6 +2291,27 @@ impl<'db> KnownInstanceType<'db> {
Self::Any => "typing.Any",
Self::Tuple => "typing.Tuple",
Self::Type => "typing.Type",
Self::TypingSelf => "typing.Self",
Self::Final => "typing.Final",
Self::ClassVar => "typing.ClassVar",
Self::Callable => "typing.Callable",
Self::Concatenate => "typing.Concatenate",
Self::Unpack => "typing.Unpack",
Self::Required => "typing.Required",
Self::NotRequired => "typing.NotRequired",
Self::TypeAlias => "typing.TypeAlias",
Self::TypeGuard => "typing.TypeGuard",
Self::TypeIs => "typing.TypeIs",
Self::List => "typing.List",
Self::Dict => "typing.Dict",
Self::DefaultDict => "typing.DefaultDict",
Self::Set => "typing.Set",
Self::FrozenSet => "typing.FrozenSet",
Self::Counter => "typing.Counter",
Self::Deque => "typing.Deque",
Self::ChainMap => "typing.ChainMap",
Self::OrderedDict => "typing.OrderedDict",
Self::ReadOnly => "typing.ReadOnly",
Self::TypeVar(typevar) => typevar.name(db),
Self::TypeAliasType(_) => "typing.TypeAliasType",
}
@ -2225,6 +2329,27 @@ impl<'db> KnownInstanceType<'db> {
Self::Any => KnownClass::Object,
Self::Tuple => KnownClass::SpecialForm,
Self::Type => KnownClass::SpecialForm,
Self::TypingSelf => KnownClass::SpecialForm,
Self::Final => KnownClass::SpecialForm,
Self::ClassVar => KnownClass::SpecialForm,
Self::Callable => KnownClass::SpecialForm,
Self::Concatenate => KnownClass::SpecialForm,
Self::Unpack => KnownClass::SpecialForm,
Self::Required => KnownClass::SpecialForm,
Self::NotRequired => KnownClass::SpecialForm,
Self::TypeAlias => KnownClass::SpecialForm,
Self::TypeGuard => KnownClass::SpecialForm,
Self::TypeIs => KnownClass::SpecialForm,
Self::ReadOnly => KnownClass::SpecialForm,
Self::List => KnownClass::StdlibAlias,
Self::Dict => KnownClass::StdlibAlias,
Self::DefaultDict => KnownClass::StdlibAlias,
Self::Set => KnownClass::StdlibAlias,
Self::FrozenSet => KnownClass::StdlibAlias,
Self::Counter => KnownClass::StdlibAlias,
Self::Deque => KnownClass::StdlibAlias,
Self::ChainMap => KnownClass::StdlibAlias,
Self::OrderedDict => KnownClass::StdlibAlias,
Self::TypeVar(_) => KnownClass::TypeVar,
Self::TypeAliasType(_) => KnownClass::TypeAliasType,
}
@ -2245,14 +2370,35 @@ impl<'db> KnownInstanceType<'db> {
}
match (module.name().as_str(), instance_name) {
("typing", "Any") => Some(Self::Any),
("typing", "ClassVar") => Some(Self::ClassVar),
("typing", "Deque") => Some(Self::Deque),
("typing", "List") => Some(Self::List),
("typing", "Dict") => Some(Self::Dict),
("typing", "DefaultDict") => Some(Self::DefaultDict),
("typing", "Set") => Some(Self::Set),
("typing", "FrozenSet") => Some(Self::FrozenSet),
("typing", "Counter") => Some(Self::Counter),
("typing", "ChainMap") => Some(Self::ChainMap),
("typing", "OrderedDict") => Some(Self::OrderedDict),
("typing", "Optional") => Some(Self::Optional),
("typing", "Union") => Some(Self::Union),
("typing", "NoReturn") => Some(Self::NoReturn),
("typing", "Tuple") => Some(Self::Tuple),
("typing", "Type") => Some(Self::Type),
("typing", "Callable") => Some(Self::Callable),
("typing" | "typing_extensions", "Literal") => Some(Self::Literal),
("typing" | "typing_extensions", "LiteralString") => Some(Self::LiteralString),
("typing" | "typing_extensions", "Optional") => Some(Self::Optional),
("typing" | "typing_extensions", "Union") => Some(Self::Union),
("typing" | "typing_extensions", "NoReturn") => Some(Self::NoReturn),
("typing" | "typing_extensions", "Never") => Some(Self::Never),
("typing" | "typing_extensions", "Tuple") => Some(Self::Tuple),
("typing" | "typing_extensions", "Type") => Some(Self::Type),
("typing" | "typing_extensions", "Self") => Some(Self::TypingSelf),
("typing" | "typing_extensions", "Final") => Some(Self::Final),
("typing" | "typing_extensions", "Concatenate") => Some(Self::Concatenate),
("typing" | "typing_extensions", "Unpack") => Some(Self::Unpack),
("typing" | "typing_extensions", "Required") => Some(Self::Required),
("typing" | "typing_extensions", "NotRequired") => Some(Self::NotRequired),
("typing" | "typing_extensions", "TypeAlias") => Some(Self::TypeAlias),
("typing" | "typing_extensions", "TypeGuard") => Some(Self::TypeGuard),
("typing" | "typing_extensions", "TypeIs") => Some(Self::TypeIs),
("typing" | "typing_extensions", "ReadOnly") => Some(Self::ReadOnly),
_ => None,
}
}

View file

@ -4786,6 +4786,10 @@ impl<'db> TypeInferenceBuilder<'db> {
Type::KnownInstance(known_instance) => {
self.infer_parameterized_known_instance_type_expression(subscript, known_instance)
}
Type::Todo(_) => {
self.infer_type_expression(slice);
value_ty
}
_ => {
self.infer_type_expression(slice);
todo_type!("generics")
@ -4833,13 +4837,89 @@ impl<'db> TypeInferenceBuilder<'db> {
},
KnownInstanceType::TypeVar(_) => {
self.infer_type_expression(parameters);
todo_type!()
todo_type!("TypeVar annotations")
}
KnownInstanceType::TypeAliasType(_) => {
self.infer_type_expression(parameters);
todo_type!("generic type alias")
todo_type!("Generic PEP-695 type alias")
}
KnownInstanceType::NoReturn | KnownInstanceType::Never => {
KnownInstanceType::Callable => {
self.infer_type_expression(parameters);
todo_type!("Callable types")
}
KnownInstanceType::ChainMap => {
self.infer_type_expression(parameters);
todo_type!("typing.ChainMap alias")
}
KnownInstanceType::OrderedDict => {
self.infer_type_expression(parameters);
todo_type!("typing.OrderedDict alias")
}
KnownInstanceType::Dict => {
self.infer_type_expression(parameters);
todo_type!("typing.Dict alias")
}
KnownInstanceType::List => {
self.infer_type_expression(parameters);
todo_type!("typing.List alias")
}
KnownInstanceType::DefaultDict => {
self.infer_type_expression(parameters);
todo_type!("typing.DefaultDict[] alias")
}
KnownInstanceType::Counter => {
self.infer_type_expression(parameters);
todo_type!("typing.Counter[] alias")
}
KnownInstanceType::Set => {
self.infer_type_expression(parameters);
todo_type!("typing.Set alias")
}
KnownInstanceType::FrozenSet => {
self.infer_type_expression(parameters);
todo_type!("typing.FrozenSet alias")
}
KnownInstanceType::Deque => {
self.infer_type_expression(parameters);
todo_type!("typing.Deque alias")
}
KnownInstanceType::ReadOnly => {
self.infer_type_expression(parameters);
todo_type!("Required[] type qualifier")
}
KnownInstanceType::NotRequired => {
self.infer_type_expression(parameters);
todo_type!("NotRequired[] type qualifier")
}
KnownInstanceType::ClassVar => {
self.infer_type_expression(parameters);
todo_type!("ClassVar[] type qualifier")
}
KnownInstanceType::Final => {
self.infer_type_expression(parameters);
todo_type!("Final[] type qualifier")
}
KnownInstanceType::Required => {
self.infer_type_expression(parameters);
todo_type!("Required[] type qualifier")
}
KnownInstanceType::TypeIs => {
self.infer_type_expression(parameters);
todo_type!("TypeIs[] special form")
}
KnownInstanceType::TypeGuard => {
self.infer_type_expression(parameters);
todo_type!("TypeGuard[] special form")
}
KnownInstanceType::Concatenate => {
self.infer_type_expression(parameters);
todo_type!("Concatenate[] special form")
}
KnownInstanceType::Unpack => {
self.infer_type_expression(parameters);
todo_type!("Unpack[] special form")
}
KnownInstanceType::NoReturn | KnownInstanceType::Never | KnownInstanceType::Any => {
self.diagnostics.add_lint(
&INVALID_TYPE_PARAMETER,
subscript.into(),
@ -4850,6 +4930,17 @@ impl<'db> TypeInferenceBuilder<'db> {
);
Type::Unknown
}
KnownInstanceType::TypingSelf | KnownInstanceType::TypeAlias => {
self.diagnostics.add_lint(
&INVALID_TYPE_PARAMETER,
subscript.into(),
format_args!(
"Special form `{}` expected no type parameter",
known_instance.repr(self.db)
),
);
Type::Unknown
}
KnownInstanceType::LiteralString => {
self.diagnostics.add_lint(
&INVALID_TYPE_PARAMETER,
@ -4863,17 +4954,6 @@ impl<'db> TypeInferenceBuilder<'db> {
}
KnownInstanceType::Type => self.infer_subclass_of_type_expression(parameters),
KnownInstanceType::Tuple => self.infer_tuple_type_expression(parameters),
KnownInstanceType::Any => {
self.diagnostics.add_lint(
&INVALID_TYPE_PARAMETER,
subscript.into(),
format_args!(
"Type `{}` expected no type parameter",
known_instance.repr(self.db)
),
);
Type::Unknown
}
}
}

View file

@ -4,7 +4,7 @@ use std::ops::Deref;
use itertools::Either;
use rustc_hash::FxHashSet;
use super::{Class, ClassLiteralType, KnownClass, KnownInstanceType, TodoType, Type};
use super::{todo_type, Class, ClassLiteralType, KnownClass, KnownInstanceType, TodoType, Type};
use crate::Db;
/// The inferred method resolution order of a given class.
@ -362,15 +362,47 @@ impl<'db> ClassBase<'db> {
| KnownInstanceType::Union
| KnownInstanceType::NoReturn
| KnownInstanceType::Never
| KnownInstanceType::Final
| KnownInstanceType::NotRequired
| KnownInstanceType::TypeGuard
| KnownInstanceType::TypeIs
| KnownInstanceType::TypingSelf
| KnownInstanceType::Unpack
| KnownInstanceType::ClassVar
| KnownInstanceType::Concatenate
| KnownInstanceType::Required
| KnownInstanceType::TypeAlias
| KnownInstanceType::ReadOnly
| KnownInstanceType::Optional => None,
KnownInstanceType::Any => Some(Self::Any),
// TODO: Classes inheriting from `typing.Type` et al. also have `Generic` in their MRO
KnownInstanceType::Dict => {
ClassBase::try_from_ty(db, KnownClass::Dict.to_class_literal(db))
}
KnownInstanceType::List => {
ClassBase::try_from_ty(db, KnownClass::List.to_class_literal(db))
}
KnownInstanceType::Type => {
ClassBase::try_from_ty(db, KnownClass::Type.to_class_literal(db))
}
KnownInstanceType::Tuple => {
ClassBase::try_from_ty(db, KnownClass::Tuple.to_class_literal(db))
}
KnownInstanceType::Set => {
ClassBase::try_from_ty(db, KnownClass::Set.to_class_literal(db))
}
KnownInstanceType::FrozenSet => {
ClassBase::try_from_ty(db, KnownClass::FrozenSet.to_class_literal(db))
}
KnownInstanceType::Callable
| KnownInstanceType::ChainMap
| KnownInstanceType::Counter
| KnownInstanceType::DefaultDict
| KnownInstanceType::Deque
| KnownInstanceType::OrderedDict => Self::try_from_ty(
db,
todo_type!("Support for more typing aliases as base classes"),
),
},
}
}