Module dataclasses_json.mm

View Source
# flake8: noqa

import typing

import warnings

import sys

from copy import deepcopy

from dataclasses import MISSING, is_dataclass, fields as dc_fields

from datetime import datetime

from decimal import Decimal

from uuid import UUID

from enum import Enum

from typing_inspect import is_union_type  # type: ignore

from marshmallow import fields, Schema, post_load

from marshmallow_enum import EnumField  # type: ignore

from marshmallow.exceptions import ValidationError

from dataclasses_json.core import (_is_supported_generic, _decode_dataclass,

                                   _ExtendedEncoder, _user_overrides_or_exts)

from dataclasses_json.utils import (_is_collection, _is_optional,

                                    _issubclass_safe, _timestamp_to_dt_aware,

                                    _is_new_type, _get_type_origin,

                                    _handle_undefined_parameters_safe,

                                    CatchAllVar)

class _TimestampField(fields.Field):

    def _serialize(self, value, attr, obj, **kwargs):

        if value is not None:

            return value.timestamp()

        else:

            if not self.required:

                return None

            else:

                raise ValidationError(self.default_error_messages["required"])

    def _deserialize(self, value, attr, data, **kwargs):

        if value is not None:

            return _timestamp_to_dt_aware(value)

        else:

            if not self.required:

                return None

            else:

                raise ValidationError(self.default_error_messages["required"])

class _IsoField(fields.Field):

    def _serialize(self, value, attr, obj, **kwargs):

        if value is not None:

            return value.isoformat()

        else:

            if not self.required:

                return None

            else:

                raise ValidationError(self.default_error_messages["required"])

    def _deserialize(self, value, attr, data, **kwargs):

        if value is not None:

            return datetime.fromisoformat(value)

        else:

            if not self.required:

                return None

            else:

                raise ValidationError(self.default_error_messages["required"])

class _UnionField(fields.Field):

    def __init__(self, desc, cls, field, *args, **kwargs):

        self.desc = desc

        self.cls = cls

        self.field = field

        super().__init__(*args, **kwargs)

    def _serialize(self, value, attr, obj, **kwargs):

        if self.allow_none and value is None:

            return None

        for type_, schema_ in self.desc.items():

            if _issubclass_safe(type(value), type_):

                if is_dataclass(value):

                    res = schema_._serialize(value, attr, obj, **kwargs)

                    res['__type'] = str(type_.__name__)

                    return res

                break

            elif isinstance(value, _get_type_origin(type_)):

                return schema_._serialize(value, attr, obj, **kwargs)

        else:

            warnings.warn(

                f'The type "{type(value).__name__}" (value: "{value}") '

                f'is not in the list of possible types of typing.Union '

                f'(dataclass: {self.cls.__name__}, field: {self.field.name}). '

                f'Value cannot be serialized properly.')

        return super()._serialize(value, attr, obj, **kwargs)

    def _deserialize(self, value, attr, data, **kwargs):

        tmp_value = deepcopy(value)

        if isinstance(tmp_value, dict) and '__type' in tmp_value:

            dc_name = tmp_value['__type']

            for type_, schema_ in self.desc.items():

                if is_dataclass(type_) and type_.__name__ == dc_name:

                    del tmp_value['__type']

                    return schema_._deserialize(tmp_value, attr, data, **kwargs)

        for type_, schema_ in self.desc.items():

            if isinstance(tmp_value, _get_type_origin(type_)):

                return schema_._deserialize(tmp_value, attr, data, **kwargs)

        else:

            warnings.warn(

                f'The type "{type(tmp_value).__name__}" (value: "{tmp_value}") '

                f'is not in the list of possible types of typing.Union '

                f'(dataclass: {self.cls.__name__}, field: {self.field.name}). '

                f'Value cannot be deserialized properly.')

        return super()._deserialize(tmp_value, attr, data, **kwargs)

TYPES = {

    typing.Mapping: fields.Mapping,

    typing.MutableMapping: fields.Mapping,

    typing.List: fields.List,

    typing.Dict: fields.Dict,

    typing.Tuple: fields.Tuple,

    typing.Callable: fields.Function,

    typing.Any: fields.Raw,

    dict: fields.Dict,

    list: fields.List,

    tuple: fields.Tuple,

    str: fields.Str,

    int: fields.Int,

    float: fields.Float,

    bool: fields.Bool,

    datetime: _TimestampField,

    UUID: fields.UUID,

    Decimal: fields.Decimal,

    CatchAllVar: fields.Dict,

}

