添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
开朗的胡萝卜  ·  QPainter::setBrush: ...·  2 周前    · 
善良的高山  ·  kubectl diff requires ...·  3 月前    · 
干练的硬币  ·  Goku grosero - ...·  3 月前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I am reporting what I believe is a bug, where mypy.types.NoneType doesn't work, where "None" does, when filtering for None using a check similar to obj is None .

Also, reveal_type doesn't work in is None checks with NoneType being used.

What do I expect? I expect NoneType to equal "None" . Please see the below code samples to better explain.

Repro With Potential NoneType Bug

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)

And the mypy output:

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".