[red-knot] Fixes to Type::to_meta_type (#14942)

This commit is contained in:
Alex Waygood
2024-12-12 19:55:11 +00:00
committed by GitHub
parent d2712c7669
commit dbc191d2d6
5 changed files with 65 additions and 18 deletions

View File

@@ -194,3 +194,26 @@ class A[T: str](metaclass=M): ...
reveal_type(A.__class__) # revealed: Literal[M]
```
## Metaclasses of metaclasses
```py
class Foo(type): ...
class Bar(type, metaclass=Foo): ...
class Baz(type, metaclass=Bar): ...
class Spam(metaclass=Baz): ...
reveal_type(Spam.__class__) # revealed: Literal[Baz]
reveal_type(Spam.__class__.__class__) # revealed: Literal[Bar]
reveal_type(Spam.__class__.__class__.__class__) # revealed: Literal[Foo]
def test(x: Spam):
reveal_type(x.__class__) # revealed: type[Spam]
reveal_type(x.__class__.__class__) # revealed: type[Baz]
reveal_type(x.__class__.__class__.__class__) # revealed: type[Bar]
reveal_type(x.__class__.__class__.__class__.__class__) # revealed: type[Foo]
reveal_type(x.__class__.__class__.__class__.__class__.__class__) # revealed: type[type]
# revealed: type[type]
reveal_type(x.__class__.__class__.__class__.__class__.__class__.__class__.__class__.__class__)
```

View File

@@ -1,4 +1,4 @@
# type[Any]
# `type[Any]`
## Simple
@@ -51,3 +51,22 @@ x: type[object] = type
x: type[object] = A
x: type[object] = A() # error: [invalid-assignment]
```
## The type of `Any` is `type[Any]`
`Any` represents an unknown set of possible runtime values. If `x` is of type `Any`, the type of
`x.__class__` is also unknown and remains dynamic, *except* that we know it must be a class object
of some kind. As such, the type of `x.__class__` is `type[Any]` rather than `Any`:
```py
from typing import Any
from does_not_exist import SomethingUnknown # error: [unresolved-import]
reveal_type(SomethingUnknown) # revealed: Unknown
def test(x: Any, y: SomethingUnknown):
reveal_type(x.__class__) # revealed: type[Any]
reveal_type(x.__class__.__class__.__class__.__class__) # revealed: type[Any]
reveal_type(y.__class__) # revealed: type[Unknown]
reveal_type(y.__class__.__class__.__class__.__class__) # revealed: type[Unknown]
```

View File

@@ -9,7 +9,7 @@ from typing import Type
class A: ...
def _(c: Type, d: Type[A], e: Type[A]):
def _(c: Type, d: Type[A]):
reveal_type(c) # revealed: type
reveal_type(d) # revealed: type[A]
c = d # fine