AivanF.
AivanF.

Reputation: 1226

meta class doesn't get inherited

In the following code:

class Meta(type):
    def __new__(cls, name, bases, attrs):
        print(name)
        return type(name, bases, attrs)

class A(object, metaclass=Meta):
    def do_complex_task(self):
        pass

class B(A):
    def do_minor_task(self):
        pass

I'd expect to see both A and B get printed, but I see that the meta class is applied to the A only. How can I solve this? My goal is to preprocess fields of all the children of A, and I'd like to omit typing metaclass=Meta in every child.

Upvotes: 1

Views: 186

Answers (2)

a_guest
a_guest

Reputation: 36329

Since you return type(name, bases, attrs) you get an object of type type instead of Meta. You can check this by printing A.__class__. Instead you should return:

return super().__new__(cls, name, bases, attrs)

Upvotes: 3

Silvio Mayolo
Silvio Mayolo

Reputation: 70397

Your metaclass is not actually Meta. If you do type(a), you get <class 'type'>, because you overrode Meta.__new__ to return an ordinary type, not a Meta instance.

Generally speaking, like with ordinary classes, with metaclasses you want to override __init__ and let __new__ do the default thing.

class Meta(type):
    def __init__(self, name, supers, attrs):
        print(name)

Then you'll see both A and B printed, as desired.

Upvotes: 1

Related Questions