microsoft / pyright

Static Type Checker for Python
Other
13.04k stars 1.39k forks source link

Non-overlapping equality check isn't reported for `StrEnum` #8361

Closed roman-g closed 1 month ago

roman-g commented 1 month ago

Describe the bug Pyright doesn't report non-overlapping equality check between different StrEnum-s

Code or Screenshots

import enum

class EnumOne(enum.StrEnum):
    A = "A"

class EnumTwo(enum.StrEnum):
    C = "C"

def x() -> EnumOne:
    return EnumOne.A

if x() == EnumTwo.C:  
    pass

[reportUnnecessaryComparison] isn't triggered for the condition in if, whereas mypy reports it as error: Non-overlapping equality check (left operand type: "EnumOne", right operand type: "Literal[EnumTwo.C]") [comparison-overlap]

VS Code extension or command-line 1.1.370

erictraut commented 1 month ago

Pyright is working as designed here, so I don't consider this a bug.

In Python, any class can override __eq__. Pyright's reportUnnecessaryComparison check needs to be conservative about what it considers an "unnecessary" comparison. If it sees that the class overrides __eq__, it cannot make assumptions about the logic inside of that __eq__ override. In your code sample, the StrEnum class inherits from str which has an __eq__ override.

You can read more about the design for the reportUnnecessaryComparison check here where it was first proposed.

roman-g commented 1 month ago

@erictraut Thanks, I see your point.

While it definitely makes sense, and I also remember that Pyright tries not to rely on manual handling of known behavior of certain classes and methods, I must admit that in this case it leads to letting prominent errors go through.

Enums are widely used across our (and I believe others') codebases, and sometimes it's quite possible to accidentally use an incorrect but somewhat similar enum in such comparisons, which could have been prevented by a type checker.