> On 16 Oct 2021, at 06:13, Steven D'Aprano <st...@pearwood.info> wrote:
> Be careful about believing what you are told.

Indeed, MyPy will correctly raise errors if you assign {None: []} to a variable 
annotated with dict[str, Number]. However, you'll find that MyPy also raises an 
error if you assign {'foo': 4} to a variable annotated with dict[str, Number]:

https://mypy-play.net/?mypy=latest&python=3.10&gist=de7faea3b4d6a0ffefc64acf3bfa7b77

The issue isn't a matter of false negatives from Mypy; it's a matter of false 
positives. For more, see the (rather long — sorry!) answer I gave Sebastian to 
a previous question of his on Stack Overflow:

https://stackoverflow.com/questions/69334475/how-to-hint-at-number-types-i-e-subclasses-of-number-not-numbers-themselv/69383462#69383462

Having said that, I absolutely agree that type-hinting doesn't seem to have 
much to do with this specific problem, and that a UserDict subclass is probably 
the way to go here.

Best,
Alex 

> On 16 Oct 2021, at 06:13, Steven D'Aprano <st...@pearwood.info> wrote:
> 
> 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/
_______________________________________________
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/NJQD6TKI5EIWBIAFKOL5L7SNHJX2KK7A/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to