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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/HLGDIWGHSIG3LDSBN7RDARK6E7VYTXQT/
Code of Conduct: http://python.org/psf/codeofconduct/