pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.24k stars 1.12k forks source link

Weird redefined-variable-type warning for IntEnum #8955

Open EugeneZelenko opened 1 year ago

EugeneZelenko commented 1 year ago

Bug description

redefined-variable-type shows weir warning for enum.IntEnum:

import enum

class Transition(enum.IntEnum):
    ONE_ONE     = 1
    ONE_TWO     = 2
    ONE_THREE   = 3
    TWO_TWO     = 4
    TWO_THREE   = 5
    THREE_THREE = 6

class State(enum.IntEnum):
    ONE   = 1
    TWO   = 2
    THREE = 3

state1 = State.ONE
state2 = State.ONE
transition = None
if state1 == State.ONE:
    if state2 == State.ONE:
        transition = Transition.ONE_ONE
    elif state2 == State.TWO:
        transition = Transition.ONE_TWO
    elif state2 == State.THREE:
        transition = Transition.ONE_THREE
    else:
        pass
elif state1 == State.TWO:
    if state2 == State.ONE:
        transition = Transition.ONE_TWO  # [redefined-variable-type]
    elif state2 == State.TWO:
        transition = Transition.TWO_TWO
    elif state2 == State.THREE:
        transition = Transition.TWO_THREE
    else:
        pass

Command used

pylint --load-plugins=pylint.extensions.redefined_variable_type --enable=all pylint_test.py

Pylint output

************* Module pylint_test
pylint_test.py:1:0: C0114: Missing module docstring (missing-module-docstring)
pylint_test.py:3:0: C0115: Missing class docstring (missing-class-docstring)
pylint_test.py:11:0: C0115: Missing class docstring (missing-class-docstring)
pylint_test.py:18:0: C0103: Constant name "transition" doesn't conform to UPPER_CASE naming style (invalid-name)
pylint_test.py:30:8: R0204: Redefinition of transition type from test.Transition.ONE_THREE to pylint_test.Transition.ONE_TWO (redefined-variable-type)

-------------------------------------------------------------------
Your code has been rated at 8.39/10 (previous run: 10.00/10, -1.61)

Expected behavior

If check meant redefinition from None to Transition, such warnings should be shown for every assignment. If not, warning should not be there.

Pylint version

pylint 2.17.4
astroid 2.15.5
Python 3.11.4 (main, Jun 26 2023, 16:57:25) [GCC 7.5.0]
Pierre-Sassoulas commented 1 year ago

Thank you for opening the issue, it's still happening on main.

hofrob commented 10 months ago

Another example using StrEnum:

import enum

class Foo(enum.StrEnum):
    ABC = enum.auto()
    DEF = enum.auto()

bar = Foo.ABC
bar = Foo.DEF

results in:

R0204: Redefinition of bar type from Foo.ABC to Foo.DEF (redefined-variable-type)

Looks like pylint assumes that the type is Foo.ABC instead of just Foo. Sometimes it will assume str instead of the StrEnum type. Annotations don't help here.

import enum

class Foo(enum.StrEnum):
    ABC = enum.auto()
    DEF = enum.auto()

def return_enum():
    return Foo("DEF")

bar = Foo.ABC
if True:
    bar = return_enum()

results in:

R0204: Redefinition of bar type from Foo.ABC to str (redefined-variable-type)
hasselmm commented 9 months ago

Thank you for reporting this, I am also running into this issue.