Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,24 @@ import typing

####################
### Built-ins
####################

class ListSubclass(typing.List): ...

# revealed: tuple[Literal[ListSubclass], Literal[list], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(protocol), Literal[object]]
# TODO: generic protocols
# revealed: tuple[Literal[ListSubclass], Literal[list], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(ListSubclass.__mro__)

class DictSubclass(typing.Dict): ...

# TODO: should have `Generic`, should not have `Unknown`
# revealed: tuple[Literal[DictSubclass], Literal[dict], Unknown, Literal[object]]
# TODO: generic protocols
# revealed: tuple[Literal[DictSubclass], Literal[dict], Literal[MutableMapping], Literal[Mapping], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(DictSubclass.__mro__)

class SetSubclass(typing.Set): ...

# revealed: tuple[Literal[SetSubclass], Literal[set], Literal[MutableSet], Literal[AbstractSet], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(protocol), Literal[object]]
# TODO: generic protocols
# revealed: tuple[Literal[SetSubclass], Literal[set], Literal[MutableSet], Literal[AbstractSet], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(SetSubclass.__mro__)

class FrozenSetSubclass(typing.FrozenSet): ...
Expand All @@ -92,11 +95,12 @@ reveal_type(FrozenSetSubclass.__mro__)

####################
### `collections`
####################

class ChainMapSubclass(typing.ChainMap): ...

# TODO: Should be (ChainMapSubclass, ChainMap, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
# revealed: tuple[Literal[ChainMapSubclass], Literal[ChainMap], Unknown, Literal[object]]
# TODO: generic protocols
# revealed: tuple[Literal[ChainMapSubclass], Literal[ChainMap], Literal[MutableMapping], Literal[Mapping], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(ChainMapSubclass.__mro__)

class CounterSubclass(typing.Counter): ...
Expand All @@ -113,7 +117,8 @@ reveal_type(DefaultDictSubclass.__mro__)

class DequeSubclass(typing.Deque): ...

# revealed: tuple[Literal[DequeSubclass], Literal[deque], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(protocol), Literal[object]]
# TODO: generic protocols
# revealed: tuple[Literal[DequeSubclass], Literal[deque], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(DequeSubclass.__mro__)

class OrderedDictSubclass(typing.OrderedDict): ...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ class Foo:
One thing that is supported is error messages for using special forms in type expressions.

```py
from typing_extensions import Unpack, TypeGuard, TypeIs, Concatenate, ParamSpec
from typing_extensions import Unpack, TypeGuard, TypeIs, Concatenate, ParamSpec, Generic

def _(
a: Unpack, # error: [invalid-type-form] "`typing.Unpack` requires exactly one argument when used in a type expression"
b: TypeGuard, # error: [invalid-type-form] "`typing.TypeGuard` requires exactly one argument when used in a type expression"
c: TypeIs, # error: [invalid-type-form] "`typing.TypeIs` requires exactly one argument when used in a type expression"
d: Concatenate, # error: [invalid-type-form] "`typing.Concatenate` requires at least two arguments when used in a type expression"
e: ParamSpec,
f: Generic, # error: [invalid-type-form] "`typing.Generic` is not allowed in type expressions"
) -> None:
reveal_type(a) # revealed: Unknown
reveal_type(b) # revealed: Unknown
Expand All @@ -65,14 +66,15 @@ 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
from typing_extensions import Self, Unpack, TypeGuard, TypeIs, Concatenate, Generic

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): ...
class G(Generic): ... # error: [invalid-base] "Cannot inherit from plain `Generic`"

reveal_type(F.__mro__) # revealed: tuple[Literal[F], @Todo(Support for Callable as a base class), Literal[object]]
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ from typing import Generic, TypeVar

T = TypeVar("T")

# TODO: no error
# error: [invalid-base]
class C(Generic[T]): ...
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ from typing import TypeVar, Generic
T = TypeVar("T")
S = TypeVar("S")

# TODO: no error
# error: [invalid-base]
class Legacy(Generic[T]):
def m(self, x: T, y: S) -> S:
return y
Expand Down Expand Up @@ -177,8 +175,6 @@ def f(x: T) -> None:
# TODO: error
y: list[S] = []

# TODO: no error
# error: [invalid-base]
class C(Generic[T]):
# TODO: error
x: list[S] = []
Expand Down Expand Up @@ -259,8 +255,7 @@ def f[T](x: T, y: T) -> None:
class Ok[S]: ...
# TODO: error for reuse of typevar
class Bad1[T]: ...
# TODO: no non-subscriptable error, error for reuse of typevar
# error: [non-subscriptable]
# TODO: error for reuse of typevar
class Bad2(Iterable[T]): ...
```

