Skip to content

Type narrowing of a union type works incorrectly in presence of a list #11272

Closed
@yasinzaehringer-paradime

Description

Bug Report

Minimum example:

# Standard library modules
from typing import List, Union

Types = Union[str, List[str]]


def f(x: Types) -> None:
    if isinstance(x, str):
        reveal_type(x)
        print("a string!")
    elif isinstance(x, list):
        reveal_type(x)
        print("a list!")
    else:
        reveal_type(x)
        print("unreachable code")

The output of mypy test.py is:

test.py:9: note: Revealed type is "builtins.str"
test.py:12: note: Revealed type is "builtins.list[builtins.str]"
test.py:15: note: Revealed type is "builtins.list[builtins.str]"

The detected type for line 15 is actually incorrect, the code is (or better should be) unreachable and List[str] has already been dealt with in the second branch.

To Reproduce

  1. Save the above code to test.py
  2. Run mypy test.py

Expected Behavior

I expect that it correctly recognises the code as unreachable.

Actual Behavior

mypy thinks that the type in the branch is reachable with type List[str].

An interesting variation of the above is using Types = Union[str, List[str], List[int]]. Then the output is:

test.py:9: note: Revealed type is "builtins.str"
test.py:12: note: Revealed type is "Union[builtins.list[builtins.str], builtins.list[builtins.int]]"
test.py:15: note: Revealed type is "<nothing>"

which is correct.

Your Environment

  • Mypy version used: mypy 0.910
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: Python 3.9.7
  • Operating system and version: MacOS 11.5.2

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