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 CHANGED
@@ -18,5 +18,8 @@ class _Missing:
18
18
  def __repr__(self):
19
19
  return "<marshmallow.missing>"
20
20
 
21
+ def __len__(self):
22
+ return 0
23
+
21
24
 
22
25
  missing: typing.Final = _Missing()
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[typing.Optional[_InternalT]]]):
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[typing.Union[ipaddress.IPv4Address, ipaddress.IPv6Address]]):
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(zip(data, original_data)):
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.Union[
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.1
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 <sloria1@gmail.com>
6
- Maintainer-email: Steven Loria <sloria1@gmail.com>, Jérôme Lafréchoux <jerome@jolimont.fr>, Jared Deckard <jared@shademaps.com>
7
- Requires-Python: >=3.9
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.7.19 ; extra == "docs"
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.12.0 ; extra == "docs"
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=maYmT3pvjQgfummof45SJI_pDqHDFWSu3knVN7su78M,374
4
- marshmallow/decorators.py,sha256=CwD37uih8cyquwYGv-qKVPUUtKmj4tgas45AKwTdlZk,9987
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=oUEjjaibiB1eJpNuH0Bqzl0GdRAtEBmGRGnVXoUeEbI,72170
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=rPusgqkJpODWL0be8CZPejZYqRmnIt7V8jUmAxWWEU8,49904
11
- marshmallow/types.py,sha256=EAMyppcDjDmSd57IWpBRk5RFY6uPoI8CvDr4pLaBXj8,1297
12
- marshmallow/utils.py,sha256=dFeiftZph6OgfT7TxEXx7JmSQRBUzxQXYWwhLPHvqYs,5442
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.1.dist-info/licenses/LICENSE,sha256=kGtdkFHkJhRMsXOtkRZnuOvQWpxYTCwmwTWzKj7RIAE,1064
17
- marshmallow-4.0.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
18
- marshmallow-4.0.1.dist-info/METADATA,sha256=Be5weyeJLpW2eNSZDbNH_yKVmM28dEjHh4-gJf4JMwY,7433
19
- marshmallow-4.0.1.dist-info/RECORD,,
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,,