A = typing.TypeVar('A')

JsonData = typing.Union[str, bytes, bytearray]

TEncoded = typing.Dict[str, typing.Any]

TOneOrMulti = typing.Union[typing.List[A], A]

TOneOrMultiEncoded = typing.Union[typing.List[TEncoded], TEncoded]

if sys.version_info >= (3, 7):

    class SchemaF(Schema, typing.Generic[A]):

        """Lift Schema into a type constructor"""

        def __init__(self, *args, **kwargs):

            """

            Raises exception because this class should not be inherited.

            This class is helper only.

            """

            super().__init__(*args, **kwargs)

            raise NotImplementedError()

        @typing.overload

        def dump(self, obj: typing.List[A], many: bool = None) -> typing.List[

            TEncoded]:  # type: ignore

            # mm has the wrong return type annotation (dict) so we can ignore the mypy error

            pass

        @typing.overload

        def dump(self, obj: A, many: bool = None) -> TEncoded:

            pass

        def dump(self, obj: TOneOrMulti,

                 many: bool = None) -> TOneOrMultiEncoded:

            pass

        @typing.overload

        def dumps(self, obj: typing.List[A], many: bool = None, *args,

                  **kwargs) -> str:

            pass

        @typing.overload

        def dumps(self, obj: A, many: bool = None, *args, **kwargs) -> str:

            pass

        def dumps(self, obj: TOneOrMulti, many: bool = None, *args,

                  **kwargs) -> str:

            pass

        @typing.overload  # type: ignore

        def load(self, data: typing.List[TEncoded],

                 many: bool = True, partial: bool = None,

                 unknown: str = None) -> \

                typing.List[A]:

            # ignore the mypy error of the decorator because mm does not define lists as an allowed input type

            pass

        @typing.overload

        def load(self, data: TEncoded,

                 many: None = None, partial: bool = None,

                 unknown: str = None) -> A:

            pass

        def load(self, data: TOneOrMultiEncoded,

                 many: bool = None, partial: bool = None,

                 unknown: str = None) -> TOneOrMulti:

            pass

        @typing.overload  # type: ignore

        def loads(self, json_data: JsonData,  # type: ignore

                  many: bool = True, partial: bool = None, unknown: str = None,

                  **kwargs) -> typing.List[A]:

            # ignore the mypy error of the decorator because mm does not define bytes as correct input data

            # mm has the wrong return type annotation (dict) so we can ignore the mypy error

            # for the return type overlap

            pass

        @typing.overload

        def loads(self, json_data: JsonData,

                  many: None = None, partial: bool = None, unknown: str = None,

                  **kwargs) -> A:

            pass

        def loads(self, json_data: JsonData,

                  many: bool = None, partial: bool = None, unknown: str = None,

                  **kwargs) -> TOneOrMulti:

            pass

    SchemaType = SchemaF[A]

else:

    SchemaType = Schema

def build_type(type_, options, mixin, field, cls):

    def inner(type_, options):

        while True:

            if not _is_new_type(type_):

                break

            type_ = type_.__supertype__

        if is_dataclass(type_):

            if _issubclass_safe(type_, mixin):

                options['field_many'] = bool(

                    _is_supported_generic(field.type) and _is_collection(

                        field.type))

                return fields.Nested(type_.schema(), **options)

            else:

                warnings.warn(f"Nested dataclass field {field.name} of type "

                              f"{field.type} detected in "

                              f"{cls.__name__} that is not an instance of "

                              f"dataclass_json. Did you mean to recursively "

                              f"serialize this field? If so, make sure to "

                              f"augment {type_} with either the "

                              f"`dataclass_json` decorator or mixin.")

                return fields.Field(**options)

        origin = getattr(type_, '__origin__', type_)

        args = [inner(a, {}) for a in getattr(type_, '__args__', []) if

                a is not type(None)]

        if _is_optional(type_):

            options["allow_none"] = True

        if origin in TYPES:

            return TYPES[origin](*args, **options)

        if _issubclass_safe(origin, Enum):

            return EnumField(enum=origin, by_value=True, *args, **options)

        if is_union_type(type_):

            union_types = [a for a in getattr(type_, '__args__', []) if

                           a is not type(None)]

            union_desc = dict(zip(union_types, args))

            return _UnionField(union_desc, cls, field, **options)

        warnings.warn(

            f"Unknown type {type_} at {cls.__name__}.{field.name}: {field.type} "

            f"It's advised to pass the correct marshmallow type to `mm_field`.")

        return fields.Field(**options)

    return inner(type_, options)

