Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import six
class ModelBase(type):
def __new__(meta, name, bases, dct):
print("ModelBase.__new__(%s)" % name)
result = super(ModelBase, meta).__new__(meta, name, bases, dct)
print("/ModelBase.__new__(%s)" % name)
return result
def __init__(cls, name, bases, dct):
print("ModelBase.__init__(%s)" % name)
super(ModelBase, cls).__init__(name, bases, dct)
print("/ModelBase.__init__(%s)" % name)
class Model(six.with_metaclass(ModelBase, object)):
pass
print("\n")
class PageBase(ModelBase):
def __new__(meta, name, bases, dct):
print("PageBase.__new__(%s)" % name)
result = super(PageBase, meta).__new__(meta, name, bases, dct)
print("/PageBase.__new__(%s)" % name)
return result
def __init__(cls, name, bases, dct):
print("PageBase.__init__(%s)" % name)
super(PageBase, cls).__init__(name, bases, dct)
print("/PageBase.__init__(%s)" % name)
class Page(six.with_metaclass(PageBase, Model)):
pass
print("\n")
class Mixin(Model):
pass
print("\n")
class BlogPost(Mixin, Page):
pass
print("\n")
class DonationsPage(Page, Mixin):
pass
"""
On Python 2.7, putting Mixin ahead of Page in BlogPost's superclass list
results in a call chain of ModelBase -> PageBase -> ModelBase -
i.e. ModelBase.__new__ is called twice:
ModelBase.__new__(BlogPost)
PageBase.__new__(BlogPost)
ModelBase.__new__(BlogPost)
/ModelBase.__new__(BlogPost)
/PageBase.__new__(BlogPost)
/ModelBase.__new__(BlogPost)
PageBase.__init__(BlogPost)
ModelBase.__init__(BlogPost)
/ModelBase.__init__(BlogPost)
/PageBase.__init__(BlogPost)
On Python 3, the call chain is PageBase -> ModelBase:
PageBase.__new__(BlogPost)
ModelBase.__new__(BlogPost)
/ModelBase.__new__(BlogPost)
/PageBase.__new__(BlogPost)
PageBase.__init__(BlogPost)
ModelBase.__init__(BlogPost)
/ModelBase.__init__(BlogPost)
/PageBase.__init__(BlogPost)
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment