Considering this example
from typing import TypeVar
_K = TypeVar("_K")
_V = TypeVar("_V")
class D(dict[_K, _V]):
...
reveal_type(D.fromkeys(range(1)))
Both mypy and pyright think that the type is builtins.dict
, not D
. Moreover, defaultdict.fromkeys
is not present in typeshed, so result type is also builtins.dict
, but not for other dict-like types in collections
.
This works like that because there is no way to annotate dict.fromkeys
to return actual type of first argument instead of dict
. So, my question is why we can not subscribe TypeVar
, so we can annotate such cases as
_Self = TypeVar("_Self", bound="dict") # or typing.Self
class dict(Generic[_K, _V]):
def classmethod(
cls: type[_Self],
iterable: Iterable[_TK],
value: _TV
) -> _Self[_TK, _TV]: ...
My use-case does not involve dicts, so it is general typing question. My case can be simplifyed to example from Descriptors HowTo
class Field(Generic[T_get, T_set]):
def __init__(self, converter=None):
self.private_name = None
self.converter = converter
def __set_name__(self, owner, name):
self.private_name = '_' + name
def __get__(self, obj, objtype=None) -> T_get:
result = getattr(obj, self.private_name)
if self.converter is not None:
result = self.converter(result)
return result
def __set__(self, obj, value: T_set):
self.validate(value)
setattr(obj, self.private_name, value)
@abstractmethod
def validate(self, value):
pass
def with_coverter(
self: Self, converter: Callable[[T_set], T_get]
) -> Self[T_get, T_set]:
result = copy.copy(self)
result.converter = converter
return result
Right now if I want to have correct return type of with_coverter
in subclasses I need to add correct signature with return super
.