DeferredValidation

class lsst.daf.butler.pydantic_utils.DeferredValidation(data: Any)

Bases: Generic[_T]

A base class whose subclasses define a wrapper for a Pydantic-aware type that defers validation but declares the same JSON schema.

Parameters:
dataobject

Unvalidated data representing an instance of the wrapped type. This may be the serialized form of the wrapped type, an instance of the wrapped type, or anything else - but the in the latter case, calls to validated will fail with a Pydantic validation error, and if the object is known to be an instance of the wrapped type, from_validated should be preferred.

Notes

This class must be subclassed to be used, but subclasses are always trivial:

class SerializableThing(DeferredValidation[Thing]):
    pass

The type parameter for DeferredValidation may be a special typing object like typing.Union or typing.Annotated instead of an actual type object. The only requirement is that it must be a type Pydantic recognizes, like a pydantic.BaseModel subclass, a dataclass, or a primitive built-in.

A wrapper subclass (e.g. SerializableThing) can be used with Pydantic via pydantic.TypeAdapter or as a field in pydantic.BaseModel. The JSON schema of the wrapper will be consistent with the JSON schema of the wrapped type (though it may not use JSON pointer references the same way), and Pydantic serialization will work regardless of whether the wrapper instance was initialized with the raw type or the wrapped type. Pydantic validation of the wrapper will effectively do nothing, however; instead, the validated method must be called to return a fully-validated instance of the wrapped type, which is then cached within the wrapper for subsequent calls to validated.

Indirect subclasses of DeferredValidation are not permitted.

A major use case for DeferredValidation is types whose validation requires additional runtime context (via the Pydantic “validation context” dictionary that can custom validator hooks can access). These types are often first deserialized (e.g. by FastAPI) in a way that does not permit that context to be provided.

Methods Summary

from_validated(wrapped)

Construct from an instance of the wrapped type.

validated(**kwargs)

Validate (if necessary) and return the validated object.

Methods Documentation

classmethod from_validated(wrapped: _T) Self

Construct from an instance of the wrapped type.

Unlike invoking the constructor with an instance of the wrapped type, this factory marks the held instance as already validated (since that is expected to be guaranteed by the caller, possibly with the help of static analysis), which sidesteps Pydantic validation in later calls to validated.

Parameters:
wrappedobject

Instance of the wrapped type.

Returns:
wrapperDeferredValidation

Instance of the wrapper.

validated(**kwargs: Any) _T

Validate (if necessary) and return the validated object.

Parameters:
**kwargs

Additional keywords arguments are passed as the Pydantic “validation context” dict.

Returns:
wrapped

An instance of the wrapped type. This is also cached for the next call to validated, which will ignore ``**kwargs``.