Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

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

Closed
zigaLuksic opened this issue Sep 27, 2022 · 1 comment
Closed
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder

Comments

@zigaLuksic
Copy link

zigaLuksic commented Sep 27, 2022

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
@zigaLuksic zigaLuksic added the bug mypy got something wrong label Sep 27, 2022
@AlexWaygood AlexWaygood added the topic-type-narrowing Conditional type narrowing / binder label Sep 27, 2022
@brianschubert
Copy link
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
Labels
bug mypy got something wrong topic-type-narrowing Conditional type narrowing / binder
Projects
None yet
Development

No branches or pull requests

3 participants