Skip to content

Infer type in conditional block after (un-)successful == comparison #3964

@FichteFoll

Description

@FichteFoll

Basically the same issue as #1825 but more general.

from typing import Union


def f(a: Union[str, int]):
    if a == 'a':
        reveal_type(a)  # expect str
        str.lower(a)
test.py:6: error: Revealed type is 'Union[builtins.str, builtins.int]'
test.py:7: error: Argument 1 to "lower" of "str" has incompatible type "Union[str, int]"; expected "str"

This works if the conditional is extended with isinstance(a, str).

As noted in the referenced issue, attention must be paid to __eq__ being overrideable, meaning it cannot safely be inferred that the type of X in X == Type() is Type (or a subclass thereof) without looking into __eq__ overrides in both classes. I do not know how widely this is used for any types or for str, but I can say that I have never seen this myself. It seems that some types are more likely to compare equal to custom classes than others (e.g. None vs list), however.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions