-
This seems kind of simple, but I haven't been able to make it work. from typing import *
T_in = TypeVar("T_in")
T_out = TypeVar("T_out")
class ValueTransformer(Generic[T_in, T_out]):
def transform(self, items: Iterable[T_in]) -> Iterator[T_out]:
raise NotImplementedError
class PairwiseTransformer(ValueTransformer[T_in, tuple[T_in, T_in]]):
def transform(self, items: Iterable[T_in]) -> Iterator[tuple[T_in, T_in]]:
iterator = iter(items)
prev = next(iterator)
for nxt in iterator:
yield prev, nxt
prev = nxt
vals: list[int] = [0, 1, 2, 3, 4]
range_pairs = PairwiseTransformer().transform(vals)
# Mypy: Need type annotation for "range_pairs" [var-annotated]
# Mypy: Argument 1 to "transform" of "PairwiseTransformer" has incompatible type "List[int]"; expected "Iterable[<nothing>]" [arg-type]
print(list(range_pairs)) # [(0, 1), (1, 2), (2, 3), (3, 4)]
reveal_type(range_pairs) # Mypy: Revealed type is "typing.Iterator[Tuple[Any, Any]]" PyCharm correctly infers the type as I tried different combinations of variance for Is this the result of something I don't understand, or is it something Mypy can't handle yet? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
In the class Here are a couple of ways to fix this:
range_pairs = PairwiseTransformer[int]().transform(vals)
class PairwiseTransformer(ValueTransformer[T_in, tuple[T_in, T_in]]):
def __init__(self, items: Iterable[T_in]):
self._items = items
def transform(self) -> Iterator[tuple[T_in, T_in]]:
iterator = iter(self._items)
prev = next(iterator)
for nxt in iterator:
yield prev, nxt
prev = nxt
vals: list[int] = [0, 1, 2, 3, 4]
range_pairs = PairwiseTransformer(vals).transform() |
Beta Was this translation helpful? Give feedback.
In the class
PairwiseTransformer
, the type variableT_in
is scoped to the class. That means it needs to be receive a type argument at the time the class is instantiated (when you callPairwiseTransformer()
). Most generic classes define a constructor that includes class-scoped type variables in one or more of its input parameter type annotations, allowing the type arguments for the class to be inferred from the arguments passed to the constructor call. In your case, however, there is no constructor defined, so the value ofT_in
goes unsolved when callingPairwiseTransformer()
. That means the type of this expressionPairwiseTransformer()
isPairwiseTransformer[Any]
, which is probably not wh…