mirror of
https://github.com/astral-sh/ruff.git
synced 2025-12-15 22:14:44 +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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue