modelity.base
- class modelity.base.Constraint
Bases:
ABCBase class for constraints.
Constraints are used to define parsing- and validation-time criteria that must be met for successful parsing/validation. Instances of this base class are used with types wrapped with
typing.Annotated.Added in version 0.36.0: Replaced
modelity.interface.IConstraintused earlier.- __abstractmethods__ = frozenset({'__call__', '__repr__'})
- abstractmethod __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- class modelity.base.Field(name: str, typ: Any, type_handler: TypeHandler, *, field_info: FieldInfo | None = None, construction_required: bool = False, validation_required: bool = False, unsettable: bool = False)
Bases:
objectDataclass containing data parsed from field’s type annotation.
- __eq__(other)
Return self==value.
- __hash__ = None
- __init__(name: str, typ: Any, type_handler: TypeHandler, *, field_info: FieldInfo | None = None, construction_required: bool = False, validation_required: bool = False, unsettable: bool = False) None
- __match_args__ = ('name', 'typ', 'type_handler')
- __repr__()
Return repr(self).
- construction_required: bool = False
Flag telling if this field is required during model construction.
Fields that are construction-required will cause model construction failure (with
modelity.error.ErrorCode.REQUIRED_MISSINGerror code) if those are missing in model’s constructor and have no default values set.Note
Fields that are construction-required are also implicitly validation-required; if construction-required fields are removed from a model object after it was successfully created, the validation step will still report same error.
Added in version 0.37.0.
- field_info: FieldInfo | None = None
The additional metadata assigned for this field.
Everything declared using
field_info()goes into here.
- property required: bool
Flag telling if this field is required.
A field is required if at least one of
construction_requiredandvalidation_requiredattributes is set toTrue.
- type_handler: TypeHandler
The type handler set for this field.
It is derived from field’s type annotation set as
typ.
- unsettable: bool = False
Flag telling if
modelity.unset.Unsetis a valid value for this field.This is used both during construction and validation stages and will eventually cause
modelity.error.ErrorCode.UNSET_NOT_ALLOWEDerror if field is left unset. For example, fields marked withtyping.Optionalcannot be unset; you have to initialize with either value, or aNone.Changed in version 0.37.0: Now this is also checked during model construction in addition to validation.
- validation_required: bool = False
Flag telling if this field is required during model validation.
Such fields can be skipped during model construction (the model construction will not fail), but are required to be set before validation takes place. This is used by
modelity.typing.Deferredtype wrapper.Note
This flag is automatically set to
Truefor construction-required fields.Added in version 0.37.0.
- class modelity.base.FieldInfo(default: ~typing.Any = Unset, default_factory: ~typing.Callable[[], ~typing.Any] | ~modelity.unset.UnsetType = Unset, title: str | None = None, description: str | None = None, examples: list | None = None, type_opts: dict = <factory>)
Bases:
objectClass for setting field metadata.
- __eq__(other)
Return self==value.
- __hash__ = None
- __init__(default: ~typing.Any = Unset, default_factory: ~typing.Callable[[], ~typing.Any] | ~modelity.unset.UnsetType = Unset, title: str | None = None, description: str | None = None, examples: list | None = None, type_opts: dict = <factory>) None
- __match_args__ = ('default', 'default_factory', 'title', 'description', 'examples', 'type_opts')
- __repr__()
Return repr(self).
- default_factory: Callable[[], Any] | UnsetType = Unset
Default value factory function.
Allows to create default values that are evaluated each time the model is created, and therefore producing different default values for different model instances.
- description: str | None = None
The description of this field.
This is a long description, to be used when
titleis not sufficient.Added in version 0.19.0.
- examples: list | None = None
The example values for this field.
This is not used directly in any way by the library, but 3rd party tools may use it f.e. to create random valid objects for tests.
Added in version 0.19.0.
- class modelity.base.Model(**kwargs)
Bases:
objectBase class for data models.
All models created using Modelity must inherit from this base class and provide zero or more fields using type annotations in similar way as when using Python dataclasses.
Here’s a simple example:
from typing import Optional from modelity.api import Model, Deferred, LooseOptional, StrictOptional, Unset, validate class Dummy(Model): foo: int # <- required; must be given in constructor xyz: float = 3.14 # <- required; optional in constructor, as it has default value set bar: Deferred[bool] = Unset # <- deferred; must be set before validation baz: Optional[str] = None # <- optional; can be `None` but cannot be `Unset` spam: LooseOptional[str] = Unset # <- optional; can be set to `None` or `Unset` more_spam: StrictOptional[str] = Unset # <- optional; can be `Unset` but cannot be `None`
>>> dummy = Dummy(foo='123') # Construct model instance; Modelity will try to parse input to expected type >>> dummy Dummy(foo=123, xyz=3.14, bar=Unset, baz=None, spam=Unset, more_spam=Unset) >>> validate(dummy) # Validation will fail; deferred field `bar` is missing Traceback (most recent call last): ... modelity.exc.ValidationError: Found 1 validation error for model 'Dummy': bar: This field is required [code=modelity.REQUIRED_MISSING] >>> dummy.bar = True # Now let's set a value to `bar` field (models are mutable) >>> validate(dummy) # And now the model is valid >>> dummy Dummy(foo=123, xyz=3.14, bar=True, baz=None, spam=Unset, more_spam=Unset)
- __contains__(name)
- __delattr__(name)
Implement delattr(self, name).
- __eq__(value)
Return self==value.
- __hash__ = None
- __iter__()
- __model_fields__: Mapping[str, Field] = {}
A per-instance view of the
ModelMeta.__model_fields__attribute.
- __repr__()
Return repr(self).
- __slots__ = ()
- accept(visitor: ModelVisitor, loc: Loc)
Accept visitor on this model.
- Parameters:
visitor – The visitor to accept.
loc – The location of this model or empty location if this is the root model.
- class modelity.base.ModelMeta(name: str, bases: tuple, attrs: dict)
Bases:
typeMetaclass for models.
The role of this metaclass is to provide field initialization, type descriptor lookup and inheritance handling.
It is used as a metaclass by
Modelbase class and all methods and properties it provides can be accessed via__class__attribute of theModelclass instances.
- class modelity.base.ModelVisitor
Bases:
ABCBase class for model data visitors.
This mechanism allows to traverse through Modelity models in a deterministic way and, depending on the implementation, serialize or validate it.
Added in version 0.36.0: Replaced
modelity.interface.IModelVisitorused earlier.- __abstractmethods__ = frozenset({'visit_any', 'visit_mapping_begin', 'visit_mapping_end', 'visit_model_begin', 'visit_model_end', 'visit_model_field_begin', 'visit_model_field_end', 'visit_none', 'visit_scalar', 'visit_sequence_begin', 'visit_sequence_end', 'visit_set_begin', 'visit_set_end', 'visit_unset'})
- abstractmethod visit_any(loc: Loc, value: Any)
Visit any value.
This is called for values from untyped containers, fields marked with
typing.Anyor typed containers wheretyping.Anyis used as a type hint.This method, unlike
visit_scalar(), can also be called with elements that are containers, not scalars.Implementations are responsible for deciding whether to recurse into the value if it is a container.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- abstractmethod visit_mapping_begin(loc: Loc, value: Mapping) bool | None
Start visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- abstractmethod visit_mapping_end(loc: Loc, value: Mapping)
Finish visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- abstractmethod visit_model_begin(loc: Loc, value: Model) bool | None
Start visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- abstractmethod visit_model_end(loc: Loc, value: Model)
Finish visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- abstractmethod visit_model_field_begin(loc: Loc, value: Any, field: Field) bool | None
Start visiting model field.
This is called for every field in a model no matter if the field is set or not.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- abstractmethod visit_model_field_end(loc: Loc, value: Any, field: Field)
Finish visiting model field.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- abstractmethod visit_none(loc: Loc, value: None)
Visit a
Nonevalue.Called when
Noneobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- abstractmethod visit_scalar(loc: Loc, value: Any)
Visit scalar object.
Scalars are primitive objects that are neither containers, nor model objects. All Python primitive types (ints, floats, strings, booleans, enums, datetimes etc.) are scalars from the Modelity point of view.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- abstractmethod visit_sequence_begin(loc: Loc, value: Sequence) bool | None
Start visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- abstractmethod visit_sequence_end(loc: Loc, value: Sequence)
Finish visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- abstractmethod visit_set_begin(loc: Loc, value: Set) bool | None
Start visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- abstractmethod visit_set_end(loc: Loc, value: Set)
Finish visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- abstractmethod visit_unset(loc: Loc, value: UnsetType)
Visit an
Unsetvalue.Called when
modelity.unset.Unsetobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- class modelity.base.TypeHandler
Bases:
ABCBase class for type handlers.
Type handlers are used by Modelity to provide type-specific runtime logic to models. Type handlers are constructed from type object or type annotations when model type is created and then used by model instances to handle user data.
Added in version 0.36.0: Replaced
modelity.interface.ITypeDescriptorused earlier.- __abstractmethods__ = frozenset({'accept', 'parse'})
- abstractmethod accept(visitor: ModelVisitor, loc: Loc, value: Any, /)
Accept given model visitor.
This method is meant to provide visitor accepting logic for handled type. Basically, this method will call the most adequate visitor method, or (for complex types) sequence of visitor methods. See
ModelVisitorfor more details.- Parameters:
visitor – The visitor to accept.
loc – The visited location in the model.
value –
The value to process.
It can be assumed that this value has the right type already.
- abstractmethod parse(errors: list[Error], loc: Loc, value: Any, /) Any | UnsetType
Parse given value as instance of handled type.
Successful parsing must return instance of handled type, which can be unchanged value if it already has desired type.
Failure must be reported by one or more errors added to errors list, and
modelity.unset.Unsetvalue returned.- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The input value.
- class modelity.base.TypeHandlerFactory(*args, **kwargs)
Bases:
ProtocolProtocol describing type handler factories.
Added in version Replaced:
modelity.interface.ITypeDescriptorFactoryused earlier.- __abstractmethods__ = frozenset({})
- __call__(typ: Any, /, **type_opts) TypeHandler
Create a type handler for the provided type and options.
- Parameters:
typ – The type or special form to create a handler for.
type_opts – Optional type-specific options passed to the handler.
- __init__(*args, **kwargs)
- __parameters__ = ()
- __protocol_attrs__ = {'__call__'}
- classmethod __subclasshook__(other)
Abstract classes can override this to customize issubclass().
This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).
- class modelity.base.TypeHandlerWithValidation
Bases:
TypeHandlerBase class for type handlers that need to run additional type-specific validation when model is validated.
For example, this base class is used by type handler for
typing.Annotatedtypes to ensure that constraints are still satisfied when model is validated, which is impossible to ensure only during parsing stage for mutable types.Added in version 0.36.0: Replaced
modelity.interface.IValidatableTypeDescriptorused earlier.- __abstractmethods__ = frozenset({'accept', 'parse', 'validate'})
- abstractmethod validate(errors: list[Error], loc: Loc, value: Any) bool
Validate the value.
Returns True and does not modify error list if the value is valid.
Returns False and adds one or more errors to the errors list if the value is not valid.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- modelity.base.create_type_handler(typ: Any, /, **type_opts)
Create type handler for provided type.
This method is using cache internally so it returns same handler if called again with same type.
- Parameters:
typ – The type to create or get handler for.
**type_opts – The optional type options to use.
- modelity.base.field_info(*, default: T | UnsetType = Unset, default_factory: Callable[[], T] | UnsetType = Unset, title: str | None = None, description: str | None = None, examples: list | None = None, **type_opts) T
Helper for creating
FieldInfoobjects in a way that will satisfy code linters.Check
FieldInfoclass documentation to get help on available parameters.Changed in version 0.19.0: Added title, description and examples parameters.
Added in version 0.16.0.
- modelity.base.register_type_handler_factory(typ: Any, factory: TypeHandlerFactory)
Register custom type handler factory for given type.
This method can be used to register custom types so Modelity could understand those, or to overwrite built-in type handlers.
- Parameters:
typ – The type to register type handler for.
factory – The type handler factory function to use for provided type.