Pylint for half-implemented abstract classes

9.5k views Asked by At

Consider following code snippet:

class AbstractClass(object):
    def method1(self):
        raise NotImplementedError()

    def method2(self):
        raise NotImplementedError()

class SemiConcreteClass(AbstractClass):
    def method1(self):
        return True

class ConcreteClass(SemiConcreteClass):
    def method2(self):
        return True

Running checks on this file with default config (pylint classes.py) yields some missing docstrings (let's ignore them) and this warning:

W: 8, 0: Method 'method2' is abstract in class 'AbstractClass' but is not overridden (abstract-method)

I know SemiConcreteClass is in fact abstract and should be sub-classed in order to be used and I do not want Pylint to report it. How can I configure Pylint to treat these classes as just another abstract class? Naming convention of class name, module where class resides - all this solutions would be fine.

I know I can explicitly silence warning in class by # pylint: disable=abstract-method comment. Is there more elegant solution?

pylint 1.4.3,
astroid 1.3.6, common 0.63.2
Python 2.7.9 (default, Dec 10 2014, 12:28:03) [MSC v.1500 64 bit (AMD64)]
1

There are 1 answers

0
Wolph On

Unfortunately pylint is not really intelligent enough in cases like these, personally I would just disable the warning since ConcreteClass obviously implements both. The alternative solution would be to make SemiConcreteClass implement both methods but that's usually something you are trying to avoid.

Instead of having Pylint check for this I usually just use the Python Abstract Base Classes instead, they will notify you of unimplemented methods.

Example:

#!/usr/bin/python
import abc


class AbstractClass(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def method1(self):
        raise NotImplementedError()

    @abc.abstractmethod
    def method2(self):
        raise NotImplementedError()


class SemiConcreteClass(AbstractClass):
    def method1(self):
        return True


SemiConcreteClass()

Which results in:

Traceback (most recent call last):
  File "test.py", line 22, in <module>
    SemiConcreteClass()
TypeError: Can't instantiate abstract class SemiConcreteClass with abstract methods method2