from typing import TypeVar
from mypy.types import NoneType
FloatOrNone = TypeVar("FloatOrNone", float, NoneType)
def test_none_type(val: FloatOrNone) -> FloatOrNone:
if val is None:
reveal_type(val)
# Doesn't even get checked
return val
reveal_type(val)
# Normally I would do something with a `float` value here
# Revealed type is 'mypy.types.NoneType*'
# Revealed type is 'builtins.float*'
return val
1.0 > test_none_type(None)
1.0 > test_none_type(0.5)
some_path/some_file.py: note: In function "test_none_type":
some_path/some_file.py:20: note: Revealed type is 'builtins.float*'
some_path/some_file.py:20: note: Revealed type is 'mypy.types.NoneType*'
some_path/some_file.py: note: At top level:
some_path/some_file.py:28: error: Value of type variable "FloatOrNone" of "test_none_type" cannot be "None" [type-var]
some_path/some_file.py:28: error: Unsupported operand types for > ("float" and "None") [operator]
You can see:
The check for val is None
didn't properly filter for None
.
reveal_type
didn't work in the is None
check
There is a mistaken type-var
error in the 2nd to last line
Repro with "None"
Success
from typing import TypeVar
FloatOrNone = TypeVar("FloatOrNone", float, "None")
def test_none_type(val: FloatOrNone) -> FloatOrNone:
if val is None:
reveal_type(val)
# Revealed type is 'None'
return val
reveal_type(val)
# Normally I would do something with a `float` value here
# Revealed type is 'builtins.float*'
return val
1.0 > test_none_type(None)
1.0 > test_none_type(0.5)
And the mypy output:
some_path/some_file.py: note: In function "test_none_type":
some_path/some_file.py: note: Revealed type is 'None'
some_path/some_file.py: note: Revealed type is 'builtins.float*'
some_path/some_file.py: note: At top level:
some_path/some_file.py: error: Unsupported operand types for > ("float" and "None") [operator]
Works as expected.
Versions
mypy==0.770
python==3.6.5
No there isn't documentation from what I had seen, I just came across it once in the source. Based on its docstring, I thought it was useful (turns out I was wrong).
Before this ticket disappears for all time, I would like to sneak in one question: is there a difference between "None"
and None
when entered as a value restriction in TypeVar
?
Why do I ask? My IDE (PyCharm, PE version 2020.1) complains about using a raw None
, saying Expected type 'Union[type, str]', got 'None' instead
. If there's no difference between None
and "None"
w.r.t. mypy, I will continue using "None"
.