Esempio n. 1
0
 def __init__(self,
              extra=None,
              only=(),
              exclude=(),
              prefix='',
              strict=None,
              many=False,
              context=None,
              load_only=(),
              dump_only=(),
              partial=False):
     # copy declared fields from metaclass
     self.declared_fields = copy.deepcopy(self._declared_fields)
     self.many = many
     self.only = only
     self.exclude = exclude
     self.prefix = prefix
     self.strict = strict if strict is not None else self.opts.strict
     self.ordered = self.opts.ordered
     self.load_only = set(load_only) or set(self.opts.load_only)
     self.dump_only = set(dump_only) or set(self.opts.dump_only)
     self.partial = partial
     #: Dictionary mapping field_names -> :class:`Field` objects
     self.fields = self.dict_class()
     #: Callable marshalling object
     self._marshal = marshalling.Marshaller(prefix=self.prefix)
     #: Callable unmarshalling object
     self._unmarshal = marshalling.Unmarshaller()
     if extra:
         warnings.warn(
             'The `extra` argument is deprecated. Use a post_dump '
             'method to add additional data instead.', DeprecationWarning)
     self.extra = extra
     self.context = context or {}
     self._normalize_nested_options()
     self._types_seen = set()
     self._update_fields(many=many)
Esempio n. 2
0
    def _do_load(
        self,
        data,
        many=None,
        partial=None,
        unknown=None,
        postprocess=True,
    ):
        """Deserialize `data`, returning the deserialized result.

        :param data: The data to deserialize.
        :param bool many: Whether to deserialize `data` as a collection. If `None`, the
            value for `self.many` is used.
        :param bool|tuple partial: Whether to validate required fields. If its value is an iterable,
            only fields listed in that iterable will be ignored will be allowed missing.
            If `True`, all fields will be allowed missing.
            If `None`, the value for `self.partial` is used.
        :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.
        :param bool postprocess: Whether to run post_load methods..
        :return: A dict of deserialized data
        :rtype: dict
        """
        # Callable unmarshalling object
        unmarshal = marshalling.Unmarshaller()
        errors = {}
        many = self.many if many is None else bool(many)
        unknown = unknown or self.unknown
        if partial is None:
            partial = self.partial
        if self._has_processors(PRE_LOAD):
            try:
                processed_data = self._invoke_load_processors(
                    PRE_LOAD,
                    data,
                    many,
                    original_data=data,
                )
            except ValidationError as err:
                errors = err.normalized_messages()
                result = None
        else:
            processed_data = data
        if not errors:
            result = unmarshal(
                processed_data,
                self.fields,
                many=many,
                partial=partial,
                unknown=unknown,
                dict_class=self.dict_class,
                index_errors=self.opts.index_errors,
            )
            self._invoke_field_validators(unmarshal, data=result, many=many)
            errors = unmarshal.errors
            # Run schema-level validation.
            if self._has_processors(VALIDATES_SCHEMA):
                field_errors = bool(errors)
                self._invoke_schema_validators(
                    unmarshal,
                    pass_many=True,
                    data=result,
                    original_data=data,
                    many=many,
                    field_errors=field_errors,
                )
                self._invoke_schema_validators(
                    unmarshal,
                    pass_many=False,
                    data=result,
                    original_data=data,
                    many=many,
                    field_errors=field_errors,
                )
        # Run post processors
        if not errors and postprocess and self._has_processors(POST_LOAD):
            try:
                result = self._invoke_load_processors(
                    POST_LOAD,
                    result,
                    many,
                    original_data=data,
                )
            except ValidationError as err:
                errors = err.normalized_messages()
        if errors:
            exc = ValidationError(errors,
                                  field_names=unmarshal.error_field_names,
                                  data=data,
                                  valid_data=result,
                                  **unmarshal.error_kwargs)
            self.handle_error(exc, data)
            raise exc

        return result
