KEMBAR78
Strict optional: Any narrowing to None in a conditional gets "stuck" at None · Issue #3338 · python/mypy · GitHub
Skip to content

Strict optional: Any narrowing to None in a conditional gets "stuck" at None #3338

@lincolnq

Description

@lincolnq

I think a code sample will explain:

from typing import Any, Optional

def narrow_any_to_none() -> None:
    """Broken case: If 'v' starts with type Any, then it gets "stuck" with type
    None after the if."""
    v = 1 # type: Any

    if v is None:
        reveal_type(v) # E: Revealed type is 'builtins.None'
        v = 2
        reveal_type(v) # E: Revealed type is 'builtins.None'
        v + 3 # E: Unsupported operand types for + (None and "int")


def narrow_optional_to_none() -> None:
    """Working as expected: If 'v' starts with an Optional type, then you can
    re-assign it no problem after the if."""
    v = 1 # type: Optional[int]

    if v is None:
        reveal_type(v) # E: Revealed type is 'builtins.None'
        v = 2
        reveal_type(v) # E: Revealed type is 'builtins.int'
        v + 3

In v0.510 and on the latest master, mypy --strict-optional on the above code produces the above errors. I expected the 2nd reveal_type to reveal 'builtins.int' and for the v + 3 line to pass type checking. (Without strict optional, everything works as expected.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions