python / python/mypy

Non-overlapping identity check when member variable mutated by function call

Open
#9,005 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

false-positive priority-1-normal topic-literal-types
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

I get the following error in a situation where I think I shouldn’t:

test.py:25: error: Non-overlapping identity check (left operand type: "Literal[MyEnum.FOO]", right operand type: "Literal[MyEnum.BAR]")

Given the following code:

import enum


@enum.unique
class MyEnum(enum.Enum):
    FOO = enum.auto()
    BAR = enum.auto()


class MyClass:
    __slots__ = (
        "_my_value",
    )

    _my_value: MyEnum

    def __init__(self) -> None:
        super().__init__()
        self._my_value = MyEnum.FOO

    def do_thing(self) -> None:
        if self._my_value is MyEnum.FOO:
            self._set_my_value_to_bar()
            # self._my_value = MyEnum.BAR
            if self._my_value is MyEnum.BAR:
                print("And yet, the value was BAR!")

    def _set_my_value_to_bar(self) -> None:
        self._my_value = MyEnum.BAR


if __name__ == "__main__":
    x = MyClass()
    x.do_thing()

If I uncomment the commented line, the error goes away. It seems that Mypy does not understand that a method call might mutate member variables of the class, obsoleting any prior checks of their values.

This is when running version 0.780 with --strict.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the report from test.py using mypy 0.780 with --strict, focusing on do_thing and _set_my_value_to_bar. Trace how the member-value check is retained across the method call; done means the later MyEnum.BAR identity check is no longer reported as non-overlapping when the call can mutate the member.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.