about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/marshmallow/error_store.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/marshmallow/error_store.py')
-rw-r--r--.venv/lib/python3.12/site-packages/marshmallow/error_store.py60
1 files changed, 60 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/marshmallow/error_store.py b/.venv/lib/python3.12/site-packages/marshmallow/error_store.py
new file mode 100644
index 00000000..61320ab2
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/marshmallow/error_store.py
@@ -0,0 +1,60 @@
+"""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 marshmallow.exceptions import SCHEMA
+
+
+class ErrorStore:
+    def __init__(self):
+        #: Dictionary of errors stored during serialization
+        self.errors = {}
+
+    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):  # noqa: PLR0911
+    """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 errors2.items():
+                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 isinstance(errors2, dict):
+        return dict(errors2, **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))})
+    return [errors1, errors2]