I have a concrete class MyConcreteClass
which subclasses an abstract
class MyABC2
, which, in turn, subclasses another abstract class MyABC1
:
import abc
class MyABC1 (object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def my_abstract_method (self):
raise NotImplementedError("MyABC1.my_abstract_method")
class MyABC2 (MyABC1):
__metaclass__ = abc.ABCMeta
class MyConcreteClass (MyABC2):
def my_abstract_method (self):
print "MyConcreteClass.my_abstract_method"
pylint
does not like that I do not define my_abstract_method
in MyABC2
:
/usr/local/bin/epylint abctest.py
************* Module abctest
abctest.py:9: warning (W0223, abstract-method, MyABC2) Method 'my_abstract_method' is abstract in class 'MyABC1' but is not overridden
Is this a known bug? Maybe I am doing something wrong?
Pylint's notion of when a class is intended to be abstract is a bit limited. Basically, it can't tell that you intended the MyABC2
class to be an abstract class. Its logic assumes that if you don't declare any methods in the class that are decorated with @abstractmethod
(or raise NotImplementedError
), you intended the class to be concrete. In such a situation, failing to override the inherited abstract methods would be an error.
Declaring the metaclass in MyABC2
doesn't help. In fact, that declaration is completely redundant, since a subclass inherits its metaclass from its parent class.
So that's the reason for the incorrect warning. Now the question is what to do about it. Ideally, pylint would be a bit more sophisticated and handle this situation better, but fixing the issue would be difficult. I don't really know how it can tell the difference between a mid-level abstract class that doesn't add any new abstract methods and a incorrectly implemented concrete class.
So probably the only option is to disable the warning for that class. Try adding the following comment to your code just above the class declaration: # pylint: disable=W0223
. (It might also work if you put the comment inside the class, I'm not sure.)