def schema(cls, mixin, infer_missing):

    schema = {}

    overrides = _user_overrides_or_exts(cls)

    # TODO check the undefined parameters and add the proper schema action

    #  https://marshmallow.readthedocs.io/en/stable/quickstart.html

    for field in dc_fields(cls):

        metadata = (field.metadata or {}).get('dataclasses_json', {})

        metadata = overrides[field.name]

        if metadata.mm_field is not None:

            schema[field.name] = metadata.mm_field

        else:

            type_ = field.type

            options = {}

            missing_key = 'missing' if infer_missing else 'default'

            if field.default is not MISSING:

                options[missing_key] = field.default

            elif field.default_factory is not MISSING:

                options[missing_key] = field.default_factory

            if options.get(missing_key, ...) is None:

                options['allow_none'] = True

            if _is_optional(type_):

                options.setdefault(missing_key, None)

                options['allow_none'] = True

                if len(type_.__args__) == 2:

                    # Union[str, int, None] is optional too, but it has more than 1 typed field.

                    type_ = type_.__args__[0]

            if metadata.letter_case is not None:

                options['data_key'] = metadata.letter_case(field.name)

            t = build_type(type_, options, mixin, field, cls)

            # if type(t) is not fields.Field:  # If we use `isinstance` we would return nothing.

            if field.type != typing.Optional[CatchAllVar]:

                schema[field.name] = t

    return schema

def build_schema(cls: typing.Type[A],

                 mixin,

                 infer_missing,

                 partial) -> typing.Type[SchemaType]:

    Meta = type('Meta',

                (),

                {'fields': tuple(field.name for field in dc_fields(cls)

                                 if

                                 field.name != 'dataclass_json_config' and field.type !=

                                 typing.Optional[CatchAllVar]),

                 # TODO #180

                 # 'render_module': global_config.json_module

                 })

    @post_load

    def make_instance(self, kvs, **kwargs):

        return _decode_dataclass(cls, kvs, partial)

    def dumps(self, *args, **kwargs):

        if 'cls' not in kwargs:

            kwargs['cls'] = _ExtendedEncoder

        return Schema.dumps(self, *args, **kwargs)

    def dump(self, obj, *, many=None):

        many = self.many if many is None else bool(many)

        dumped = Schema.dump(self, obj, many=many)

        # TODO This is hacky, but the other option I can think of is to generate a different schema

        #  depending on dump and load, which is even more hacky

        # The only problem is the catch all field, we can't statically create a schema for it

        # so we just update the dumped dict

        if many:

            for i, _obj in enumerate(obj):

                dumped[i].update(

                    _handle_undefined_parameters_safe(cls=_obj, kvs={},

                                                      usage="dump"))

        else:

            dumped.update(_handle_undefined_parameters_safe(cls=obj, kvs={},

                                                            usage="dump"))

        return dumped

    schema_ = schema(cls, mixin, infer_missing)

    DataClassSchema: typing.Type[SchemaType] = type(

        f'{cls.__name__.capitalize()}Schema',

        (Schema,),

        {'Meta': Meta,

         f'make_{cls.__name__.lower()}': make_instance,

         'dumps': dumps,

         'dump': dump,

         **schema_})

    return DataClassSchema

Variables

A
JsonData
SchemaType
TEncoded
TOneOrMulti
TOneOrMultiEncoded
TYPES

Functions

build_schema

def build_schema(
    cls: Type[~A],
    mixin,
    infer_missing,
    partial
) -> Type[dataclasses_json.mm.SchemaF[~A]]
View Source
def build_schema(cls: typing.Type[A],

                 mixin,

                 infer_missing,

                 partial) -> typing.Type[SchemaType]:

    Meta = type('Meta',

                (),

                {'fields': tuple(field.name for field in dc_fields(cls)

                                 if

                                 field.name != 'dataclass_json_config' and field.type !=

                                 typing.Optional[CatchAllVar]),

                 # TODO #180

                 # 'render_module': global_config.json_module

                 })

    @post_load

    def make_instance(self, kvs, **kwargs):

        return _decode_dataclass(cls, kvs, partial)

    def dumps(self, *args, **kwargs):

        if 'cls' not in kwargs:

            kwargs['cls'] = _ExtendedEncoder

        return Schema.dumps(self, *args, **kwargs)

    def dump(self, obj, *, many=None):

        many = self.many if many is None else bool(many)

        dumped = Schema.dump(self, obj, many=many)

        # TODO This is hacky, but the other option I can think of is to generate a different schema

        #  depending on dump and load, which is even more hacky

        # The only problem is the catch all field, we can't statically create a schema for it

        # so we just update the dumped dict

        if many:

            for i, _obj in enumerate(obj):

                dumped[i].update(

                    _handle_undefined_parameters_safe(cls=_obj, kvs={},

                                                      usage="dump"))

        else:

            dumped.update(_handle_undefined_parameters_safe(cls=obj, kvs={},

                                                            usage="dump"))

        return dumped

    schema_ = schema(cls, mixin, infer_missing)

    DataClassSchema: typing.Type[SchemaType] = type(

        f'{cls.__name__.capitalize()}Schema',

        (Schema,),

        {'Meta': Meta,

         f'make_{cls.__name__.lower()}': make_instance,

         'dumps': dumps,

         'dump': dump,

         **schema_})

    return DataClassSchema

build_type

def build_type(
    type_,
    options,
    mixin,
    field,
    cls
)
View Source
def build_type(type_, options, mixin, field, cls):

    def inner(type_, options):

        while True:

            if not _is_new_type(type_):

                break

            type_ = type_.__supertype__

        if is_dataclass(type_):

            if _issubclass_safe(type_, mixin):

                options['field_many'] = bool(

                    _is_supported_generic(field.type) and _is_collection(

                        field.type))

                return fields.Nested(type_.schema(), **options)

            else:

                warnings.warn(f"Nested dataclass field {field.name} of type "

                              f"{field.type} detected in "

                              f"{cls.__name__} that is not an instance of "

                              f"dataclass_json. Did you mean to recursively "

                              f"serialize this field? If so, make sure to "

                              f"augment {type_} with either the "

                              f"`dataclass_json` decorator or mixin.")

                return fields.Field(**options)

        origin = getattr(type_, '__origin__', type_)

        args = [inner(a, {}) for a in getattr(type_, '__args__', []) if

                a is not type(None)]

        if _is_optional(type_):

            options["allow_none"] = True

        if origin in TYPES:

            return TYPES[origin](*args, **options)

        if _issubclass_safe(origin, Enum):

            return EnumField(enum=origin, by_value=True, *args, **options)

        if is_union_type(type_):

            union_types = [a for a in getattr(type_, '__args__', []) if

                           a is not type(None)]

            union_desc = dict(zip(union_types, args))

            return _UnionField(union_desc, cls, field, **options)

        warnings.warn(

            f"Unknown type {type_} at {cls.__name__}.{field.name}: {field.type} "

            f"It's advised to pass the correct marshmallow type to `mm_field`.")

        return fields.Field(**options)

    return inner(type_, options)

schema

def schema(
    cls,
    mixin,
    infer_missing
)
View Source
def schema(cls, mixin, infer_missing):

    schema = {}

    overrides = _user_overrides_or_exts(cls)

    # TODO check the undefined parameters and add the proper schema action

    #  https://marshmallow.readthedocs.io/en/stable/quickstart.html

    for field in dc_fields(cls):

        metadata = (field.metadata or {}).get('dataclasses_json', {})

        metadata = overrides[field.name]

        if metadata.mm_field is not None:

            schema[field.name] = metadata.mm_field

        else:

            type_ = field.type

            options = {}

            missing_key = 'missing' if infer_missing else 'default'

            if field.default is not MISSING:

                options[missing_key] = field.default

            elif field.default_factory is not MISSING:

                options[missing_key] = field.default_factory

            if options.get(missing_key, ...) is None:

                options['allow_none'] = True

            if _is_optional(type_):

                options.setdefault(missing_key, None)

                options['allow_none'] = True

                if len(type_.__args__) == 2:

                    # Union[str, int, None] is optional too, but it has more than 1 typed field.

                    type_ = type_.__args__[0]

            if metadata.letter_case is not None:

                options['data_key'] = metadata.letter_case(field.name)

            t = build_type(type_, options, mixin, field, cls)

            # if type(t) is not fields.Field:  # If we use `isinstance` we would return nothing.

            if field.type != typing.Optional[CatchAllVar]:

                schema[field.name] = t

    return schema

