"""Helper API for setting serialization/deserialization context.Example usage:.. code-block:: python import typing from marshmallow import Schema, fields from marshmallow.experimental.context import Context class UserContext(typing.TypedDict): suffix: str UserSchemaContext = Context[UserContext] class UserSchema(Schema): name_suffixed = fields.Function( lambda user: user["name"] + UserSchemaContext.get()["suffix"] ) with UserSchemaContext({"suffix": "bar"}): print(UserSchema().dump({"name": "foo"})) # {'name_suffixed': 'foobar'}"""from__future__importannotationsimportcontextlibimportcontextvarsimporttypingtry:fromtypesimportEllipsisTypeexceptImportError:# Python<3.10EllipsisType=type(Ellipsis)# type: ignore[misc]_ContextT=typing.TypeVar("_ContextT")_DefaultT=typing.TypeVar("_DefaultT")_CURRENT_CONTEXT:contextvars.ContextVar=contextvars.ContextVar("context")
[docs]classContext(contextlib.AbstractContextManager,typing.Generic[_ContextT]):"""Context manager for setting and retrieving context. :param context: The context to use within the context manager scope. """def__init__(self,context:_ContextT)->None:self.context=contextself.token:contextvars.Token|None=Nonedef__enter__(self)->Context[_ContextT]:self.token=_CURRENT_CONTEXT.set(self.context)returnselfdef__exit__(self,*args,**kwargs)->None:_CURRENT_CONTEXT.reset(typing.cast("contextvars.Token",self.token))
[docs]@classmethoddefget(cls,default:_DefaultT|EllipsisType=...)->_ContextT|_DefaultT:"""Get the current context. :param default: Default value to return if no context is set. If not provided and no context is set, a :exc:`LookupError` is raised. """ifdefaultisnot...:return_CURRENT_CONTEXT.get(default)return_CURRENT_CONTEXT.get()