I had this question for quite a while and couldn't really find a post that explained this aspect of metaclasses. In fact I had it for so long that I came up with this alternate, and ultimately unnecessary, solution. Technically it conforms exactly to the kind of syntax I wanted (which is cool) but in the end it's a hack. Since I spent so long making a pointless (but still cool) bit of code, I figured I'd at least try and make sure no one else got stuck in the same rut.
My confusion really stemmed from the fact that I hadn't fully extended my understanding of metaclasses, and the relationship they have with their classes, to its logical conclusion. So, as it turns out, the best way to create the kind of inheritance I wanted was actually to perform it inside a series of metaclasses - for the same reasons trying to inherit attributes through the instances of a class makes no sense, it makes no sense to be making the instances of a metaclass polymorphic:
from six import with_metaclass
class Meta(type):
"""a metaclass"""
def __init__(cls, name, bases, classdict):
print("Beginning '%s' setup" % name)
cls.setup_class()
print("Finished '%s' setup \n" % name)
def setup_class(cls):
cls.attribute = 0
cls.instantiate('Meta')
class AMeta(Meta):
def setup_class(cls):
super(AMeta, cls).setup_class()
cls.instantiate('A')
def instantiate(cls, name):
print("instantiating through '%s'" % name)
class A(with_metaclass(AMeta, object)): pass
class BMeta(AMeta):
def setup_class(cls):
super(BMeta, cls).setup_class()
cls.instantiate('B')
class B(with_metaclass(BMeta, object)): pass
class C(B): pass
If anyone cares to more thoroughly examine this, I'm sure someone out there would appreciate it.