On Fri, Oct 15, 2021 at 06:17:12PM +0200, Sebastian M. Ernst wrote: > Data = Dict[str, Number] > > @typechecked > def foo(bar: Data): > print(bar) > ``` > > Yes, this is using run-time checks (typeguard), which works just fine. > Only strings as keys and Number objects as values are going through. (I > was told that MyPy does not get this at the moment.)
Be careful about believing what you are told. [steve ~]$ cat test.py from numbers import Number from typing import Dict Data = Dict[str, Number] a: Data = {None: []} [steve ~]$ mypy test.py test.py:4: error: Dict entry 0 has incompatible type "None": "List[<nothing>]"; expected "str": "Number" Found 1 error in 1 file (checked 1 source file) > The issue is that `bar` itself still allows "everything" to go in (and out): > > ```python > @typechecked > def foo2(bar: Data): > bar[1.0] = b'should not be allowed' > ``` The Python interpreter intentionally doesn't know or care about typing annotations. The interpreter should absolutely allow that. However mypy correctly flags that assignment as a type error. How about typeguard? That's for the typeguard developers to answer, but my guess is that they will say that the typechecked decorator can enforce type checking of the input parameters and perhaps even the return result, but there is nothing they can do about what happens inside the body of the function. > PEP 589 introduces typed dictionaries, but for a fixed set of predefined > keys (similar to struct-like constructs in other languages). In > contrast, I am looking for an arbitrary number of typed keys/value pairs. Something like this? from numbers import Number from collections import UserDict class RestrictedDict(UserDict): def __setitem__(self, key, value): if not isinstance(key, str): raise TypeError('key must be a string') if not isinstance(value, Number): raise TypeError('value must be a number') super().__setitem__(key, value) (I think that is the only method that needs to be overloaded.) -- Steve _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HLGDIWGHSIG3LDSBN7RDARK6E7VYTXQT/ Code of Conduct: http://python.org/psf/codeofconduct/