Skip to content

Comparison with Literal int, Literal Enum and frozenset occupancy constrains value differently and sometimes incorrectly #8641

@alwaysmpe

Description

@alwaysmpe

Describe the bug

I have an integer enum and a set of those enum values. Depending on how a value is compared to the enum and how constructs are typed I get inconsistent behaviour.

  • If I do a direct comparison with the enum value in a branch, pyright is able to correctly deduce that the value in the branch is constrained to the enum, however doesn't then raise an unnecessary comparison error if a second comparison is done with the underlying value.
  • If I have a frozenset of values typed as containing the enum type but not literal values, it is constrained to that type and further comparisons to specific values do not raise an error.
  • If I have a frozenset typed as containing literal values, further comparisons to one of the constrained literal values raises an unnecessary comparison error.

Code or Screenshots

from enum import Enum
from typing import Literal

class IntVal(int, Enum):
    one = 1
    two = 2
    three = 3

type OneTwo = Literal[
    IntVal.one,
    IntVal.two,
]

one_two_set: frozenset[OneTwo] = frozenset({
    IntVal.one,
    IntVal.two,
})

int_val_set: frozenset[IntVal] = frozenset({
    IntVal.one,
    IntVal.two,
})

def foo(t: int):
    if t == IntVal.one:
        # The below does not report an unnecessary comparison but perhaps should
        if t == 1:
            pass
    if t in one_two_set:
        if t == IntVal.one:
            # The below reports an unnecessary comparison, incorrectly claiming it will never be true
            if t == 1:
                pass
    if t in int_val_set:
        # The below does not report an unnecessary comparison, unlike the above branch
        if t == 1:
            pass

The message I get:

Condition will always evaluate to False since the types "Literal[IntVal.one, IntVal.two]" and "Literal[1]" have no overlap (reportUnnecessaryComparison)

VS Code extension or command-line

pylance, pyright cli and playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    addressed in next versionIssue is fixed and will appear in next published versionbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions