Search code examples
pythonpylint

pylint error on calling base class ctor when base is abstract


Some cases classes should not call the constructor of their super class, like those inherited from abstract classes:

class Father:
    def __init__(self):
        pass
class Son(Father):
    def __init__(self):
        self.salary = 700
    def __repr__(self):
        return f"my salary is {self.salary}"
print(Son())

Still, my legacy code contains a linter that complains about that:

$ pylint3 --disable=too-few-public-methods,missing-docstring main.py 
No config file found, using default configuration
************* Module main
W:  5, 4: __init__ method from base class 'Father' is not called (super-init-not-called)

Is there any way to convey this fact to pylint?


Solution

  • If the Father class is abstract you should not have an __init__ (well except if the init does something then you should call it) and you can explicitly make it inherits from ABC like this:

    import abc
    
    
    class Father(abc.ABC):
    
        @abc.abstractmethod
        def interface(self):
            ...
    
    
    class Son(Father):
        def __init__(self):
            self.salary = 700
    
        def __repr__(self):
            return f"my salary is {self.salary}"
    
        def interface(self):
            print(repr(self))
    
    
    class BadSon(Father):
        """interface not implemented here"""
    
    
    print(Son())
    print(BadSon())
    

    pylint understands what's going on:

    a.py:26:6: E0110: Abstract class 'BadSon' with abstract
    methods instantiated (abstract-class-instantiated)
    

    But when you launch with python there's an error too:

    my salary is 700
    Traceback (most recent call last):
      File "b.py", line 26, in <module>
        print(BadSon())
    TypeError: Can't instantiate abstract class BadSon with abstract methods interface
    

    See the documentation for the abc module