def __new__(cls, name, bases, attrs): new_attrs = {} associations = {} validators = [] hooks = {} for attr_name, attr in attrs.items(): if isinstance(attr, Association): # need to make a copy of the association, to preserve # instance-level attribs of the association associations[attr_name] = attr else: new_attrs[attr_name] = attr if toothpick.validations._is_validator(attr): validators.append(attr) for hook_name in toothpick.hooks._which_hook(attr): hooks_for_name = hooks.get(hook_name, []) hooks_for_name.append(attr) hooks[hook_name] = hooks_for_name # handle associations, validators, and hooks declared in other classes inherited_associations = {} for base in bases: if hasattr(base, "_cls_associations"): inherited_associations.update(base._cls_associations) validators.extend(cls.find_validators(base)) for hook_name, hook_methods in cls.find_hooks(base).items(): hooks_for_name = hooks.get(hook_name, []) hooks_for_name.extend(hook_methods) hooks[hook_name] = hooks_for_name # make sure any clashes reflect the declared class inherited_associations.update(associations) associations = inherited_associations special_attrs = dict(_cls_associations=associations, _hooks=hooks) if any([issubclass(base, HasResources) for base in bases]): special_attrs["_resources"] = dict() if any([issubclass(base, Validatable) for base in bases]): special_attrs["_validators"] = validators new_attrs.update(special_attrs) return register_model(name, type.__new__(cls, name, bases, new_attrs))
def find_hooks(cls, base): hooks = {} for method_name, method in inspect.getmembers(base, inspect.ismethod): for hook_name in toothpick.hooks._which_hook(method): hooks_for_name = hooks.get(hook_name, []) hooks_for_name.append(method) hooks[hook_name] = hooks_for_name return hooks