Classes

SchemaF

class SchemaF(
    *args,
    **kwargs
)

Lift Schema into a type constructor

View Source
    class SchemaF(Schema, typing.Generic[A]):

        """Lift Schema into a type constructor"""

        def __init__(self, *args, **kwargs):

            """

            Raises exception because this class should not be inherited.

            This class is helper only.

            """

            super().__init__(*args, **kwargs)

            raise NotImplementedError()

        @typing.overload

        def dump(self, obj: typing.List[A], many: bool = None) -> typing.List[

            TEncoded]:  # type: ignore

            # mm has the wrong return type annotation (dict) so we can ignore the mypy error

            pass

        @typing.overload

        def dump(self, obj: A, many: bool = None) -> TEncoded:

            pass

        def dump(self, obj: TOneOrMulti,

                 many: bool = None) -> TOneOrMultiEncoded:

            pass

        @typing.overload

        def dumps(self, obj: typing.List[A], many: bool = None, *args,

                  **kwargs) -> str:

            pass

        @typing.overload

        def dumps(self, obj: A, many: bool = None, *args, **kwargs) -> str:

            pass

        def dumps(self, obj: TOneOrMulti, many: bool = None, *args,

                  **kwargs) -> str:

            pass

        @typing.overload  # type: ignore

        def load(self, data: typing.List[TEncoded],

                 many: bool = True, partial: bool = None,

                 unknown: str = None) -> \

                typing.List[A]:

            # ignore the mypy error of the decorator because mm does not define lists as an allowed input type

            pass

        @typing.overload

        def load(self, data: TEncoded,

                 many: None = None, partial: bool = None,

                 unknown: str = None) -> A:

            pass

        def load(self, data: TOneOrMultiEncoded,

                 many: bool = None, partial: bool = None,

                 unknown: str = None) -> TOneOrMulti:

            pass

        @typing.overload  # type: ignore

        def loads(self, json_data: JsonData,  # type: ignore

                  many: bool = True, partial: bool = None, unknown: str = None,

                  **kwargs) -> typing.List[A]:

            # ignore the mypy error of the decorator because mm does not define bytes as correct input data

            # mm has the wrong return type annotation (dict) so we can ignore the mypy error

            # for the return type overlap

            pass

        @typing.overload

        def loads(self, json_data: JsonData,

                  many: None = None, partial: bool = None, unknown: str = None,

                  **kwargs) -> A:

            pass

        def loads(self, json_data: JsonData,

                  many: bool = None, partial: bool = None, unknown: str = None,

                  **kwargs) -> TOneOrMulti:

            pass

Ancestors (in MRO)

  • marshmallow.schema.Schema
  • marshmallow.base.SchemaABC
  • typing.Generic

Class variables

Meta
OPTIONS_CLASS
TYPE_MAPPING
error_messages
opts

Static methods

from_dict
def from_dict(
    fields: Dict[str, Union[marshmallow.fields.Field, type]],
    *,
    name: str = 'GeneratedSchema'
) -> type

Generate a Schema class given a dictionary of fields.

.. code-block:: python

from marshmallow import Schema, fields

PersonSchema = Schema.from_dict({"name": fields.Str()})
print(PersonSchema().load({"name": "David"}))  # => {'name': 'David'}

Generated schemas are not added to the class registry and therefore cannot be referred to by name in Nested fields.

:param dict fields: Dictionary mapping field names to field instances. :param str name: Optional name for the class, which will appear in the repr for the class.

.. versionadded:: 3.0.0

