Skip to content

Type narrowing discards tuple from Union[Tuple, Sequence] in conditional #13749

Closed

Description

@zigaLuksic

Bug Report

When refining an element of type Union[Tuple, Sequence] with the isinstance(x, Sequence) in a conditional, the Tuple part of the type is wrongly discarded in the branch.

To Reproduce

from typing import Sequence, Tuple, Union


def test_func(x: Union[Tuple[int], Sequence[str]]) -> str:
    if isinstance(x, Sequence):
        reveal_type(x)  # Revealed type is "typing.Sequence[builtins.str]"
        return x[0]  # raises no error
    return "a"  # Statement is unreachable

Expected Behavior

The revealed type of x should be Union[Tuple[int], Sequence[str]] or something equivalent. The line return x[0] should be marked as an issue, because currently test_func((1,)) returns 1 so the functions shouldn't typecheck.

Actual Behavior

test.py:6:21: note: Revealed type is "typing.Sequence[builtins.str]"
test.py:8:5: error: Statement is unreachable  [unreachable]
Found 1 error in 1 file (checked 1 source file)

Your Environment

Used a fresh virtual environment

  • Mypy version used: 0.971
  • Python version used: 3.8

Activity

  1. brianschubert commented on Dec 7, 2024

    @brianschubert
    Collaborator

    This was fixed in #16470, released with v1.8.0. Mypy now correctly infers a union type inside the if branch:

    from typing import Sequence, Tuple, Union
    
    def test_func(x: Union[Tuple[int], Sequence[str]]) -> str:
        if isinstance(x, Sequence):
            reveal_type(x)  # N: Revealed type is "Union[tuple[builtins.int], typing.Sequence[builtins.str]]"
            return x[0]  # E: Incompatible return value type (got "int | str", expected "str")
        return "a"  # Statement is unreachable

    Thanks for the original report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-type-narrowingConditional type narrowing / binder

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions