classification
Title: Should typing.get_type_hints change None annotations?
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: eric.smith, gvanrossum, larry
Priority: low Keywords:

Created on 2021-01-10 11:29 by larry, last changed 2021-01-11 00:00 by gvanrossum.

Messages (4)
msg384760 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2021-01-10 11:29
PEP 484 says:

    (Note that the return type of __init__ ought to be annotated
     with -> None. The reason for this is subtle. [...]

    https://www.python.org/dev/peps/pep-0484/#the-meaning-of-annotations

If you follow this advice, then call typing.get_type_hints() on your __init__ function, you'll find it has turned "None" into "type(None)".

git blame suggests get_type_hints' behavior was in the initial checkin of typing.py (46dbb7d1032c19163f37785509b8f5b3004416e8).  So it's always behaved this way.

Is "None" still considered the correct return annotation of an __init__?  If so, should typing.get_type_hints() really be changing it to type(None)?
msg384768 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-01-10 16:25
Notice that this isn't just for __init__ or return types, it happens with any annotations (here, with 3.8):

>>> def g(i: None): pass
...
>>> g.__annotations__
{'i': None}
>>> get_type_hints(g)
{'i': <class 'NoneType'>}
>>>

I just noticed that PEP 484 also says:

https://www.python.org/dev/peps/pep-0484/#using-none

"When used in a type hint, the expression None is considered equivalent to type(None)."

But I find it odd that get_type_hints would make this determination for you.
msg384769 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-01-10 16:32
See also https://github.com/python/mypy/issues/640 "Support type(None) as a type", which was closed with "I don't think anyone cares". Jukka's comment was "Or maybe we should update PEP 484 to not suggest that type(None) is valid as a type, and None is the only correct spelling? There should one -- and preferably only one -- obvious way to do it etc."

Despite the fact that I'd also like to see only one way to do things, other than tests that will break when using get_type_hints instead of looking at annotations directly, I'm not sure it makes much difference. People already need to treat type(None) as equivalent to None for annotations: we're late to the game for making a change.
msg384789 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-01-11 00:00
I agree this is a bit unfortunate, but I also think it's a bit late to change now.

However *if* we're going to change it we should do it now (in 3.10) or never. Given that we never *write* type(None) in annotations, it's unfortunate to get that back whenever we wrote None.

I personally don't care because I never use get_type_hints() -- I don't use annotations at runtime (which may also be how this snuck into  get_type_hints() in the first place -- some misguided idea that it should return a "type").
History
Date User Action Args
2021-01-11 00:00:58gvanrossumsetmessages: + msg384789
2021-01-10 16:32:35eric.smithsetmessages: + msg384769
2021-01-10 16:25:35eric.smithsetmessages: + msg384768
2021-01-10 11:29:52larrycreate