View Source
    @classmethod

    def from_dict(

        cls,

        fields: typing.Dict[str, typing.Union[ma_fields.Field, type]],

        *,

        name: str = "GeneratedSchema"

    ) -> type:

        """Generate a `Schema` class given a dictionary of fields.

        .. code-block:: python

            from marshmallow import Schema, fields

            PersonSchema = Schema.from_dict({"name": fields.Str()})

            print(PersonSchema().load({"name": "David"}))  # => {'name': 'David'}

        Generated schemas are not added to the class registry and therefore cannot

        be referred to by name in `Nested` fields.

        :param dict fields: Dictionary mapping field names to field instances.

        :param str name: Optional name for the class, which will appear in

            the ``repr`` for the class.

        .. versionadded:: 3.0.0

        """

        attrs = fields.copy()

        attrs["Meta"] = type(

            "GeneratedMeta", (getattr(cls, "Meta", object),), {"register": False}

        )

        schema_cls = type(name, (cls,), attrs)

        return schema_cls

Instance variables

dict_class
set_class

Methods

dump
def dump(
    self,
    obj: Union[List[~A], ~A],
    many: bool = None
) -> Union[List[Dict[str, Any]], Dict[str, Any]]

Serialize an object to native Python data types according to this Schema's fields.

:param obj: The object to serialize. :param many: Whether to serialize obj as a collection. If None, the value for self.many is used. :return: A dict of serialized data :rtype: dict

.. versionadded:: 1.0.0 .. versionchanged:: 3.0.0b7 This method returns the serialized data rather than a (data, errors) duple. A :exc:ValidationError <marshmallow.exceptions.ValidationError> is raised if obj is invalid. .. versionchanged:: 3.0.0rc9 Validation no longer occurs upon serialization.

View Source
        def dump(self, obj: TOneOrMulti,

                 many: bool = None) -> TOneOrMultiEncoded:

            pass
dumps
def dumps(
    self,
    obj: Union[List[~A], ~A],
    many: bool = None,
    *args,
    **kwargs
) -> str

Same as :meth:dump, except return a JSON-encoded string.

:param obj: The object to serialize. :param many: Whether to serialize obj as a collection. If None, the value for self.many is used. :return: A json string :rtype: str

.. versionadded:: 1.0.0 .. versionchanged:: 3.0.0b7 This method returns the serialized data rather than a (data, errors) duple. A :exc:ValidationError <marshmallow.exceptions.ValidationError> is raised if obj is invalid.

View Source
        def dumps(self, obj: TOneOrMulti, many: bool = None, *args,

                  **kwargs) -> str:

            pass
get_attribute
def get_attribute(
    self,
    obj: Any,
    attr: str,
    default: Any
)

Defines how to pull values from an object to serialize.

.. versionadded:: 2.0.0

.. versionchanged:: 3.0.0a1 Changed position of obj and attr.

View Source
    def get_attribute(self, obj: typing.Any, attr: str, default: typing.Any):

        """Defines how to pull values from an object to serialize.

        .. versionadded:: 2.0.0

        .. versionchanged:: 3.0.0a1

            Changed position of ``obj`` and ``attr``.

        """

        return get_value(obj, attr, default)
handle_error
def handle_error(
    self,
    error: marshmallow.exceptions.ValidationError,
    data: Any,
    *,
    many: bool,
    **kwargs
)

Custom error handler function for the schema.

:param error: The ValidationError raised during (de)serialization. :param data: The original input data. :param many: Value of many on dump or load. :param partial: Value of partial on load.

.. versionadded:: 2.0.0

.. versionchanged:: 3.0.0rc9 Receives many and partial (on deserialization) as keyword arguments.

View Source
    def handle_error(

        self, error: ValidationError, data: typing.Any, *, many: bool, **kwargs

    ):

        """Custom error handler function for the schema.

        :param error: The `ValidationError` raised during (de)serialization.

        :param data: The original input data.

        :param many: Value of ``many`` on dump or load.

        :param partial: Value of ``partial`` on load.

        .. versionadded:: 2.0.0

        .. versionchanged:: 3.0.0rc9

            Receives `many` and `partial` (on deserialization) as keyword arguments.

        """

        pass
load
def load(
    self,
    data: Union[List[Dict[str, Any]], Dict[str, Any]],
    many: bool = None,
    partial: bool = None,
    unknown: str = None
) -> Union[List[~A], ~A]

