marshmallow 4.0.1__py3-none-any.whl → 4.1.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/constants.py +3 -0
- marshmallow/decorators.py +17 -17
- marshmallow/fields.py +5 -7
- marshmallow/schema.py +3 -1
- marshmallow/types.py +3 -10
- marshmallow/utils.py +4 -10
- {marshmallow-4.0.1.dist-info → marshmallow-4.1.0.dist-info}/METADATA +7 -7
- {marshmallow-4.0.1.dist-info → marshmallow-4.1.0.dist-info}/RECORD +10 -10
- {marshmallow-4.0.1.dist-info → marshmallow-4.1.0.dist-info}/WHEEL +0 -0
- {marshmallow-4.0.1.dist-info → marshmallow-4.1.0.dist-info}/licenses/LICENSE +0 -0
marshmallow/constants.py
CHANGED
marshmallow/decorators.py
CHANGED
|
@@ -68,8 +68,8 @@ Example: ::
|
|
|
68
68
|
from __future__ import annotations
|
|
69
69
|
|
|
70
70
|
import functools
|
|
71
|
+
import typing
|
|
71
72
|
from collections import defaultdict
|
|
72
|
-
from typing import Any, Callable, cast
|
|
73
73
|
|
|
74
74
|
PRE_DUMP = "pre_dump"
|
|
75
75
|
POST_DUMP = "post_dump"
|
|
@@ -80,10 +80,10 @@ VALIDATES_SCHEMA = "validates_schema"
|
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
class MarshmallowHook:
|
|
83
|
-
__marshmallow_hook__: dict[str, list[tuple[bool, Any]]] | None = None
|
|
83
|
+
__marshmallow_hook__: dict[str, list[tuple[bool, typing.Any]]] | None = None
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
def validates(*field_names: str) -> Callable[..., Any]:
|
|
86
|
+
def validates(*field_names: str) -> typing.Callable[..., typing.Any]:
|
|
87
87
|
"""Register a validator method for field(s).
|
|
88
88
|
|
|
89
89
|
:param field_names: Names of the fields that the method validates.
|
|
@@ -95,12 +95,12 @@ def validates(*field_names: str) -> Callable[..., Any]:
|
|
|
95
95
|
|
|
96
96
|
|
|
97
97
|
def validates_schema(
|
|
98
|
-
fn: Callable[..., Any] | None = None,
|
|
98
|
+
fn: typing.Callable[..., typing.Any] | None = None,
|
|
99
99
|
*,
|
|
100
100
|
pass_collection: bool = False,
|
|
101
101
|
pass_original: bool = False,
|
|
102
102
|
skip_on_field_errors: bool = True,
|
|
103
|
-
) -> Callable[..., Any]:
|
|
103
|
+
) -> typing.Callable[..., typing.Any]:
|
|
104
104
|
"""Register a schema-level validator.
|
|
105
105
|
|
|
106
106
|
By default it receives a single object at a time, transparently handling the ``many``
|
|
@@ -131,10 +131,10 @@ def validates_schema(
|
|
|
131
131
|
|
|
132
132
|
|
|
133
133
|
def pre_dump(
|
|
134
|
-
fn: Callable[..., Any] | None = None,
|
|
134
|
+
fn: typing.Callable[..., typing.Any] | None = None,
|
|
135
135
|
*,
|
|
136
136
|
pass_collection: bool = False,
|
|
137
|
-
) -> Callable[..., Any]:
|
|
137
|
+
) -> typing.Callable[..., typing.Any]:
|
|
138
138
|
"""Register a method to invoke before serializing an object. The method
|
|
139
139
|
receives the object to be serialized and returns the processed object.
|
|
140
140
|
|
|
@@ -150,11 +150,11 @@ def pre_dump(
|
|
|
150
150
|
|
|
151
151
|
|
|
152
152
|
def post_dump(
|
|
153
|
-
fn: Callable[..., Any] | None = None,
|
|
153
|
+
fn: typing.Callable[..., typing.Any] | None = None,
|
|
154
154
|
*,
|
|
155
155
|
pass_collection: bool = False,
|
|
156
156
|
pass_original: bool = False,
|
|
157
|
-
) -> Callable[..., Any]:
|
|
157
|
+
) -> typing.Callable[..., typing.Any]:
|
|
158
158
|
"""Register a method to invoke after serializing an object. The method
|
|
159
159
|
receives the serialized object and returns the processed object.
|
|
160
160
|
|
|
@@ -173,10 +173,10 @@ def post_dump(
|
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
def pre_load(
|
|
176
|
-
fn: Callable[..., Any] | None = None,
|
|
176
|
+
fn: typing.Callable[..., typing.Any] | None = None,
|
|
177
177
|
*,
|
|
178
178
|
pass_collection: bool = False,
|
|
179
|
-
) -> Callable[..., Any]:
|
|
179
|
+
) -> typing.Callable[..., typing.Any]:
|
|
180
180
|
"""Register a method to invoke before deserializing an object. The method
|
|
181
181
|
receives the data to be deserialized and returns the processed data.
|
|
182
182
|
|
|
@@ -194,11 +194,11 @@ def pre_load(
|
|
|
194
194
|
|
|
195
195
|
|
|
196
196
|
def post_load(
|
|
197
|
-
fn: Callable[..., Any] | None = None,
|
|
197
|
+
fn: typing.Callable[..., typing.Any] | None = None,
|
|
198
198
|
*,
|
|
199
199
|
pass_collection: bool = False,
|
|
200
200
|
pass_original: bool = False,
|
|
201
|
-
) -> Callable[..., Any]:
|
|
201
|
+
) -> typing.Callable[..., typing.Any]:
|
|
202
202
|
"""Register a method to invoke after deserializing an object. The method
|
|
203
203
|
receives the deserialized data and returns the processed data.
|
|
204
204
|
|
|
@@ -219,12 +219,12 @@ def post_load(
|
|
|
219
219
|
|
|
220
220
|
|
|
221
221
|
def set_hook(
|
|
222
|
-
fn: Callable[..., Any] | None,
|
|
222
|
+
fn: typing.Callable[..., typing.Any] | None,
|
|
223
223
|
tag: str,
|
|
224
224
|
*,
|
|
225
225
|
many: bool = False,
|
|
226
|
-
**kwargs: Any,
|
|
227
|
-
) -> Callable[..., Any]:
|
|
226
|
+
**kwargs: typing.Any,
|
|
227
|
+
) -> typing.Callable[..., typing.Any]:
|
|
228
228
|
"""Mark decorated function as a hook to be picked up later.
|
|
229
229
|
You should not need to use this method directly.
|
|
230
230
|
|
|
@@ -241,7 +241,7 @@ def set_hook(
|
|
|
241
241
|
|
|
242
242
|
# Set a __marshmallow_hook__ attribute instead of wrapping in some class,
|
|
243
243
|
# because I still want this to end up as a normal (unbound) method.
|
|
244
|
-
function = cast("MarshmallowHook", fn)
|
|
244
|
+
function = typing.cast("MarshmallowHook", fn)
|
|
245
245
|
try:
|
|
246
246
|
hook_config = function.__marshmallow_hook__
|
|
247
247
|
except AttributeError:
|
marshmallow/fields.py
CHANGED
|
@@ -685,7 +685,7 @@ class Pluck(Nested):
|
|
|
685
685
|
return self._load(value, partial=partial)
|
|
686
686
|
|
|
687
687
|
|
|
688
|
-
class List(Field[list[
|
|
688
|
+
class List(Field[list[_InternalT | None]]):
|
|
689
689
|
"""A list field, composed with another `Field` class or
|
|
690
690
|
instance.
|
|
691
691
|
|
|
@@ -816,7 +816,7 @@ class Tuple(Field[tuple]):
|
|
|
816
816
|
|
|
817
817
|
return tuple(
|
|
818
818
|
field._serialize(each, attr, obj, **kwargs)
|
|
819
|
-
for field, each in zip(self.tuple_fields, value)
|
|
819
|
+
for field, each in zip(self.tuple_fields, value, strict=True)
|
|
820
820
|
)
|
|
821
821
|
|
|
822
822
|
def _deserialize(
|
|
@@ -834,7 +834,7 @@ class Tuple(Field[tuple]):
|
|
|
834
834
|
result = []
|
|
835
835
|
errors = {}
|
|
836
836
|
|
|
837
|
-
for idx, (field, each) in enumerate(zip(self.tuple_fields, value)):
|
|
837
|
+
for idx, (field, each) in enumerate(zip(self.tuple_fields, value, strict=True)):
|
|
838
838
|
try:
|
|
839
839
|
result.append(field.deserialize(each, **kwargs))
|
|
840
840
|
except ValidationError as error:
|
|
@@ -1745,7 +1745,7 @@ class Email(String):
|
|
|
1745
1745
|
self.validators.insert(0, validator)
|
|
1746
1746
|
|
|
1747
1747
|
|
|
1748
|
-
class IP(Field[
|
|
1748
|
+
class IP(Field[ipaddress.IPv4Address | ipaddress.IPv6Address]):
|
|
1749
1749
|
"""A IP address field.
|
|
1750
1750
|
|
|
1751
1751
|
:param exploded: If `True`, serialize ipv6 address in long form, ie. with groups
|
|
@@ -1802,9 +1802,7 @@ class IPv6(IP):
|
|
|
1802
1802
|
DESERIALIZATION_CLASS = ipaddress.IPv6Address
|
|
1803
1803
|
|
|
1804
1804
|
|
|
1805
|
-
class IPInterface(
|
|
1806
|
-
Field[typing.Union[ipaddress.IPv4Interface, ipaddress.IPv6Interface]]
|
|
1807
|
-
):
|
|
1805
|
+
class IPInterface(Field[ipaddress.IPv4Interface | ipaddress.IPv6Interface]):
|
|
1808
1806
|
"""A IPInterface field.
|
|
1809
1807
|
|
|
1810
1808
|
IP interface is the non-strict form of the IPNetwork type where arbitrary host
|
marshmallow/schema.py
CHANGED
|
@@ -1188,7 +1188,9 @@ class Schema(metaclass=SchemaMeta):
|
|
|
1188
1188
|
pass_original = validator_kwargs.get("pass_original", False)
|
|
1189
1189
|
|
|
1190
1190
|
if many and not pass_collection:
|
|
1191
|
-
for idx, (item, orig) in enumerate(
|
|
1191
|
+
for idx, (item, orig) in enumerate(
|
|
1192
|
+
zip(data, original_data, strict=True)
|
|
1193
|
+
):
|
|
1192
1194
|
self._run_validator(
|
|
1193
1195
|
validator,
|
|
1194
1196
|
item,
|
marshmallow/types.py
CHANGED
|
@@ -7,23 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
-
try:
|
|
11
|
-
from typing import TypeAlias
|
|
12
|
-
except ImportError: # Remove when dropping Python 3.9
|
|
13
|
-
from typing_extensions import TypeAlias
|
|
14
|
-
|
|
15
10
|
import typing
|
|
16
11
|
|
|
17
12
|
#: A type that can be either a sequence of strings or a set of strings
|
|
18
|
-
StrSequenceOrSet: TypeAlias = typing.
|
|
19
|
-
typing.Sequence[str], typing.AbstractSet[str]
|
|
20
|
-
]
|
|
13
|
+
StrSequenceOrSet: typing.TypeAlias = typing.Sequence[str] | typing.AbstractSet[str]
|
|
21
14
|
|
|
22
15
|
#: Type for validator functions
|
|
23
|
-
Validator: TypeAlias = typing.Callable[[typing.Any], typing.Any]
|
|
16
|
+
Validator: typing.TypeAlias = typing.Callable[[typing.Any], typing.Any]
|
|
24
17
|
|
|
25
18
|
#: A valid option for the ``unknown`` schema option and argument
|
|
26
|
-
UnknownOption: TypeAlias = typing.Literal["exclude", "include", "raise"]
|
|
19
|
+
UnknownOption: typing.TypeAlias = typing.Literal["exclude", "include", "raise"]
|
|
27
20
|
|
|
28
21
|
|
|
29
22
|
class SchemaValidator(typing.Protocol):
|
marshmallow/utils.py
CHANGED
|
@@ -7,31 +7,25 @@ import inspect
|
|
|
7
7
|
import typing
|
|
8
8
|
from collections.abc import Mapping, Sequence
|
|
9
9
|
|
|
10
|
-
# Remove when we drop Python 3.9
|
|
11
|
-
try:
|
|
12
|
-
from typing import TypeGuard
|
|
13
|
-
except ImportError:
|
|
14
|
-
from typing_extensions import TypeGuard
|
|
15
|
-
|
|
16
10
|
from marshmallow.constants import missing
|
|
17
11
|
|
|
18
12
|
|
|
19
|
-
def is_generator(obj) -> TypeGuard[typing.Generator]:
|
|
13
|
+
def is_generator(obj) -> typing.TypeGuard[typing.Generator]:
|
|
20
14
|
"""Return True if ``obj`` is a generator"""
|
|
21
15
|
return inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj)
|
|
22
16
|
|
|
23
17
|
|
|
24
|
-
def is_iterable_but_not_string(obj) -> TypeGuard[typing.Iterable]:
|
|
18
|
+
def is_iterable_but_not_string(obj) -> typing.TypeGuard[typing.Iterable]:
|
|
25
19
|
"""Return True if ``obj`` is an iterable object that isn't a string."""
|
|
26
20
|
return (hasattr(obj, "__iter__") and not hasattr(obj, "strip")) or is_generator(obj)
|
|
27
21
|
|
|
28
22
|
|
|
29
|
-
def is_sequence_but_not_string(obj) -> TypeGuard[Sequence]:
|
|
23
|
+
def is_sequence_but_not_string(obj) -> typing.TypeGuard[Sequence]:
|
|
30
24
|
"""Return True if ``obj`` is a sequence that isn't a string."""
|
|
31
25
|
return isinstance(obj, Sequence) and not isinstance(obj, (str, bytes))
|
|
32
26
|
|
|
33
27
|
|
|
34
|
-
def is_collection(obj) -> TypeGuard[typing.Iterable]:
|
|
28
|
+
def is_collection(obj) -> typing.TypeGuard[typing.Iterable]:
|
|
35
29
|
"""Return True if ``obj`` is a collection type, e.g list, tuple, queryset."""
|
|
36
30
|
return is_iterable_but_not_string(obj) and not isinstance(obj, Mapping)
|
|
37
31
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marshmallow
|
|
3
|
-
Version: 4.0
|
|
3
|
+
Version: 4.1.0
|
|
4
4
|
Summary: A lightweight library for converting complex datatypes to and from native Python datatypes.
|
|
5
|
-
Author-email: Steven Loria <
|
|
6
|
-
Maintainer-email: Steven Loria <
|
|
7
|
-
Requires-Python: >=3.
|
|
5
|
+
Author-email: Steven Loria <oss@stevenloria.com>
|
|
6
|
+
Maintainer-email: Steven Loria <oss@stevenloria.com>, Jérôme Lafréchoux <jerome@jolimont.fr>, Jared Deckard <jared@shademaps.com>
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
8
|
Description-Content-Type: text/x-rst
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: backports-datetime-fromisoformat; python_version < '3.11'
|
|
20
20
|
Requires-Dist: typing-extensions; python_version < '3.11'
|
|
@@ -22,11 +22,11 @@ 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.9.25 ; 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"
|
|
29
|
-
Requires-Dist: sphinxext-opengraph==0.
|
|
29
|
+
Requires-Dist: sphinxext-opengraph==0.13.0 ; extra == "docs"
|
|
30
30
|
Requires-Dist: pytest ; extra == "tests"
|
|
31
31
|
Requires-Dist: simplejson ; extra == "tests"
|
|
32
32
|
Project-URL: Changelog, https://marshmallow.readthedocs.io/en/latest/changelog.html
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
marshmallow/__init__.py,sha256=9XHBRTrPmbVaU-Z8CWo8nlcf9Z5VvkRD37d1luJuAaM,573
|
|
2
2
|
marshmallow/class_registry.py,sha256=HTC9srCEaRsiy5L_vUKQso7IQfeZeRXxZfz4_2NitoM,3029
|
|
3
|
-
marshmallow/constants.py,sha256=
|
|
4
|
-
marshmallow/decorators.py,sha256=
|
|
3
|
+
marshmallow/constants.py,sha256=v86zJ9nywyN7euiHQw8hJSkuPyeuflUvv0jZVtfre8M,415
|
|
4
|
+
marshmallow/decorators.py,sha256=maOozW03vQ7k9qZqZ_TvTYR3w--kb0NfkAOy1Q0TnZ0,10165
|
|
5
5
|
marshmallow/error_store.py,sha256=iCPSdw8nJGiS4fjWuIAY1aSI_Hhckcdo3l_g-7pjaMw,2240
|
|
6
6
|
marshmallow/exceptions.py,sha256=1L3ZHwQNelWU5ujIPsON5tZ6WQPk64pBGWNyfwhz608,2273
|
|
7
|
-
marshmallow/fields.py,sha256=
|
|
7
|
+
marshmallow/fields.py,sha256=DxFiqatexaj9tbs395Pre_Sr2h3BdlF2scSKxcJLV1M,72154
|
|
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=
|
|
11
|
-
marshmallow/types.py,sha256=
|
|
12
|
-
marshmallow/utils.py,sha256=
|
|
10
|
+
marshmallow/schema.py,sha256=tgcgL1wqJTMd6irpGL7x89lDUNP4cPRCNPY1y6-kBeI,49955
|
|
11
|
+
marshmallow/types.py,sha256=X2DVsg8H7fFqco5yK2tZDwoqjxRPFjVurEdT-YogNC8,1161
|
|
12
|
+
marshmallow/utils.py,sha256=YI38vVbIwa9T1kPrnW8sF6HmTbi0MFZYNzINKwtbxew,5334
|
|
13
13
|
marshmallow/validate.py,sha256=X6uhUir-2DqUVzKMkEN6I8LrLPJ1mbL8RECRggByllU,23931
|
|
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.0.
|
|
17
|
-
marshmallow-4.0.
|
|
18
|
-
marshmallow-4.0.
|
|
19
|
-
marshmallow-4.0.
|
|
16
|
+
marshmallow-4.1.0.dist-info/licenses/LICENSE,sha256=kGtdkFHkJhRMsXOtkRZnuOvQWpxYTCwmwTWzKj7RIAE,1064
|
|
17
|
+
marshmallow-4.1.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
18
|
+
marshmallow-4.1.0.dist-info/METADATA,sha256=JQA9KW9qwD2NGhc3sAF4VSU3xIfjssg7LJn39lq8we0,7439
|
|
19
|
+
marshmallow-4.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|