-
Consider a generic tree and a transform class (produces some result after visiting every node). class Tree(Generic[_Child_T]):
children: List[Union[Tree[_Child_T], _Child_T]]
class Transformer(Generic[_Child_T, _Return_T]):
def transform(self, tree: Tree[_Child_T]) -> _Return_T:
... Note that class Transformer(Generic[_Child_T, _Return_T]):
def transform(self, tree: Tree[_Child_T]) -> _Return_T:
...
def chain(self, other: Transformer[_Child_U, _Return_V]) -> Transformer[_Child_T, _Return_V]:
... The catch here is that this will only work when |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
What happens at runtime when |
Beta Was this translation helpful? Give feedback.
-
Thanks to @sobolevn's comment, I was able to come up with the answer I was looking for. The key is to annotate the from typing import Generic, List, TypeVar, Union
_Child_T = TypeVar("_Child_T")
_Child_U = TypeVar("_Child_U")
_Return_T = TypeVar("_Return_T")
_Return_V = TypeVar("_Return_V")
class Tree(Generic[_Child_T]):
children: "List[Union[Tree[_Child_T], _Child_T]]"
class Transformer(Generic[_Child_T, _Return_T]):
def transform(self, tree: Tree[_Child_T]) -> _Return_T:
pass
def chain(
self: "Transformer[_Child_T, Tree[_Child_U]]",
other: "Transformer[_Child_U, _Return_V]"
) -> "Transformer[_Child_T, _Return_V]":
pass
tree_str_to_int: Transformer[str, int] = Transformer()
tree_str_to_tree_int: Transformer[str, Tree[int]] = Transformer()
tree_str_to_str: Transformer[str, str] = Transformer()
tree_int_to_str: Transformer[int, str] = Transformer()
tree_str_to_int.chain(tree_str_to_int)
tree_str_to_tree_int.chain(tree_str_to_str)
tree_str_to_tree_int.chain(tree_int_to_str) When checked with $ mypy --version
mypy 0.910
$ mypy typing_example.py
typing_example.py:29: error: Invalid self argument "Transformer[str, int]" to attribute function "chain" with type "Callable[[Transformer[_Child_T, Tree[_Child_U]], Transformer[_Child_U, _Return_V]], Transformer[_Child_T, _Return_V]]"
typing_example.py:29: error: Argument 1 to "chain" of "Transformer" has incompatible type "Transformer[str, int]"; expected "Transformer[<nothing>, int]"
typing_example.py:30: error: Argument 1 to "chain" of "Transformer" has incompatible type "Transformer[str, str]"; expected "Transformer[int, str]"
Found 3 errors in 1 file (checked 1 source file)
|
Beta Was this translation helpful? Give feedback.
Thanks to @sobolevn's comment, I was able to come up with the answer I was looking for. The key is to annotate the
self
argument to thechain()
method, despite that rarely being necessary. The following code say that for a call tochain()
to be valid_Return_T == Tree[_Child_U]
, but does not require that allTransformer
s produce aTree
.