1. masklinn
  2. Extends


Extends / extends / __init__.py

__all__ = ['Base', 'Extend']

def get_extends(cls):
    # __subclasses__ is sorted in loading order and the mro
    # executes the bases left-to-right. We want the resolution
    # order of the extended type to be last-loaded first (the
    # latest-loaded extender sees its methods executed first,
    # execution goes up the extension sequence and ends on the
    # base class), therefore we must revert ``extenders``
    return [
        sub for sub in cls.__subclasses__()
        if issubclass(sub, Extend)
        if sub is not Extend][::-1]

class Extend(object):

class Base(object):
    def __new__(cls):
        base_extenders = get_extends(cls)
        ancestor_extenders = sum(map(get_extends, cls.mro()[1:]), [])
        if not (base_extenders or ancestor_extenders):
            return object.__new__(cls)

        extenders = (base_extenders or [cls]) + ancestor_extenders
        return object.__new__(
            type(cls.__name__, tuple(extenders), {}))