marshmallow 4.1.1__py3-none-any.whl → 4.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- marshmallow/error_store.py +23 -12
- marshmallow/fields.py +9 -4
- marshmallow/schema.py +1 -1
- {marshmallow-4.1.1.dist-info → marshmallow-4.2.0.dist-info}/METADATA +2 -2
- {marshmallow-4.1.1.dist-info → marshmallow-4.2.0.dist-info}/RECORD +7 -7
- {marshmallow-4.1.1.dist-info → marshmallow-4.2.0.dist-info}/WHEEL +0 -0
- {marshmallow-4.1.1.dist-info → marshmallow-4.2.0.dist-info}/licenses/LICENSE +0 -0
marshmallow/error_store.py
CHANGED
|
@@ -18,6 +18,7 @@ class ErrorStore:
|
|
|
18
18
|
# field error -> store/merge error messages under field name key
|
|
19
19
|
# schema error -> if string or list, store/merge under _schema key
|
|
20
20
|
# -> if dict, store/merge with other top-level keys
|
|
21
|
+
messages = copy_containers(messages)
|
|
21
22
|
if field_name != SCHEMA or not isinstance(messages, dict):
|
|
22
23
|
messages = {field_name: messages}
|
|
23
24
|
if index is not None:
|
|
@@ -25,6 +26,14 @@ class ErrorStore:
|
|
|
25
26
|
self.errors = merge_errors(self.errors, messages)
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
def copy_containers(errors):
|
|
30
|
+
if isinstance(errors, list):
|
|
31
|
+
return [copy_containers(val) for val in errors]
|
|
32
|
+
if isinstance(errors, dict):
|
|
33
|
+
return {key: copy_containers(val) for key, val in errors.items()}
|
|
34
|
+
return errors
|
|
35
|
+
|
|
36
|
+
|
|
28
37
|
def merge_errors(errors1, errors2): # noqa: PLR0911
|
|
29
38
|
"""Deeply merge two error messages.
|
|
30
39
|
|
|
@@ -37,24 +46,26 @@ def merge_errors(errors1, errors2): # noqa: PLR0911
|
|
|
37
46
|
return errors1
|
|
38
47
|
if isinstance(errors1, list):
|
|
39
48
|
if isinstance(errors2, list):
|
|
40
|
-
|
|
49
|
+
errors1.extend(errors2)
|
|
50
|
+
return errors1
|
|
41
51
|
if isinstance(errors2, dict):
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
errors2[SCHEMA] = merge_errors(errors1, errors2.get(SCHEMA))
|
|
53
|
+
return errors2
|
|
54
|
+
errors1.append(errors2)
|
|
55
|
+
return errors1
|
|
44
56
|
if isinstance(errors1, dict):
|
|
45
|
-
if isinstance(errors2, list):
|
|
46
|
-
return dict(errors1, **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)})
|
|
47
57
|
if isinstance(errors2, dict):
|
|
48
|
-
errors = dict(errors1)
|
|
49
58
|
for key, val in errors2.items():
|
|
50
|
-
if key in
|
|
51
|
-
|
|
59
|
+
if key in errors1:
|
|
60
|
+
errors1[key] = merge_errors(errors1[key], val)
|
|
52
61
|
else:
|
|
53
|
-
|
|
54
|
-
return
|
|
55
|
-
|
|
62
|
+
errors1[key] = val
|
|
63
|
+
return errors1
|
|
64
|
+
errors1[SCHEMA] = merge_errors(errors1.get(SCHEMA), errors2)
|
|
65
|
+
return errors1
|
|
56
66
|
if isinstance(errors2, list):
|
|
57
67
|
return [errors1, *errors2]
|
|
58
68
|
if isinstance(errors2, dict):
|
|
59
|
-
|
|
69
|
+
errors2[SCHEMA] = merge_errors(errors1, errors2.get(SCHEMA))
|
|
70
|
+
return errors2
|
|
60
71
|
return [errors1, errors2]
|
marshmallow/fields.py
CHANGED
|
@@ -482,6 +482,9 @@ class Nested(Field):
|
|
|
482
482
|
:param only: A list or tuple of fields to marshal. If `None`, all fields are marshalled.
|
|
483
483
|
This parameter takes precedence over ``exclude``.
|
|
484
484
|
:param many: Whether the field is a collection of objects.
|
|
485
|
+
If `None` (default), and nested `Schema` instance is provided, ``many`` is not overridden.
|
|
486
|
+
If `None` (default), and `Schema` subclass is provided, schema instance sets ``many`` as False.
|
|
487
|
+
If `True | False` nested `[nested_field].schema.many` is overridden.
|
|
485
488
|
:param unknown: Whether to exclude, include, or raise an error for unknown
|
|
486
489
|
fields in the data. Use `EXCLUDE`, `INCLUDE` or `RAISE`.
|
|
487
490
|
:param kwargs: The same keyword arguments that :class:`Field` receives.
|
|
@@ -502,7 +505,7 @@ class Nested(Field):
|
|
|
502
505
|
*,
|
|
503
506
|
only: types.StrSequenceOrSet | None = None,
|
|
504
507
|
exclude: types.StrSequenceOrSet = (),
|
|
505
|
-
many: bool =
|
|
508
|
+
many: bool | None = None,
|
|
506
509
|
unknown: types.UnknownOption | None = None,
|
|
507
510
|
**kwargs: Unpack[_BaseFieldKwargs],
|
|
508
511
|
):
|
|
@@ -537,7 +540,7 @@ class Nested(Field):
|
|
|
537
540
|
|
|
538
541
|
if isinstance(nested, Schema):
|
|
539
542
|
self._schema = copy.copy(nested)
|
|
540
|
-
# Respect only and exclude passed from parent and re-initialize fields
|
|
543
|
+
# Respect only and exclude and many passed from parent and re-initialize fields
|
|
541
544
|
set_class = typing.cast("type[set]", self._schema.set_class)
|
|
542
545
|
if self.only is not None:
|
|
543
546
|
if self._schema.only is not None:
|
|
@@ -548,6 +551,8 @@ class Nested(Field):
|
|
|
548
551
|
if self.exclude:
|
|
549
552
|
original = self._schema.exclude
|
|
550
553
|
self._schema.exclude = set_class(self.exclude) | set_class(original)
|
|
554
|
+
if self.many is not None:
|
|
555
|
+
self._schema.many = self.many
|
|
551
556
|
self._schema._init_fields()
|
|
552
557
|
else:
|
|
553
558
|
if isinstance(nested, type) and issubclass(nested, Schema):
|
|
@@ -558,9 +563,9 @@ class Nested(Field):
|
|
|
558
563
|
f"`Schema`, not {nested.__class__}."
|
|
559
564
|
)
|
|
560
565
|
else:
|
|
561
|
-
schema_class = class_registry.get_class(nested, all=False)
|
|
566
|
+
schema_class = class_registry.get_class(nested, all=False)
|
|
562
567
|
self._schema = schema_class(
|
|
563
|
-
many=self.many,
|
|
568
|
+
many=bool(self.many),
|
|
564
569
|
only=self.only,
|
|
565
570
|
exclude=self.exclude,
|
|
566
571
|
load_only=self._nested_normalized_option("load_only"),
|
marshmallow/schema.py
CHANGED
|
@@ -341,7 +341,7 @@ class Schema(metaclass=SchemaMeta):
|
|
|
341
341
|
|
|
342
342
|
class MySchema2(Schema):
|
|
343
343
|
# Type checkers will check attributes
|
|
344
|
-
class Meta(Schema.
|
|
344
|
+
class Meta(Schema.Meta):
|
|
345
345
|
additional = True # Incompatible types in assignment
|
|
346
346
|
|
|
347
347
|
.. versionremoved:: 3.0.0b7 Remove ``strict``.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marshmallow
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: A lightweight library for converting complex datatypes to and from native Python datatypes.
|
|
5
5
|
Author-email: Steven Loria <oss@stevenloria.com>
|
|
6
6
|
Maintainer-email: Steven Loria <oss@stevenloria.com>, Jérôme Lafréchoux <jerome@jolimont.fr>, Jared Deckard <jared@shademaps.com>
|
|
@@ -22,7 +22,7 @@ Requires-Dist: marshmallow[tests] ; extra == "dev"
|
|
|
22
22
|
Requires-Dist: tox ; extra == "dev"
|
|
23
23
|
Requires-Dist: pre-commit>=3.5,<5.0 ; extra == "dev"
|
|
24
24
|
Requires-Dist: autodocsumm==0.2.14 ; extra == "docs"
|
|
25
|
-
Requires-Dist: furo==2025.
|
|
25
|
+
Requires-Dist: furo==2025.12.19 ; extra == "docs"
|
|
26
26
|
Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "docs"
|
|
27
27
|
Requires-Dist: sphinx-issues==5.0.1 ; extra == "docs"
|
|
28
28
|
Requires-Dist: sphinx==8.2.3 ; extra == "docs"
|
|
@@ -2,18 +2,18 @@ marshmallow/__init__.py,sha256=9XHBRTrPmbVaU-Z8CWo8nlcf9Z5VvkRD37d1luJuAaM,573
|
|
|
2
2
|
marshmallow/class_registry.py,sha256=HTC9srCEaRsiy5L_vUKQso7IQfeZeRXxZfz4_2NitoM,3029
|
|
3
3
|
marshmallow/constants.py,sha256=v86zJ9nywyN7euiHQw8hJSkuPyeuflUvv0jZVtfre8M,415
|
|
4
4
|
marshmallow/decorators.py,sha256=maOozW03vQ7k9qZqZ_TvTYR3w--kb0NfkAOy1Q0TnZ0,10165
|
|
5
|
-
marshmallow/error_store.py,sha256=
|
|
5
|
+
marshmallow/error_store.py,sha256=5-62el8Ey2w59x8FDhUC5afPu63NXjumKiAagAGL9bY,2444
|
|
6
6
|
marshmallow/exceptions.py,sha256=1L3ZHwQNelWU5ujIPsON5tZ6WQPk64pBGWNyfwhz608,2273
|
|
7
|
-
marshmallow/fields.py,sha256=
|
|
7
|
+
marshmallow/fields.py,sha256=_4RmK6DBd8AJ20-BZsJRWIxyJcO-dk_YX1uRVkqMVEI,72518
|
|
8
8
|
marshmallow/orderedset.py,sha256=adVCG4HtfYFexqZThiFsiwc_i0g8LNWI_bF6cjMz2r0,2953
|
|
9
9
|
marshmallow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
marshmallow/schema.py,sha256=
|
|
10
|
+
marshmallow/schema.py,sha256=OxdZiqVn2d-XKOC2o_FRbXMNox1OOH2yNPN0YSEC6Jc,49955
|
|
11
11
|
marshmallow/types.py,sha256=X2DVsg8H7fFqco5yK2tZDwoqjxRPFjVurEdT-YogNC8,1161
|
|
12
12
|
marshmallow/utils.py,sha256=YI38vVbIwa9T1kPrnW8sF6HmTbi0MFZYNzINKwtbxew,5334
|
|
13
13
|
marshmallow/validate.py,sha256=HUIjC6XOLRpu7PeoL0xEFnvOh9NzZQYQYb-j6XVL8y4,23942
|
|
14
14
|
marshmallow/experimental/__init__.py,sha256=5_iaUmT7_f6QML2LJXmA3xqgk5UBAgCeIazHtC1GVgc,147
|
|
15
15
|
marshmallow/experimental/context.py,sha256=_4KF6sNK6pE0MckyYTGXmU3hJL2tY-TN4oVmE_eDob0,2040
|
|
16
|
-
marshmallow-4.
|
|
17
|
-
marshmallow-4.
|
|
18
|
-
marshmallow-4.
|
|
19
|
-
marshmallow-4.
|
|
16
|
+
marshmallow-4.2.0.dist-info/licenses/LICENSE,sha256=kGtdkFHkJhRMsXOtkRZnuOvQWpxYTCwmwTWzKj7RIAE,1064
|
|
17
|
+
marshmallow-4.2.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
18
|
+
marshmallow-4.2.0.dist-info/METADATA,sha256=giDnUgeTpLh1z0xGcDDQQIHXEQGUE3QtmMDAyUP2OjA,7440
|
|
19
|
+
marshmallow-4.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|