"""Decorator that makes a model class,given a definition of the model,and another class that represents afamily of models that the new model belongs to.The function returns a newly-created subclassof the class representing the family of models.The subclass can then be instantiatedand have all model methods."""from__future__importannotationsfromtypingimportTypefrom.baseimportModelfrom.definitionimportvalidateasvalidate_definitionfrom.registryimportregister_model
[docs]classModelDefinitionValidationError(Exception):"""Exception raised when validating a model definition fails. Used by :func:`vak.models.decorator.model` decorator. """pass
[docs]defmodel(family:Type[Model]):"""Decorator that makes a model class, given a definition of the model, and another class that represents a family of models that the new model belongs to. Returns a newly-created subclass of the class representing the family of models. The subclass can then be instantiated and have all model methods. Parameters ---------- definition : type The definition of the new model that will be made. A class with all the class variables required by :func:`vak.models.definition.validate`. See docstring of that function for specification. family : subclass of vak.models.Model The class representing the family of models that the new model will belong to. E.g., :class:`vak.models.FrameClassificationModel`. Returns ------- model : type A sub-class of ``model_family``, with attribute ``definition``, that will be used when making new instances of the model. """def_model(definition:Type):ifnotissubclass(family,Model):raiseTypeError("The ``family`` argument to the ``vak.models.model`` decorator""should be a subclass of ``vak.models.base.Model``,"f"but the type was: {type(family)}, ""which was not recognized as a subclass ""of ``vak.models.base.Model``.")try:validate_definition(definition)exceptValueErroraserr:raiseModelDefinitionValidationError(f"Validation failed for the following model definition:\n{definition}")fromerrexceptTypeErroraserr:raiseModelDefinitionValidationError(f"Validation failed for the following model definition:\n{definition}")fromerrattributes=dict(family.__dict__)attributes.update({"definition":definition})subclass_name=definition.__name__subclass=type(subclass_name,(family,),attributes)subclass.__module__=definition.__module__# finally, add model to registryregister_model(subclass)returnsubclassreturn_model