-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
TypeVar
s cannot refer to type variables
#2756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Confimed. But I'm not sure whether this is a bug or an understandable restriction on the type system. How were you intending to use Perhaps you're better off using a type alias? Those can be generic, e.g. IterA = Union[Iterator[A], Iterable[A]] (Note that when using a generic type alias, you should append a type parameter, e.g. |
I just ran into this today -- here's a stripped-down example of my use-case for this: from typing import Any, Generic, Sequence, TypeVar
T = TypeVar('T')
ST = TypeVar('ST', bound=Sequence[Any])
# want: ST = TypeVar('ST', bound=Sequence[T])
class Abstract(Generic[T, ST]):
def _helper(self) -> ST:
...
def method(self) -> ST:
return self._helper()
class Impl(Abstract[int, bytes]):
def _helper(self) -> bytes:
return b''
def dummy(x: Abstract[T, ST]) -> None:
reveal_type(x.method().__len__)
reveal_type(x.method()[0])
reveal_type(Impl().method()) The output of running mypy on this is:
Ideally, mypy would be able to infer that the sequence is of
In Java, for example, I can create this relationship by writing the template parameters as |
This is my use case for this issue (and also for #3148):
|
It might be worth explicitly stating in PEP 484 that type variables are not permitted inside |
Sure, send a PR to the peps repo. |
This doesn't seem useful enough to be worth the extra complexity, so I'm closing the issue. |
Hello, I would like to add to the discussion here. It definitely seems to be a complex issue but I think the use case is not that uncommon. In my case I am having issues with generic containers in a graph class, something like this simplified example: T = TypeVar('T')
class Node(Generic[T]):
@property
def key(self) -> T:
...
# What I can do:
class Graph(Generic[T]):
def __init__(self):
self._nodes = [] # type: List[Node[T]]
def build_edge(self, src: T, dst: T):
self._nodes.append(Node(src))
self._nodes.append(Node(dst))
# What I would like to do:
TNode = TypeVar('TNode', bound=Node[T])
class Graph(Generic[TNode]):
def __init__(self):
self._nodes = [] # type: List[TNode]
def build_edge(self, src: T, dst: T):
# Default implementation, can be overridden
# by child classes
self._nodes.append(Node(src))
self._nodes.append(Node(dst)) The second approach would allow a subclass of Graph to use an specialization of the Node class without issues. I think people will run into this issue whenever there are subclasses that utilize generics that can be specialized. Maybe it's not the most common use case, but it is a situation that works well with regular Python and where typing can help clarify a lot the code and the types that are being assumed in each function. |
I encountered exactly the same problem as @gjulianm 's. This is a quite common pattern in anything related to implementing trees and graphs of any kind (mine is a binary search tree). I don't know if there are any other ways to implement this, but please share if you know. BTW, all my attempts end up as the same error message.
|
We define a type variable
A
:The following gives the error
Invalid type A
:The text was updated successfully, but these errors were encountered: