[ty] Include type parameters in generic callable display (#22435)
This commit is contained in:
@@ -786,17 +786,17 @@ argument:
|
||||
```py
|
||||
from typing_extensions import Self
|
||||
|
||||
reveal_type(object.__new__) # revealed: def __new__(cls) -> Self@__new__
|
||||
reveal_type(object().__new__) # revealed: def __new__(cls) -> Self@__new__
|
||||
# revealed: Overload[(cls, x: str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc = 0, /) -> Self@__new__, (cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self@__new__]
|
||||
reveal_type(object.__new__) # revealed: def __new__[Self](cls) -> Self
|
||||
reveal_type(object().__new__) # revealed: def __new__[Self](cls) -> Self
|
||||
# revealed: Overload[[Self](cls, x: str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc = 0, /) -> Self, [Self](cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self]
|
||||
reveal_type(int.__new__)
|
||||
# revealed: Overload[(cls, x: str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc = 0, /) -> Self@__new__, (cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self@__new__]
|
||||
# revealed: Overload[[Self](cls, x: str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc = 0, /) -> Self, [Self](cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self]
|
||||
reveal_type((42).__new__)
|
||||
|
||||
class X:
|
||||
def __init__(self, val: int): ...
|
||||
def make_another(self) -> Self:
|
||||
reveal_type(self.__new__) # revealed: def __new__(cls) -> Self@__new__
|
||||
reveal_type(self.__new__) # revealed: def __new__[Self](cls) -> Self
|
||||
return self.__new__(type(self))
|
||||
```
|
||||
|
||||
|
||||
@@ -1208,7 +1208,7 @@ def uses_dataclass[T](x: T) -> ChildOfParentDataclass[T]:
|
||||
# revealed: (self: ParentDataclass[Unknown], value: Unknown) -> None
|
||||
reveal_type(ParentDataclass.__init__)
|
||||
|
||||
# revealed: (self: ParentDataclass[T@ChildOfParentDataclass], value: T@ChildOfParentDataclass) -> None
|
||||
# revealed: [T](self: ParentDataclass[T], value: T) -> None
|
||||
reveal_type(ChildOfParentDataclass.__init__)
|
||||
|
||||
result_int = uses_dataclass(42)
|
||||
|
||||
@@ -817,7 +817,7 @@ class WithOverloadedMethod(Generic[T]):
|
||||
def method(self, x: S | T) -> S | T:
|
||||
return x
|
||||
|
||||
# revealed: Overload[(self, x: int) -> int, (self, x: S@method) -> S@method | int]
|
||||
# revealed: Overload[(self, x: int) -> int, [S](self, x: S) -> S | int]
|
||||
reveal_type(WithOverloadedMethod[int].method)
|
||||
```
|
||||
|
||||
|
||||
@@ -702,7 +702,7 @@ class WithOverloadedMethod[T]:
|
||||
def method[S](self, x: S | T) -> S | T:
|
||||
return x
|
||||
|
||||
# revealed: Overload[(self, x: int) -> int, (self, x: S@method) -> S@method | int]
|
||||
# revealed: Overload[(self, x: int) -> int, [S](self, x: S) -> S | int]
|
||||
reveal_type(WithOverloadedMethod[int].method)
|
||||
```
|
||||
|
||||
|
||||
@@ -867,7 +867,7 @@ class ClassWithOverloadedInit[T]:
|
||||
# overload. We would then also have to determine that R must be equal to the return type of **P's
|
||||
# solution.
|
||||
|
||||
# revealed: Overload[(x: int) -> ClassWithOverloadedInit[int], (x: str) -> ClassWithOverloadedInit[str]]
|
||||
# revealed: Overload[[T](x: int) -> ClassWithOverloadedInit[int], [T](x: str) -> ClassWithOverloadedInit[str]]
|
||||
reveal_type(into_callable(ClassWithOverloadedInit))
|
||||
# TODO: revealed: Overload[(x: int) -> ClassWithOverloadedInit[int], (x: str) -> ClassWithOverloadedInit[str]]
|
||||
# revealed: Overload[(x: int) -> ClassWithOverloadedInit[int] | ClassWithOverloadedInit[str], (x: str) -> ClassWithOverloadedInit[int] | ClassWithOverloadedInit[str]]
|
||||
@@ -888,7 +888,7 @@ class GenericClass[T]:
|
||||
def _(x: list[str]):
|
||||
# TODO: This fails because we are not propagating GenericClass's generic context into the
|
||||
# Callable that we create for it.
|
||||
# revealed: (x: list[T@GenericClass], y: list[T@GenericClass]) -> GenericClass[T@GenericClass]
|
||||
# revealed: [T](x: list[T], y: list[T]) -> GenericClass[T]
|
||||
reveal_type(into_callable(GenericClass))
|
||||
# revealed: ty_extensions.GenericContext[T@GenericClass]
|
||||
reveal_type(generic_context(into_callable(GenericClass)))
|
||||
|
||||
@@ -153,7 +153,7 @@ already solved and specialized when the class was specialized:
|
||||
from ty_extensions import generic_context
|
||||
|
||||
legacy.m("string", None) # error: [invalid-argument-type]
|
||||
reveal_type(legacy.m) # revealed: bound method Legacy[int].m[S](x: int, y: S@m) -> S@m
|
||||
reveal_type(legacy.m) # revealed: bound method Legacy[int].m[S](x: int, y: S) -> S
|
||||
# revealed: ty_extensions.GenericContext[T@Legacy]
|
||||
reveal_type(generic_context(Legacy))
|
||||
# revealed: ty_extensions.GenericContext[Self@m, S@m]
|
||||
@@ -344,4 +344,27 @@ class C[T]:
|
||||
ok2: Inner[T]
|
||||
```
|
||||
|
||||
## Mixed-scope type parameters
|
||||
|
||||
Methods can have type parameters that are scoped to the method itself, while also referring to type
|
||||
parameters from the enclosing class.
|
||||
|
||||
```py
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
from ty_extensions import into_callable
|
||||
|
||||
T = TypeVar("T")
|
||||
S = TypeVar("S")
|
||||
|
||||
class Foo(Generic[T]):
|
||||
def bar(self, x: T, y: S) -> tuple[T, S]:
|
||||
raise NotImplementedError
|
||||
|
||||
def f(x: type[Foo[T]]) -> T:
|
||||
# revealed: [S](self, x: T@f, y: S) -> tuple[T@f, S]
|
||||
reveal_type(into_callable(x.bar))
|
||||
raise NotImplementedError
|
||||
```
|
||||
|
||||
[scoping]: https://typing.python.org/en/latest/spec/generics.html#scoping-rules-for-type-variables
|
||||
|
||||
@@ -348,7 +348,7 @@ def expects_named_tuple(x: typing.NamedTuple):
|
||||
reveal_type(x) # revealed: tuple[object, ...] & NamedTupleLike
|
||||
reveal_type(x._make) # revealed: bound method type[NamedTupleLike]._make(iterable: Iterable[Any]) -> NamedTupleLike
|
||||
reveal_type(x._replace) # revealed: bound method NamedTupleLike._replace(...) -> NamedTupleLike
|
||||
# revealed: Overload[(value: tuple[object, ...], /) -> tuple[object, ...], (value: tuple[_T@__add__, ...], /) -> tuple[object, ...]]
|
||||
# revealed: Overload[(value: tuple[object, ...], /) -> tuple[object, ...], [_T](value: tuple[_T, ...], /) -> tuple[object, ...]]
|
||||
reveal_type(x.__add__)
|
||||
reveal_type(x.__iter__) # revealed: bound method tuple[object, ...].__iter__() -> Iterator[object]
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ def func[T](x: T) -> T: ...
|
||||
def func[T](x: T | None = None) -> T | None:
|
||||
return x
|
||||
|
||||
reveal_type(func) # revealed: Overload[() -> None, (x: T@func) -> T@func]
|
||||
reveal_type(func) # revealed: Overload[() -> None, [T](x: T) -> T]
|
||||
reveal_type(func()) # revealed: None
|
||||
reveal_type(func(1)) # revealed: Literal[1]
|
||||
reveal_type(func("")) # revealed: Literal[""]
|
||||
|
||||
@@ -11,7 +11,7 @@ def _(flag: bool) -> None:
|
||||
abs = 1
|
||||
chr: int = 1
|
||||
|
||||
reveal_type(abs) # revealed: Literal[1] | (def abs[_T](x: SupportsAbs[_T@abs], /) -> _T@abs)
|
||||
reveal_type(abs) # revealed: Literal[1] | (def abs[_T](x: SupportsAbs[_T], /) -> _T)
|
||||
reveal_type(chr) # revealed: Literal[1] | (def chr(i: SupportsIndex, /) -> str)
|
||||
```
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ info: Type variable defined here
|
||||
| ^^^^^^
|
||||
14 | return 0
|
||||
|
|
||||
info: Union variant `def f4[T](x: T@f4) -> int` is incompatible with this call site
|
||||
info: Union variant `def f4[T](x: T) -> int` is incompatible with this call site
|
||||
info: Attempted to call union type `(def f1() -> int) | (def f2(name: str) -> int) | (def f3(a: int, b: int) -> int) | ... omitted 5 union elements`
|
||||
info: rule `invalid-argument-type` is enabled by default
|
||||
|
||||
|
||||
Reference in New Issue
Block a user