"""A registry of :class:`Schema <marshmallow.Schema>` classes. This allows for stringlookup of schemas, which may be used withclass:`fields.Nested <marshmallow.fields.Nested>`... warning:: This module is treated as private API. Users should not need to use this module directly."""# ruff: noqa: ERA001from__future__importannotationsimporttypingfrommarshmallow.exceptionsimportRegistryErroriftyping.TYPE_CHECKING:frommarshmallowimportSchemaSchemaType=type[Schema]# {# <class_name>: <list of class objects># <module_path_to_class>: <list of class objects># }_registry={}# type: dict[str, list[SchemaType]]
[docs]defregister(classname:str,cls:SchemaType)->None:"""Add a class to the registry of serializer classes. When a class is registered, an entry for both its classname and its full, module-qualified path are added to the registry. Example: :: class MyClass: pass register("MyClass", MyClass) # Registry: # { # 'MyClass': [path.to.MyClass], # 'path.to.MyClass': [path.to.MyClass], # } """# Module where the class is locatedmodule=cls.__module__# Full module path to the class# e.g. user.schemas.UserSchemafullpath=f"{module}.{classname}"# If the class is already registered; need to check if the entries are# in the same module as cls to avoid having multiple instances of the same# class in the registryifclassnamein_registryandnotany(each.__module__==moduleforeachin_registry[classname]):_registry[classname].append(cls)elifclassnamenotin_registry:_registry[classname]=[cls]# Also register the full pathiffullpathnotin_registry:_registry.setdefault(fullpath,[]).append(cls)else:# If fullpath does exist, replace existing entry_registry[fullpath]=[cls]
[docs]defget_class(classname:str,*,all:bool=False)->list[SchemaType]|SchemaType:# noqa: A002"""Retrieve a class from the registry. :raises: `marshmallow.exceptions.RegistryError` if the class cannot be found or if there are multiple entries for the given class name. """try:classes=_registry[classname]exceptKeyErroraserror:raiseRegistryError(f"Class with name {classname!r} was not found. You may need ""to import the class.")fromerroriflen(classes)>1:ifall:return_registry[classname]raiseRegistryError(f"Multiple classes with name {classname!r} ""were found. Please use the full, ""module-qualified path.")return_registry[classname][0]