Deserialize a data structure to an object defined by this Schema's fields.

:param data: The data to deserialize. :param many: Whether to deserialize data as a collection. If None, the value for self.many is used. :param partial: Whether to ignore missing fields and not require any fields declared. Propagates down to Nested fields as well. If its value is an iterable, only missing fields listed in that iterable will be ignored. Use dot delimiters to specify nested fields. :param unknown: Whether to exclude, include, or raise an error for unknown fields in the data. Use EXCLUDE, INCLUDE or RAISE. If None, the value for self.unknown is used. :return: Deserialized data

.. versionadded:: 1.0.0 .. versionchanged:: 3.0.0b7 This method returns the deserialized data rather than a (data, errors) duple. A :exc:ValidationError <marshmallow.exceptions.ValidationError> is raised if invalid data are passed.

View Source
        def load(self, data: TOneOrMultiEncoded,

                 many: bool = None, partial: bool = None,

                 unknown: str = None) -> TOneOrMulti:

            pass
loads
def loads(
    self,
    json_data: Union[str, bytes, bytearray],
    many: bool = None,
    partial: bool = None,
    unknown: str = None,
    **kwargs
) -> Union[List[~A], ~A]

Same as :meth:load, except it takes a JSON string as input.

:param json_data: A JSON string of the data to deserialize. :param many: Whether to deserialize obj as a collection. If None, the value for self.many is used. :param partial: Whether to ignore missing fields and not require any fields declared. Propagates down to Nested fields as well. If its value is an iterable, only missing fields listed in that iterable will be ignored. Use dot delimiters to specify nested fields. :param unknown: Whether to exclude, include, or raise an error for unknown fields in the data. Use EXCLUDE, INCLUDE or RAISE. If None, the value for self.unknown is used. :return: Deserialized data

.. versionadded:: 1.0.0 .. versionchanged:: 3.0.0b7 This method returns the deserialized data rather than a (data, errors) duple. A :exc:ValidationError <marshmallow.exceptions.ValidationError> is raised if invalid data are passed.

View Source
        def loads(self, json_data: JsonData,

                  many: bool = None, partial: bool = None, unknown: str = None,

                  **kwargs) -> TOneOrMulti:

            pass
on_bind_field
def on_bind_field(
    self,
    field_name: str,
    field_obj: marshmallow.fields.Field
) -> None

Hook to modify a field when it is bound to the Schema.

No-op by default.

View Source
    def on_bind_field(self, field_name: str, field_obj: ma_fields.Field) -> None:

        """Hook to modify a field when it is bound to the `Schema`.

        No-op by default.

        """

        return None
validate
def validate(
    self,
    data: Mapping,
    *,
    many: bool = None,
    partial: Union[bool, Sequence[str], Set[str]] = None
) -> Dict[str, List[str]]

Validate data against the schema, returning a dictionary of validation errors.

:param data: The data to validate. :param many: Whether to validate data as a collection. If None, the value for self.many is used. :param partial: Whether to ignore missing fields and not require any fields declared. Propagates down to Nested fields as well. If its value is an iterable, only missing fields listed in that iterable will be ignored. Use dot delimiters to specify nested fields. :return: A dictionary of validation errors.

.. versionadded:: 1.1.0

View Source
    def validate(

        self,

        data: typing.Mapping,

        *,

        many: bool = None,

        partial: typing.Union[bool, types.StrSequenceOrSet] = None

    ) -> typing.Dict[str, typing.List[str]]:

        """Validate `data` against the schema, returning a dictionary of

        validation errors.

        :param data: The data to validate.

        :param many: Whether to validate `data` as a collection. If `None`, the

            value for `self.many` is used.

        :param partial: Whether to ignore missing fields and not require

            any fields declared. Propagates down to ``Nested`` fields as well. If

            its value is an iterable, only missing fields listed in that iterable

            will be ignored. Use dot delimiters to specify nested fields.

        :return: A dictionary of validation errors.

        .. versionadded:: 1.1.0

        """

        try:

            self._do_load(data, many=many, partial=partial, postprocess=False)

        except ValidationError as exc:

            return typing.cast(typing.Dict[str, typing.List[str]], exc.messages)

        return {}