Expand All @@ -273,8 +268,7 @@ class C[T]:
class Ok1[S]: ...
# TODO: error for reuse of typevar
class Bad1[T]: ...
# TODO: no non-subscriptable error, error for reuse of typevar
# error: [non-subscriptable]
# TODO: error for reuse of typevar
class Bad2(Iterable[T]): ...
```

Expand Down
24 changes: 8 additions & 16 deletions crates/red_knot_python_semantic/resources/mdtest/protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ from typing import Protocol

class MyProtocol(Protocol): ...

# TODO: at runtime this is `(<class '__main__.MyProtocol'>, <class 'typing.Protocol'>, <class 'typing.Generic'>, <class 'object'>)`
reveal_type(MyProtocol.__mro__) # revealed: tuple[Literal[MyProtocol], @Todo(protocol), Literal[object]]
reveal_type(MyProtocol.__mro__) # revealed: tuple[Literal[MyProtocol], typing.Protocol, typing.Generic, Literal[object]]
```

Just like for any other class base, it is an error for `Protocol` to appear multiple times in a
Expand Down Expand Up @@ -72,8 +71,7 @@ it is not sufficient for it to have `Protocol` in its MRO.
```py
class SubclassOfMyProtocol(MyProtocol): ...

# TODO
# revealed: tuple[Literal[SubclassOfMyProtocol], Literal[MyProtocol], @Todo(protocol), Literal[object]]
# revealed: tuple[Literal[SubclassOfMyProtocol], Literal[MyProtocol], typing.Protocol, typing.Generic, Literal[object]]
reveal_type(SubclassOfMyProtocol.__mro__)

# TODO: should be `Literal[False]`
Expand All @@ -94,8 +92,7 @@ class OtherProtocol(Protocol):

class ComplexInheritance(SubProtocol, OtherProtocol, Protocol): ...

# TODO
# revealed: tuple[Literal[ComplexInheritance], Literal[SubProtocol], Literal[MyProtocol], Literal[OtherProtocol], @Todo(protocol), Literal[object]]
# revealed: tuple[Literal[ComplexInheritance], Literal[SubProtocol], Literal[MyProtocol], Literal[OtherProtocol], typing.Protocol, typing.Generic, Literal[object]]
reveal_type(ComplexInheritance.__mro__)

# TODO: should be `Literal[True]`
Expand All @@ -109,15 +106,13 @@ or `TypeError` is raised at runtime when the class is created.
# TODO: should emit `[invalid-protocol]`
class Invalid(NotAProtocol, Protocol): ...

# TODO
# revealed: tuple[Literal[Invalid], Literal[NotAProtocol], @Todo(protocol), Literal[object]]
# revealed: tuple[Literal[Invalid], Literal[NotAProtocol], typing.Protocol, typing.Generic, Literal[object]]
reveal_type(Invalid.__mro__)

# TODO: should emit an `[invalid-protocol`] error
class AlsoInvalid(MyProtocol, OtherProtocol, NotAProtocol, Protocol): ...

# TODO
# revealed: tuple[Literal[AlsoInvalid], Literal[MyProtocol], Literal[OtherProtocol], Literal[NotAProtocol], @Todo(protocol), Literal[object]]
# revealed: tuple[Literal[AlsoInvalid], Literal[MyProtocol], Literal[OtherProtocol], Literal[NotAProtocol], typing.Protocol, typing.Generic, Literal[object]]
reveal_type(AlsoInvalid.__mro__)
```

Expand All @@ -135,11 +130,9 @@ T = TypeVar("T")
# type checkers.
class Fine(Protocol, object): ...

# TODO
reveal_type(Fine.__mro__) # revealed: tuple[Literal[Fine], @Todo(protocol), Literal[object]]
reveal_type(Fine.__mro__) # revealed: tuple[Literal[Fine], typing.Protocol, typing.Generic, Literal[object]]

# TODO: should not error
class StillFine(Protocol, Generic[T], object): ... # error: [invalid-base]
class StillFine(Protocol, Generic[T], object): ...
class EvenThis[T](Protocol, object): ...
```

Expand All @@ -149,8 +142,7 @@ And multiple inheritance from a mix of protocol and non-protocol classes is fine
```py
class FineAndDandy(MyProtocol, OtherProtocol, NotAProtocol): ...

# TODO
# revealed: tuple[Literal[FineAndDandy], Literal[MyProtocol], Literal[OtherProtocol], @Todo(protocol), Literal[NotAProtocol], Literal[object]]
# revealed: tuple[Literal[FineAndDandy], Literal[MyProtocol], Literal[OtherProtocol], typing.Protocol, typing.Generic, Literal[NotAProtocol], Literal[object]]
reveal_type(FineAndDandy.__mro__)
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ from typing import Tuple

class C(Tuple): ...

# revealed: tuple[Literal[C], Literal[tuple], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(protocol), Literal[object]]
# TODO: generic protocols
# revealed: tuple[Literal[C], Literal[tuple], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(C.__mro__)
```
Loading
Loading