def hookable(cls):
assert isinstance(cls, type)<EOL>hook_definitions = []<EOL>if not issubclass(cls, Hookable):<EOL><INDENT>for k, v in list(cls.__dict__.items()):<EOL><INDENT>if isinstance(v, (ClassHook, InstanceHook)):<EOL><INDENT>delattr(cls, k)<EOL>if v.name is None:<EOL><INDENT>v.name = k<EOL><DEDENT>hook_definitions.append((k, v))<EOL><DEDENT><DEDENT><DEDENT>hookable_cls = type(cls.__name__, (cls, Hookable), {})<EOL>for k, v in hook_definitions:<EOL><INDENT>setattr(hookable_cls, k, HookDescriptor(defining_hook=v, defining_class=hookable_cls))<EOL><DEDENT>return hookable_cls<EOL>
Initialise hookery in a class that declares hooks by decorating it with this decorator.

This replaces the class with another one which has the same name, but also inherits Hookable
which has HookableMeta set as metaclass so that sub-classes of cls will have hook descriptors
initialised properly.

When you say:
    @hookable
    class My:
        before = Hook()

then @hookable changes My.before to be a HookDescriptor which is then
changed into Hook if anyone accesses it.

There is no need to decorate sub-classes of cls with @hookable.