Pylint: Not support subclass of Enum(enum34)

Created on 8 May 2015  路  9Comments  路  Source: PyCQA/pylint

Originally reported by: BitBucket: iceout, GitHub: @iceout?


Python-2.7.6 + enum34 (Enum backported from Python-3.4.0)

test code:

from enum import Enum


class OrderedEnum(Enum):

 def __ge__(self, other):
     if self.__class__ is other.__class__:
         return self.value >= other.value  # line 11
     return NotImplemented

def __gt__(self, other):
     if self.__class__ is other.__class__:
         return self.value > other.value
     return NotImplemented

class Color(OrderedEnum):
    red = 0
    green = 1

class People(Enum):
    jack = 0
    john = 1

print(Color.red.value)  # line 29
print(People.jack.name)

pylint -E test.py:

E: 11,19: Instance of 'OrderedEnum' has no 'value' member (no-member)
E: 16,19: Instance of 'OrderedEnum' has no 'value' member (no-member)
E: 29, 6: Instance of 'int' has no 'value' member (no-member)

bug

All 9 comments

_Original comment by_ Claudiu Popa (BitBucket: PCManticore, GitHub: @PCManticore):


Yes, this was intentional (handling subclasses for enums was a little complicated when support for them was added). This should be fixed in astroid at some point, here's the relevant code: https://bitbucket.org/logilab/astroid/src/f75482328c8c39538c74fa9a85915ec5c58ce1fa/astroid/brain/py2stdlib.py?at=default#cl-281

have the same problem.

import inspect
from enum import Enum

class ChoiceEnum(Enum):

    @classmethod
    def choices(cls):
        # get all members of the class
        members = inspect.getmembers(cls, lambda m: not(inspect.isroutine(m)))
        # filter down to just properties
        props = [m for m in members if not(m[0][:2] == '__')]
        # format into django choice tuple
        choices = tuple([(p[1].value, p[0]) for p in props])
        return choices

class BookingState(ChoiceEnum):
    IS_BOOKING = 0
    CONFIRMED = 1
    PAID = 2

class TourOfferingState(ChoiceEnum):
    OPEN = 0
    CONFIRMED = 1
    CANCELED = 2
    CLOSED = 3 

Is there anything that can be done in this issue?
I've got the same problem subclassing IntEnum in Python 3.6.

@LJBD Apart of disabling the check for now, no, there's no other solution. It would be great to have this fixed, but can't promise exactly when that's going to happen, unless someone proposes a patch to speed this up.

FYI a partial workaround here is to define your enum overrides as a mixin, and then subclass enum explicitly in all of your "subclasses." For example:

from enum import Enum

class SpecialEnumMixin:
  def __new__(cls, value, info):
    obj = object.__new__(cls)
    obj._value_ = value
    obj._info = info
    return obj

  @property
  def info(self):
    return self._info

class SpecialEnum(SpecialEnumMixin, Enum):
  A = ("a", "this is a")
  B = ("b", "this is b")

assert SpecialEnum.A.info == "this is a"
assert SpecialEnum("a") is SpecialEnum.A

Doing it this way, pylint recognizes the "subclass" correctly as an enum.

Is there a way to disable such no-member violations? Without disabling ALL of them?

Why people didn't fix this?

@gbrennon looks like they're willing to accept patches if you can find the cause of the issue and fix it yourself

Is there a way to disable such no-member violations? Without disabling ALL of them?

@dufferzafar : this might help https://pylint.readthedocs.io/en/latest/user_guide/message-control.html

Was this page helpful?
0 / 5 - 0 ratings