12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- # -*- coding: utf-8 -*-
- """Utilities for storing collections of error messages.
- .. warning::
- This module is treated as private API.
- Users should not need to use this module directly.
- """
- from __future__ import unicode_literals
- from marshmallow.compat import iteritems
- from marshmallow.exceptions import SCHEMA
- class ErrorStore(object):
- def __init__(self):
- #: Dictionary of errors stored during serialization
- self.errors = {}
- #: True while (de)serializing a collection
- self._pending = False
- def store_error(self, messages, field_name=SCHEMA, index=None):
- # field error -> store/merge error messages under field name key
- # schema error -> if string or list, store/merge under _schema key
- # -> if dict, store/merge with other top-level keys
- if field_name != SCHEMA or not isinstance(messages, dict):
- messages = {field_name: messages}
- if index is not None:
- messages = {index: messages}
- self.errors = merge_errors(self.errors, messages)
- def merge_errors(errors1, errors2):
- """Deeply merge two error messages.
- The format of ``errors1`` and ``errors2`` matches the ``message``
- parameter of :exc:`marshmallow.exceptions.ValidationError`.
- """
- if not errors1:
- return errors2
- if not errors2:
- return errors1
- if isinstance(errors1, list):
- if isinstance(errors2, list):
- return errors1 + errors2
- if isinstance(errors2, dict):
- return dict(
- errors2,
- **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))}
- )
- return errors1 + [errors2]
- if isinstance(errors1, dict):
- if isinstance(errors2, list):
- return dict(
- errors1,
- **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)}
- )
- if isinstance(errors2, dict):
- errors = dict(errors1)
- for key, val in iteritems(errors2):
- if key in errors:
- errors[key] = merge_errors(errors[key], val)
- else:
- errors[key] = val
- return errors
- return dict(
- errors1,
- **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)}
- )
- if isinstance(errors2, list):
- return [errors1] + errors2 if errors2 else errors1
- if isinstance(errors2, dict):
- return dict(
- errors2,
- **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))}
- )
- return [errors1, errors2]
|