how to correctly create a dict subclass with typing #1033
-
we have a lot of classes that subclass I'm not able to create a custom subclass of Currently, trying to figure out the What's the correct return type for example below # Module "builtins" has no attribute "dict_values"
from builtins import dict_values # type: ignore
import time
from typing import Any
from typing import cast
from typing import Dict, List
from typing import Tuple
from typing import TypeVar
from typing import ValuesView
_KT = TypeVar("_KT", bound=Any)
_VT = TypeVar("_VT", bound=Any)
class MyDict(Dict[_KT, _VT]):
"""a dictionary that stores values as a two-tuple with a timestamp.
the exposed values however are those that were originally passed in.
"""
def __getitem__(self, __k: _KT) -> _VT:
super_dict = cast(Dict[_KT, Tuple[_VT, float]], super())
try:
value = super_dict.__getitem__(__k)
except KeyError:
raise
else:
return value[0]
def __setitem__(self, __k: _KT, v: _VT) -> None:
super_dict = cast(Dict[_KT, Tuple[_VT, float]], super())
return super_dict.__setitem__(__k, (v, time.time()))
# values like a normal person - return a list
# Return type "List[_VT]" of "values" incompatible with return type "dict_values[_KT, _VT]" in supertype "dict"
# Return type "List[_VT]" of "values" incompatible with return type "ValuesView[_VT]" in supertype "Mapping"
# def values(self) -> List[_VT]:
# super_dict = cast(Dict[_KT, Tuple[_VT, float]], super())
# return [v[0] for k, v in super_dict.items()]
# try to use real ValuesView
# Return type "ValuesView[_VT]" of "values" incompatible with return type "dict_values[_KT, _VT]" in supertype "dict"
# def values(self) -> ValuesView[_VT]:
# super_dict = cast(Dict[_KT, Tuple[_VT, float]], super())
# return ValuesView({k: v[0] for k, v in super_dict.items()})
# try to use the dict_values mypy is claiming -
# not possible, because we cannot import private dict_values
def values(self) -> dict_values[_KT, _VT]:
super_dict = cast(Dict[_KT, Tuple[_VT, float]], super())
return ValuesView({k: v[0] for k, v in super_dict.items()})
md: MyDict[str, str] = MyDict()
# fails, revealed type is Any, because we had to ignore type
# on dict_values
reveal_type(md.values()) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 9 replies
-
Yeah this was broken in 3.10, see here: https://bugs.python.org/issue46399 We're trying to figure out some solutions! |
Beta Was this translation helpful? Give feedback.
-
i know this is a different question but similar area, what's the correct typing for setdefault()? if I have a dict[str, str], how is the None value implied by setdefault accommodated? import typing
from typing import Dict
x: Dict[str, str] = {"a": "b"}
# we would think typing would raise an error for this
q = x.setdefault("c")
if typing.TYPE_CHECKING:
# Revealed type is "builtins.str*"
reveal_type(q)
# which is wrong. it's None
assert q is not None |
Beta Was this translation helpful? Give feedback.
Yeah this was broken in 3.10, see here: https://bugs.python.org/issue46399
We're trying to figure out some solutions!