Esempio n. 3
0
    def _do_load(self, data, many=None, partial=None, postprocess=True):
        """Deserialize `data`, returning the deserialized result and a dictonary of
        validation errors.

        :param data: The data to deserialize.
        :param bool many: Whether to deserialize `data` as a collection. If `None`, the
            value for `self.many` is used.
        :param bool|tuple partial: Whether to validate required fields. If its value is an iterable,
            only fields listed in that iterable will be ignored will be allowed missing.
            If `True`, all fields will be allowed missing.
            If `None`, the value for `self.partial` is used.
        :param bool postprocess: Whether to run post_load methods..
        :return: A tuple of the form (`data`, `errors`)
        """
        # Callable unmarshalling object
        unmarshal = marshalling.Unmarshaller()
        errors = {}
        many = self.many if many is None else bool(many)
        if partial is None:
            partial = self.partial
        try:
            processed_data = self._invoke_load_processors(
                PRE_LOAD,
                data,
                many,
                original_data=data)
        except ValidationError as err:
            errors = err.normalized_messages()
            result = None
        if not errors:
            try:
                result = unmarshal(
                    processed_data,
                    self.fields,
                    many=many,
                    partial=partial,
                    dict_class=self.dict_class,
                    index_errors=self.opts.index_errors,
                )
            except ValidationError as error:
                result = error.data
            self._invoke_field_validators(unmarshal, data=result, many=many)
            errors = unmarshal.errors
            field_errors = bool(errors)
            # Run schema-level migration
            try:
                self._invoke_validators(unmarshal, pass_many=True, data=result, original_data=data,
                                        many=many, field_errors=field_errors)
            except ValidationError as err:
                errors.update(err.messages)
            try:
                self._invoke_validators(unmarshal, pass_many=False, data=result, original_data=data,
                                        many=many, field_errors=field_errors)
            except ValidationError as err:
                errors.update(err.messages)
        # Run post processors
        if not errors and postprocess:
            try:
                result = self._invoke_load_processors(
                    POST_LOAD,
                    result,
                    many,
                    original_data=data)
            except ValidationError as err:
                errors = err.normalized_messages()
        if errors:
            # TODO: Remove self.__error_handler__ in a later release
            if self.__error_handler__ and callable(self.__error_handler__):
                self.__error_handler__(errors, data)
            exc = ValidationError(
                errors,
                field_names=unmarshal.error_field_names,
                fields=unmarshal.error_fields,
                data=data,
                **unmarshal.error_kwargs
            )
            self.handle_error(exc, data)
            if self.strict:
                raise exc

        return result, errors
Esempio n. 4
0
    def _do_load(  # noqa:C901
            self, data, many=None, partial=None, unknown=None,
            postprocess=True,
    ):
        errors = {}
        result = None
        processed_data = None
        many = self.many if many is None else bool(many)
        unknown = unknown or self.unknown
        if partial is None:
            partial = self.partial
        if self._has_processors(PRE_LOAD):
            try:
                processed_data = self._invoke_load_processors(
                    PRE_LOAD,
                    data,
                    many,
                    original_data=data,
                )
            except ValidationError as err:
                errors = err.normalized_messages()
        else:
            processed_data = data
        unmarshaller = marshalling.Unmarshaller()
        if not errors:
            result = unmarshaller.deserialize(
                processed_data,
                self._fields,
                many=False,
                partial=partial,
                unknown=unknown,
                dict_class=self.dict_class,
                index_errors=self.opts.index_errors,
            )
            self._invoke_field_validators(unmarshaller, data=result, many=False)
            if self._has_processors(VALIDATES_SCHEMA):
                field_errors = bool(unmarshaller.errors)
                self._invoke_schema_validators(
                    unmarshaller,
                    pass_many=True,
                    data=result,
                    original_data=data,
                    many=many,
                    field_errors=field_errors,
                )
                self._invoke_schema_validators(
                    unmarshaller,
                    pass_many=False,
                    data=result,
                    original_data=data,
                    many=many,
                    field_errors=field_errors,
                )
            errors = unmarshaller.errors
            if not errors and postprocess and self._has_processors(POST_LOAD):
                try:
                    result = self._invoke_load_processors(
                        POST_LOAD,
                        result,
                        many,
                        original_data=data,
                    )
                except ValidationError as err:
                    errors = err.normalized_messages()
        if errors:
            error_field_names = getattr(unmarshaller, 'error_field_names', [])
            exc = ValidationError(
                errors,
                field_names=error_field_names,
                data=data,
                valid_data=result,
                **unmarshaller.error_kwargs
            )
            self.handle_error(exc, data)
            raise exc

        return result