Inheriting the class dictionary with metaclasses

inheritance, metaclass, python, python-3.x

Solution

You need to somehow keep the `fields` of the superclasses, for example by iterating over the "bases" and using their `fields` as starting point:

class MyMeta(type):
    def __new__(mcs, name, bases, clsdict):
        if 'fields' not in clsdict:
            clsdict['fields'] = {}
        # Initialize "fields" from base classes
        for base in bases:
            try:
                clsdict['fields'].update(base.fields)
            except AttributeError:
                pass
        # Fill in new fields (I included a "trivial" condition here, just use yours instead.)
        clsdict['fields'].update({k: v for k, v in clsdict.items() if k.startswith('param')})
        return super(MyMeta, mcs).__new__(mcs, name, bases, clsdict)

And it works for `SubClass` and `SubSubClass`:

>>> SubClass.fields
{'param1': 1}

>>> SubSubClass.fields
{'param1': 1}

Problem

I am setting a class property `fields` using a metaclass: ``` class MyMeta(type): def __new__(mcs, name, bases, clsdict): clsdict['fields'] = {k: v for k, v in clsdict.items() if <my_condition>} return super(MyMeta, mcs).__new__(mcs, name, bases, clsdict) class MyBaseClass(metaclass=MyMeta): fields = {} ``` The following instantiation leads to expected results: ``` class SubClass(MyBaseClass): param1 = 1 # meets <my_condition> >>> SubClass.fields {param1: 1} ``` But if I now subclass `SubClass`, `fields` is empty: ``` class SubSubClass(SubClass): pass >>> SubSubClass.fields {} ``` How would I be able to update the classdict of all classes in inheritance hierarchy so that the `fields` variable would be updated from base classes?

Original source