godsarmy godsarmy - 4 months ago 10
Python Question

Why pylint keeps saying my class is R0923 - 'interface not implemented'

I am writing python classes with abc module to define abstract class and using sub-class to implement the abstract method. However, when i tried to use pylint to justify it, pylint keeps saying my subclass is "interface not implemented". I am a little bit confused how pylint regards a class is an interface. Could anyone shed some light on me?

Here is my example code. When i call

pylint mytest.py
, the result is as
R0923: 17:MyClass: Interface not implemented
.

import abc


class MyInterface(object):
"""docstring for MyInterface"""

__metaclass__ = abc.ABCMeta

def __init__(self, arg):
self.arg = arg

@abc.abstractmethod
def test(self):
pass


class MyClass(MyInterface):
"""docstring for MyClass"""
def __init__(self, arg):
super(MyClass, self).__init__(arg)

def test(self):
"""docstring for test"""
print self.arg

Answer

Pylint is rather opinionated about interfaces and how you should use them. In your case you have mixed two distinct concepts from pylint's point of view. One is an abstract class and other is an interface. Pylint thinks that correct way to deal with an abstract class is to subclass from it and correct way to use an interface is to specify it in the class implementation by listing it in __implements__ class variable like so:

class Dog(object):
    __implements__ = (IWalk, IRun, IMakeASound)

Going through your specific case here is what pylint's train of thought looks like:

  • infer that MyInterface is an interface from it's name.
  • also MyInterface is an abstract class because of all the abc stuff going on.
  • MyClass is an implementation of MyInterface the abstract class.
  • MyClass inherits from MyInterface the interface.

So far everything goes well according from pylint's perspective. MyInterface the abstract class has been subclassed and MyInterface the interface has been subclassed so maybe it's just some base class for other interfaces.

  • Conclude that MyClass is an interface because it inherits from MyInterface the interface.
  • MyClass the interface has not been implemented anywhere.

This is where something went wrong from pylint's perspective.

To make a coherent story for the pylint you can adjust your code like so:

import abc


class MyInterface(object):
    """docstring for MyInterface"""

    __metaclass__ = abc.ABCMeta

    def __init__(self, arg):
        self.arg = arg

    @abc.abstractmethod
    def test(self):
        pass


class MyClass(MyInterface):
    """docstring for MyClass"""
    def __init__(self, arg):
        super(MyClass, self).__init__(arg)

    def test(self):
        """docstring for test"""
        print self.arg

class MyImplementation(object):
    __implements__ = (MyClass, )
Comments