I have some classes that use generic types by inheriting from typing.Generic. In methods of these classes, the self parameter retains the generic type of the object; for example, in iter_1() below, the type of self is inferred as OuterBase[InnerBaseT].
How can I specify this type manually for a function parameter? I want to provide the parameter's type as OuterBaseT along with its generic type InnerBaseT. The reason I want to do this is so that in iter_2() below, the type of item in the scope of the for loop will not be Any, but InnerBaseT, or whatever custom TypeVar that I provide. (I know I can simply add a line item: InnerBaseT above the for loop, but this feels more like a workaround than a general solution.)
I am looking for something similar to the syntax in iter_3(). However, this way seems to ignore everything except the inner-most bracketed type, and just takes that as the type of the parameter (see comments).
I have scoured the typing docs and other SO questions to no avail. Is this possible? If not, why not—would implementing it in mypy somehow have strange consequences for type inference in other scenarios?
from typing import Generic, TypeVar, List, Iterable
InnerBaseT = TypeVar('InnerBaseT', bound='InnerBase')
OuterBaseT = TypeVar('OuterBaseT', bound='OuterBase')
class InnerBase: pass
class InnerDerived1(InnerBase): pass
class InnerDerived2(InnerBase): pass
class OuterBase(Generic[InnerBaseT]):
def __init__(self):
self.items: List[InnerBaseT] = []
def iter_1(self) -> Iterable:
# Type of `self` is shown as `OuterBase[InnerBaseT]` (PyCharm with mypy=0.971, see screenshot)
for item in self.items:
# Type of `item` is correctly `InnerBaseT`
yield item
def iter_2(self) -> Iterable:
def helper(outer_base: OuterBaseT) -> Iterable:
for item in outer_base.items:
# Type of `item` here is `Any`
yield item
yield from helper(self)
def iter_3(self) -> Iterable:
def helper(outer_base: OuterBaseT[InnerBaseT]) -> Iterable:
# Type of `outer_base` is `InnerBaseT` (strange)
for item in outer_base.items:
yield item
yield from helper(self) # "Expected type 'InnerBaseT', got 'OuterBase[InnerBaseT]' instead"
Hovering over self (PyCharm with mypy=0.971) shows that the inferred type shows its corresponding generic TypeVar, which is basically what I want to manually specify:

Thanks in advance for any ideas.