mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
[ty] Understand classes that inherit from subscripted Protocol[]
as generic (#17832)
This commit is contained in:
parent
2370297cde
commit
d1bb10a66b
35 changed files with 451 additions and 183 deletions
|
@ -33,7 +33,9 @@ class Shape:
|
|||
reveal_type(self) # revealed: Unknown
|
||||
return self
|
||||
|
||||
reveal_type(Shape().nested_type()) # revealed: @Todo(specialized non-generic class)
|
||||
# TODO: should be `list[Shape]`
|
||||
reveal_type(Shape().nested_type()) # revealed: list[Self]
|
||||
|
||||
reveal_type(Shape().nested_func()) # revealed: Shape
|
||||
|
||||
class Circle(Shape):
|
||||
|
|
|
@ -14,7 +14,7 @@ Ts = TypeVarTuple("Ts")
|
|||
|
||||
def append_int(*args: *Ts) -> tuple[*Ts, int]:
|
||||
# TODO: tuple[*Ts]
|
||||
reveal_type(args) # revealed: tuple
|
||||
reveal_type(args) # revealed: tuple[Unknown, ...]
|
||||
|
||||
return (*args, 1)
|
||||
|
||||
|
|
|
@ -30,24 +30,22 @@ def f(
|
|||
ordered_dict_bare: typing.OrderedDict,
|
||||
ordered_dict_parametrized: typing.OrderedDict[int, str],
|
||||
):
|
||||
# TODO: revealed: list[Unknown]
|
||||
reveal_type(list_bare) # revealed: list
|
||||
reveal_type(list_bare) # revealed: list[Unknown]
|
||||
# TODO: revealed: list[int]
|
||||
reveal_type(list_parametrized) # revealed: list
|
||||
reveal_type(list_parametrized) # revealed: list[Unknown]
|
||||
|
||||
reveal_type(dict_bare) # revealed: dict[Unknown, Unknown]
|
||||
# TODO: revealed: dict[int, str]
|
||||
reveal_type(dict_parametrized) # revealed: dict[Unknown, Unknown]
|
||||
|
||||
# TODO: revealed: set[Unknown]
|
||||
reveal_type(set_bare) # revealed: set
|
||||
reveal_type(set_bare) # revealed: set[Unknown]
|
||||
# TODO: revealed: set[int]
|
||||
reveal_type(set_parametrized) # revealed: set
|
||||
reveal_type(set_parametrized) # revealed: set[Unknown]
|
||||
|
||||
# TODO: revealed: frozenset[Unknown]
|
||||
reveal_type(frozen_set_bare) # revealed: frozenset
|
||||
reveal_type(frozen_set_bare) # revealed: frozenset[Unknown]
|
||||
# TODO: revealed: frozenset[str]
|
||||
reveal_type(frozen_set_parametrized) # revealed: frozenset
|
||||
reveal_type(frozen_set_parametrized) # revealed: frozenset[Unknown]
|
||||
|
||||
reveal_type(chain_map_bare) # revealed: ChainMap[Unknown, Unknown]
|
||||
# TODO: revealed: ChainMap[str, int]
|
||||
|
@ -61,10 +59,9 @@ def f(
|
|||
# TODO: revealed: defaultdict[str, int]
|
||||
reveal_type(default_dict_parametrized) # revealed: defaultdict[Unknown, Unknown]
|
||||
|
||||
# TODO: revealed: deque[Unknown]
|
||||
reveal_type(deque_bare) # revealed: deque
|
||||
reveal_type(deque_bare) # revealed: deque[Unknown]
|
||||
# TODO: revealed: deque[str]
|
||||
reveal_type(deque_parametrized) # revealed: deque
|
||||
reveal_type(deque_parametrized) # revealed: deque[Unknown]
|
||||
|
||||
reveal_type(ordered_dict_bare) # revealed: OrderedDict[Unknown, Unknown]
|
||||
# TODO: revealed: OrderedDict[int, str]
|
||||
|
@ -84,26 +81,23 @@ import typing
|
|||
|
||||
class ListSubclass(typing.List): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'ListSubclass'>, <class 'list'>, <class 'MutableSequence'>, <class 'Sequence'>, <class 'Reversible'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, <class 'object'>]
|
||||
# revealed: tuple[<class 'ListSubclass'>, <class 'list[Unknown]'>, <class 'MutableSequence[Unknown]'>, <class 'Sequence[Unknown]'>, <class 'Reversible[Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], <class 'object'>]
|
||||
reveal_type(ListSubclass.__mro__)
|
||||
|
||||
class DictSubclass(typing.Dict): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'DictSubclass'>, <class 'dict[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
# TODO: should not have multiple `Generic[]` elements
|
||||
# revealed: tuple[<class 'DictSubclass'>, <class 'dict[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
reveal_type(DictSubclass.__mro__)
|
||||
|
||||
class SetSubclass(typing.Set): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'SetSubclass'>, <class 'set'>, <class 'MutableSet'>, <class 'AbstractSet'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, <class 'object'>]
|
||||
# revealed: tuple[<class 'SetSubclass'>, <class 'set[Unknown]'>, <class 'MutableSet[Unknown]'>, <class 'AbstractSet[Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], <class 'object'>]
|
||||
reveal_type(SetSubclass.__mro__)
|
||||
|
||||
class FrozenSetSubclass(typing.FrozenSet): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'FrozenSetSubclass'>, <class 'frozenset'>, <class 'AbstractSet'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, <class 'object'>]
|
||||
# revealed: tuple[<class 'FrozenSetSubclass'>, <class 'frozenset[Unknown]'>, <class 'AbstractSet[Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], <class 'object'>]
|
||||
reveal_type(FrozenSetSubclass.__mro__)
|
||||
|
||||
####################
|
||||
|
@ -112,31 +106,30 @@ reveal_type(FrozenSetSubclass.__mro__)
|
|||
|
||||
class ChainMapSubclass(typing.ChainMap): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'ChainMapSubclass'>, <class 'ChainMap[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
# TODO: should not have multiple `Generic[]` elements
|
||||
# revealed: tuple[<class 'ChainMapSubclass'>, <class 'ChainMap[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
reveal_type(ChainMapSubclass.__mro__)
|
||||
|
||||
class CounterSubclass(typing.Counter): ...
|
||||
|
||||
# TODO: Should be (CounterSubclass, Counter, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
|
||||
# revealed: tuple[<class 'CounterSubclass'>, <class 'Counter[Unknown]'>, <class 'dict[Unknown, int]'>, <class 'MutableMapping[Unknown, int]'>, <class 'Mapping[Unknown, int]'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], typing.Generic[_T], <class 'object'>]
|
||||
# TODO: Should have one `Generic[]` element, not three(!)
|
||||
# revealed: tuple[<class 'CounterSubclass'>, <class 'Counter[Unknown]'>, <class 'dict[Unknown, int]'>, <class 'MutableMapping[Unknown, int]'>, <class 'Mapping[Unknown, int]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], typing.Generic[_KT, _VT_co], typing.Generic[_T], <class '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[<class 'DefaultDictSubclass'>, <class 'defaultdict[Unknown, Unknown]'>, <class 'dict[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
# TODO: Should not have multiple `Generic[]` elements
|
||||
# revealed: tuple[<class 'DefaultDictSubclass'>, <class 'defaultdict[Unknown, Unknown]'>, <class 'dict[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
reveal_type(DefaultDictSubclass.__mro__)
|
||||
|
||||
class DequeSubclass(typing.Deque): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'DequeSubclass'>, <class 'deque'>, <class 'MutableSequence'>, <class 'Sequence'>, <class 'Reversible'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, <class 'object'>]
|
||||
# revealed: tuple[<class 'DequeSubclass'>, <class 'deque[Unknown]'>, <class 'MutableSequence[Unknown]'>, <class 'Sequence[Unknown]'>, <class 'Reversible[Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], <class 'object'>]
|
||||
reveal_type(DequeSubclass.__mro__)
|
||||
|
||||
class OrderedDictSubclass(typing.OrderedDict): ...
|
||||
|
||||
# TODO: Should be (OrderedDictSubclass, OrderedDict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
|
||||
# revealed: tuple[<class 'OrderedDictSubclass'>, <class 'OrderedDict[Unknown, Unknown]'>, <class 'dict[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
# TODO: Should not have multiple `Generic[]` elements
|
||||
# revealed: tuple[<class 'OrderedDictSubclass'>, <class 'OrderedDict[Unknown, Unknown]'>, <class 'dict[Unknown, Unknown]'>, <class 'MutableMapping[Unknown, Unknown]'>, <class 'Mapping[Unknown, Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], typing.Generic[_KT, _VT_co], <class 'object'>]
|
||||
reveal_type(OrderedDictSubclass.__mro__)
|
||||
```
|
||||
|
|
|
@ -16,7 +16,7 @@ Alias: TypeAlias = int
|
|||
|
||||
def f(*args: Unpack[Ts]) -> tuple[Unpack[Ts]]:
|
||||
# TODO: should understand the annotation
|
||||
reveal_type(args) # revealed: tuple
|
||||
reveal_type(args) # revealed: tuple[Unknown, ...]
|
||||
|
||||
reveal_type(Alias) # revealed: @Todo(Support for `typing.TypeAlias`)
|
||||
|
||||
|
@ -24,7 +24,7 @@ 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
|
||||
reveal_type(args) # revealed: tuple[Unknown, ...]
|
||||
reveal_type(kwargs) # revealed: dict[str, @Todo(Support for `typing.ParamSpec`)]
|
||||
return callback(42, *args, **kwargs)
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ reveal_type(d) # revealed: tuple[tuple[str, str], tuple[int, int]]
|
|||
reveal_type(e) # revealed: @Todo(full tuple[...] support)
|
||||
reveal_type(f) # revealed: @Todo(full tuple[...] support)
|
||||
reveal_type(g) # revealed: @Todo(full tuple[...] support)
|
||||
reveal_type(h) # revealed: tuple[@Todo(specialized non-generic class), @Todo(specialized non-generic class)]
|
||||
reveal_type(h) # revealed: tuple[list[int], list[int]]
|
||||
|
||||
reveal_type(i) # revealed: tuple[str | int, str | int]
|
||||
reveal_type(j) # revealed: tuple[str | int]
|
||||
|
@ -76,7 +76,7 @@ a: tuple[()] = (1, 2)
|
|||
# error: [invalid-assignment] "Object of type `tuple[Literal["foo"]]` is not assignable to `tuple[int]`"
|
||||
b: tuple[int] = ("foo",)
|
||||
|
||||
# error: [invalid-assignment] "Object of type `tuple[list, Literal["foo"]]` is not assignable to `tuple[str | int, str]`"
|
||||
# error: [invalid-assignment] "Object of type `tuple[list[Unknown], Literal["foo"]]` is not assignable to `tuple[str | int, str]`"
|
||||
c: tuple[str | int, str] = ([], "foo")
|
||||
```
|
||||
|
||||
|
|
|
@ -1728,7 +1728,7 @@ reveal_type(False.real) # revealed: Literal[0]
|
|||
All attribute access on literal `bytes` types is currently delegated to `builtins.bytes`:
|
||||
|
||||
```py
|
||||
# revealed: bound method Literal[b"foo"].join(iterable_of_bytes: @Todo(specialized non-generic class), /) -> bytes
|
||||
# revealed: bound method Literal[b"foo"].join(iterable_of_bytes: Iterable[@Todo(Support for `typing.TypeAlias`)], /) -> bytes
|
||||
reveal_type(b"foo".join)
|
||||
# revealed: bound method Literal[b"foo"].endswith(suffix: @Todo(Support for `typing.TypeAlias`), start: SupportsIndex | None = ellipsis, end: SupportsIndex | None = ellipsis, /) -> bool
|
||||
reveal_type(b"foo".endswith)
|
||||
|
|
|
@ -79,8 +79,7 @@ lambda x=1: reveal_type(x) # revealed: Unknown | Literal[1]
|
|||
Using a variadic parameter:
|
||||
|
||||
```py
|
||||
# TODO: should be `tuple[Unknown, ...]` (needs generics)
|
||||
lambda *args: reveal_type(args) # revealed: tuple
|
||||
lambda *args: reveal_type(args) # revealed: tuple[Unknown, ...]
|
||||
```
|
||||
|
||||
Using a keyword-variadic parameter:
|
||||
|
|
|
@ -25,8 +25,8 @@ def f(a, b: int, c=1, d: int = 2, /, e=3, f: Literal[4] = 4, *args: object, g=5,
|
|||
reveal_type(f) # revealed: Literal[4]
|
||||
reveal_type(g) # revealed: Unknown | Literal[5]
|
||||
reveal_type(h) # revealed: Literal[6]
|
||||
# TODO: should be `tuple[object, ...]` (needs generics)
|
||||
reveal_type(args) # revealed: tuple
|
||||
# TODO: should be `tuple[object, ...]`
|
||||
reveal_type(args) # revealed: tuple[Unknown, ...]
|
||||
reveal_type(kwargs) # revealed: dict[str, str]
|
||||
```
|
||||
|
||||
|
@ -36,8 +36,7 @@ def f(a, b: int, c=1, d: int = 2, /, e=3, f: Literal[4] = 4, *args: object, g=5,
|
|||
|
||||
```py
|
||||
def g(*args, **kwargs):
|
||||
# TODO: should be `tuple[Unknown, ...]` (needs generics)
|
||||
reveal_type(args) # revealed: tuple
|
||||
reveal_type(args) # revealed: tuple[Unknown, ...]
|
||||
reveal_type(kwargs) # revealed: dict[str, Unknown]
|
||||
```
|
||||
|
||||
|
|
|
@ -399,7 +399,7 @@ In a specialized generic alias, the specialization is applied to the attributes
|
|||
class.
|
||||
|
||||
```py
|
||||
from typing import Generic, TypeVar
|
||||
from typing import Generic, TypeVar, Protocol
|
||||
|
||||
T = TypeVar("T")
|
||||
U = TypeVar("U")
|
||||
|
@ -425,6 +425,33 @@ reveal_type(c.y) # revealed: str
|
|||
reveal_type(c.method1()) # revealed: int
|
||||
reveal_type(c.method2()) # revealed: str
|
||||
reveal_type(c.method3()) # revealed: LinkedList[int]
|
||||
|
||||
class SomeProtocol(Protocol[T]):
|
||||
x: T
|
||||
|
||||
class Foo:
|
||||
x: int
|
||||
|
||||
class D(Generic[T, U]):
|
||||
x: T
|
||||
y: U
|
||||
|
||||
def method1(self) -> T:
|
||||
return self.x
|
||||
|
||||
def method2(self) -> U:
|
||||
return self.y
|
||||
|
||||
def method3(self) -> SomeProtocol[T]:
|
||||
return Foo()
|
||||
|
||||
d = D[int, str]()
|
||||
reveal_type(d.x) # revealed: int
|
||||
reveal_type(d.y) # revealed: str
|
||||
reveal_type(d.method1()) # revealed: int
|
||||
reveal_type(d.method2()) # revealed: str
|
||||
reveal_type(d.method3()) # revealed: SomeProtocol[int]
|
||||
reveal_type(d.method3().x) # revealed: int
|
||||
```
|
||||
|
||||
## Cyclic class definitions
|
||||
|
|
|
@ -38,6 +38,7 @@ T = TypeVar("T")
|
|||
U: TypeVar = TypeVar("U")
|
||||
|
||||
# error: [invalid-legacy-type-variable] "A legacy `typing.TypeVar` must be immediately assigned to a variable"
|
||||
# error: [invalid-type-form] "Function calls are not allowed in type expressions"
|
||||
TestList = list[TypeVar("W")]
|
||||
```
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ from typing import Generic, TypeVar
|
|||
|
||||
T = TypeVar("T")
|
||||
|
||||
# error: [invalid-generic-class] "Cannot both inherit from `Generic` and use PEP 695 type variables"
|
||||
# error: [invalid-generic-class] "Cannot both inherit from `typing.Generic` and use PEP 695 type variables"
|
||||
class BothGenericSyntaxes[U](Generic[T]): ...
|
||||
```
|
||||
|
||||
|
|
|
@ -785,7 +785,7 @@ from subexporter import *
|
|||
|
||||
# TODO: Should be `list[str]`
|
||||
# TODO: Should we avoid including `Unknown` for this case?
|
||||
reveal_type(__all__) # revealed: Unknown | list
|
||||
reveal_type(__all__) # revealed: Unknown | list[Unknown]
|
||||
|
||||
__all__.append("B")
|
||||
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
## Empty list
|
||||
|
||||
```py
|
||||
reveal_type([]) # revealed: list
|
||||
reveal_type([]) # revealed: list[Unknown]
|
||||
```
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
## Basic set
|
||||
|
||||
```py
|
||||
reveal_type({1, 2}) # revealed: set
|
||||
reveal_type({1, 2}) # revealed: set[Unknown]
|
||||
```
|
||||
|
|
|
@ -48,8 +48,8 @@ alice2 = Person2(1, "Alice")
|
|||
# TODO: should be an error
|
||||
Person2(1)
|
||||
|
||||
reveal_type(alice2.id) # revealed: @Todo(GenericAlias instance)
|
||||
reveal_type(alice2.name) # revealed: @Todo(GenericAlias instance)
|
||||
reveal_type(alice2.id) # revealed: @Todo(functional `NamedTuple` syntax)
|
||||
reveal_type(alice2.name) # revealed: @Todo(functional `NamedTuple` syntax)
|
||||
```
|
||||
|
||||
### Multiple Inheritance
|
||||
|
|
|
@ -133,11 +133,11 @@ match x:
|
|||
case "foo" | 42 | None:
|
||||
reveal_type(x) # revealed: Literal["foo", 42] | None
|
||||
case "foo" | tuple():
|
||||
reveal_type(x) # revealed: tuple
|
||||
reveal_type(x) # revealed: tuple[Unknown, ...]
|
||||
case True | False:
|
||||
reveal_type(x) # revealed: bool
|
||||
case 3.14 | 2.718 | 1.414:
|
||||
reveal_type(x) # revealed: float & ~tuple
|
||||
reveal_type(x) # revealed: float & ~tuple[Unknown, ...]
|
||||
|
||||
reveal_type(x) # revealed: object
|
||||
```
|
||||
|
@ -155,7 +155,7 @@ reveal_type(x) # revealed: object
|
|||
match x:
|
||||
case "foo" | 42 | None if reveal_type(x): # revealed: Literal["foo", 42] | None
|
||||
pass
|
||||
case "foo" | tuple() if reveal_type(x): # revealed: Literal["foo"] | tuple
|
||||
case "foo" | tuple() if reveal_type(x): # revealed: Literal["foo"] | tuple[Unknown, ...]
|
||||
pass
|
||||
case True | False if reveal_type(x): # revealed: bool
|
||||
pass
|
||||
|
|
|
@ -58,6 +58,7 @@ class Bar1(Protocol[T], Generic[T]):
|
|||
class Bar2[T](Protocol):
|
||||
x: T
|
||||
|
||||
# error: [invalid-generic-class] "Cannot both inherit from subscripted `typing.Protocol` and use PEP 695 type variables"
|
||||
class Bar3[T](Protocol[T]):
|
||||
x: T
|
||||
```
|
||||
|
@ -70,8 +71,8 @@ simultaneously:
|
|||
class DuplicateBases(Protocol, Protocol[T]):
|
||||
x: T
|
||||
|
||||
# TODO: should not have `Protocol` multiple times
|
||||
# revealed: tuple[<class 'DuplicateBases'>, typing.Protocol, @Todo(`Protocol[]` subscript), typing.Generic, <class 'object'>]
|
||||
# TODO: should not have `Protocol` or `Generic` multiple times
|
||||
# revealed: tuple[<class 'DuplicateBases[Unknown]'>, typing.Protocol, typing.Generic, typing.Protocol[T], typing.Generic[T], <class 'object'>]
|
||||
reveal_type(DuplicateBases.__mro__)
|
||||
```
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ reveal_type(__loader__) # revealed: LoaderProtocol | None
|
|||
reveal_type(__package__) # revealed: str | None
|
||||
reveal_type(__doc__) # revealed: str | None
|
||||
reveal_type(__spec__) # revealed: ModuleSpec | None
|
||||
|
||||
reveal_type(__path__) # revealed: @Todo(specialized non-generic class)
|
||||
reveal_type(__path__) # revealed: MutableSequence[str]
|
||||
|
||||
class X:
|
||||
reveal_type(__name__) # revealed: str
|
||||
|
|
|
@ -9,13 +9,13 @@ A list can be indexed into with:
|
|||
|
||||
```py
|
||||
x = [1, 2, 3]
|
||||
reveal_type(x) # revealed: list
|
||||
reveal_type(x) # revealed: list[Unknown]
|
||||
|
||||
# TODO reveal int
|
||||
reveal_type(x[0]) # revealed: Unknown
|
||||
|
||||
# TODO reveal list
|
||||
reveal_type(x[0:1]) # revealed: @Todo(specialized non-generic class)
|
||||
# TODO reveal list[int]
|
||||
reveal_type(x[0:1]) # revealed: list[Unknown]
|
||||
|
||||
# error: [call-non-callable]
|
||||
reveal_type(x["a"]) # revealed: Unknown
|
||||
|
|
|
@ -83,9 +83,8 @@ python-version = "3.9"
|
|||
```py
|
||||
class A(tuple[int, str]): ...
|
||||
|
||||
# Runtime value: `(A, tuple, object)`
|
||||
# TODO: Generics
|
||||
reveal_type(A.__mro__) # revealed: tuple[<class 'A'>, @Todo(GenericAlias instance), <class 'object'>]
|
||||
# revealed: tuple[<class 'A'>, <class 'tuple[@Todo(Generic tuple specializations), ...]'>, <class 'Sequence[@Todo(Generic tuple specializations)]'>, <class 'Reversible[@Todo(Generic tuple specializations)]'>, <class 'Collection[@Todo(Generic tuple specializations)]'>, <class 'Iterable[@Todo(Generic tuple specializations)]'>, <class 'Container[@Todo(Generic tuple specializations)]'>, typing.Protocol[_T_co], typing.Generic[_T_co], <class 'object'>]
|
||||
reveal_type(A.__mro__)
|
||||
```
|
||||
|
||||
## `typing.Tuple`
|
||||
|
@ -100,7 +99,7 @@ from typing import Any, Tuple
|
|||
class A: ...
|
||||
|
||||
def _(c: Tuple, d: Tuple[int, A], e: Tuple[Any, ...]):
|
||||
reveal_type(c) # revealed: tuple
|
||||
reveal_type(c) # revealed: tuple[Unknown, ...]
|
||||
reveal_type(d) # revealed: tuple[int, A]
|
||||
reveal_type(e) # revealed: @Todo(full tuple[...] support)
|
||||
```
|
||||
|
@ -115,7 +114,6 @@ from typing import Tuple
|
|||
|
||||
class C(Tuple): ...
|
||||
|
||||
# TODO: generic protocols
|
||||
# revealed: tuple[<class 'C'>, <class 'tuple'>, <class 'Sequence'>, <class 'Reversible'>, <class 'Collection'>, <class 'Iterable'>, <class 'Container'>, @Todo(`Protocol[]` subscript), typing.Generic, <class 'object'>]
|
||||
# revealed: tuple[<class 'C'>, <class 'tuple[Unknown, ...]'>, <class 'Sequence[Unknown]'>, <class 'Reversible[Unknown]'>, <class 'Collection[Unknown]'>, <class 'Iterable[Unknown]'>, <class 'Container[Unknown]'>, typing.Protocol[_T_co], typing.Generic[_T_co], <class 'object'>]
|
||||
reveal_type(C.__mro__)
|
||||
```
|
||||
|
|
|
@ -151,7 +151,8 @@ static_assert(not is_subtype_of(tuple[B1, B2], tuple[()]))
|
|||
static_assert(not is_subtype_of(tuple[B1, B2], tuple[A1]))
|
||||
static_assert(not is_subtype_of(tuple[B1, B2], tuple[A1, A2, Unrelated]))
|
||||
|
||||
static_assert(is_subtype_of(tuple[int], tuple))
|
||||
# TODO: should pass
|
||||
static_assert(is_subtype_of(tuple[int], tuple[object, ...])) # error: [static-assert-error]
|
||||
```
|
||||
|
||||
## Union types
|
||||
|
|
|
@ -6,14 +6,20 @@ cpython # access to field whilst being initialized, too many cycle iterations
|
|||
discord.py # some kind of hang, only when multi-threaded?
|
||||
freqtrade # hangs
|
||||
hydpy # too many iterations
|
||||
ibis # too many iterations
|
||||
jax # too many iterations
|
||||
packaging # too many iterations
|
||||
pandas # slow
|
||||
pandas-stubs # hangs/slow, or else https://github.com/salsa-rs/salsa/issues/831
|
||||
pandera # stack overflow
|
||||
pip # vendors packaging, see above
|
||||
prefect # slow
|
||||
pylint # cycle panics (self-recursive type alias)
|
||||
pyodide # too many cycle iterations
|
||||
pywin32 # bad use-def map (binding with definitely-visible unbound)
|
||||
schemathesis # https://github.com/salsa-rs/salsa/issues/831
|
||||
scikit-learn # success, but mypy-primer hangs processing the output
|
||||
setuptools # vendors packaging, see above
|
||||
spack # success, but mypy-primer hangs processing the output
|
||||
spark # too many iterations
|
||||
steam.py # hangs
|
||||
|
|
|
@ -42,13 +42,11 @@ git-revise
|
|||
graphql-core
|
||||
httpx-caching
|
||||
hydra-zen
|
||||
ibis
|
||||
ignite
|
||||
imagehash
|
||||
isort
|
||||
itsdangerous
|
||||
janus
|
||||
jax
|
||||
jinja
|
||||
koda-validate
|
||||
kopf
|
||||
|
@ -70,11 +68,9 @@ openlibrary
|
|||
operator
|
||||
optuna
|
||||
paasta
|
||||
packaging
|
||||
paroxython
|
||||
parso
|
||||
pegen
|
||||
pip
|
||||
poetry
|
||||
porcupine
|
||||
ppb-vector
|
||||
|
@ -86,7 +82,6 @@ pydantic
|
|||
pyinstrument
|
||||
pyjwt
|
||||
pylox
|
||||
pyodide
|
||||
pyp
|
||||
pyppeteer
|
||||
pytest
|
||||
|
@ -100,7 +95,6 @@ rotki
|
|||
schema_salad
|
||||
scipy
|
||||
scrapy
|
||||
setuptools
|
||||
sockeye
|
||||
speedrun.com_global_scoreboard_webapp
|
||||
sphinx
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue