Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error "__init__ method from base class is not called" for an abstract class

Tags:

python

pylint

I have

class A(object):
    def __init__ (self): raise NotImplementedError("A")

class B(A):
    def __init__ (self):
        ....

and pylint says

__init__ method from base class 'A' is not called

Obviously, I do not want to do

super(B, self).__init__()
  • so what do I do?

(I tried abc and got

Undefined variable 'abstractmethod'

from pylint, so that is not an option either).

like image 905
sds Avatar asked Aug 01 '14 03:08

sds


3 Answers

Ignore pylint. It's just a program that doesn't take abstract classes into account. Be confident you are smarter than it is. Pylint is a knee brace, not a crutch.

like image 56
holdenweb Avatar answered Oct 15 '22 04:10

holdenweb


Using abc works for me:

import abc

class A(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def __init__(self):
        pass

class B(A):
    def __init__(self):
        super(B, self).__init__()

I get warnings, but nothing related to abc or the parent's __init__ not being called:

C:  1, 0: Missing module docstring (missing-docstring)
C:  3, 0: Invalid class name "A" (invalid-name)
C:  3, 0: Missing class docstring (missing-docstring)
R:  3, 0: Too few public methods (0/2) (too-few-public-methods)
C:  9, 0: Invalid class name "B" (invalid-name)
C:  9, 0: Missing class docstring (missing-docstring)
R:  9, 0: Too few public methods (0/2) (too-few-public-methods)
R:  3, 0: Abstract class is only referenced 1 times (abstract-class-little-used)

For what its worth, I'm with @holdenweb on this one. Sometimes you know better than pylint.

like image 4
dano Avatar answered Oct 15 '22 04:10

dano


Defining an empty __init__ as an abstract method is not very useful.

Instead, make A inherit from ABC (ABstract Class), and use @abstractmethod decorator on methods that really need to be implemented by the user.

from abc import ABC, abstractmethod

class A(ABC):
    @abstractmethod
    def cool_method(self):
        raise NotImplemented

In that way, you would effectively not be able to instantiate A, and at the same time, you avoid the warning. Also consider that the default __init__ method for A when not implemented, would be something along the lines of:

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

So additionally, it has the advantage that it respects the mro, if you later want to use A in a multiple inheritance setup, you will not run into problems.

like image 1
Mateo de Mayo Avatar answered Oct 15 '22 04:10

Mateo de Mayo