marshmallow 3.21.0__py3-none-any.whl → 3.21.2__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/__init__.py +3 -3
- marshmallow/base.py +1 -0
- marshmallow/class_registry.py +3 -1
- marshmallow/decorators.py +17 -10
- marshmallow/exceptions.py +1 -0
- marshmallow/fields.py +11 -9
- marshmallow/schema.py +3 -2
- marshmallow/types.py +1 -0
- marshmallow/utils.py +3 -0
- marshmallow/validate.py +7 -9
- {marshmallow-3.21.0.dist-info → marshmallow-3.21.2.dist-info}/METADATA +3 -7
- marshmallow-3.21.2.dist-info/RECORD +18 -0
- marshmallow-3.21.0.dist-info/RECORD +0 -18
- {marshmallow-3.21.0.dist-info → marshmallow-3.21.2.dist-info}/LICENSE +0 -0
- {marshmallow-3.21.0.dist-info → marshmallow-3.21.2.dist-info}/WHEEL +0 -0
marshmallow/__init__.py
CHANGED
|
@@ -52,9 +52,9 @@ def __getattr__(name: str) -> typing.Any:
|
|
|
52
52
|
stacklevel=2,
|
|
53
53
|
)
|
|
54
54
|
__parsed_version__ = Version(importlib.metadata.version("marshmallow"))
|
|
55
|
-
__version_info__: tuple[int, int, int] | tuple[
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
__version_info__: tuple[int, int, int] | tuple[int, int, int, str, int] = (
|
|
56
|
+
__parsed_version__.release # type: ignore[assignment]
|
|
57
|
+
)
|
|
58
58
|
if __parsed_version__.pre:
|
|
59
59
|
__version_info__ += __parsed_version__.pre # type: ignore[assignment]
|
|
60
60
|
return __version_info__
|
marshmallow/base.py
CHANGED
marshmallow/class_registry.py
CHANGED
|
@@ -7,6 +7,7 @@ class:`fields.Nested <marshmallow.fields.Nested>`.
|
|
|
7
7
|
This module is treated as private API.
|
|
8
8
|
Users should not need to use this module directly.
|
|
9
9
|
"""
|
|
10
|
+
|
|
10
11
|
from __future__ import annotations
|
|
11
12
|
|
|
12
13
|
import typing
|
|
@@ -35,7 +36,8 @@ def register(classname: str, cls: SchemaType) -> None:
|
|
|
35
36
|
class MyClass:
|
|
36
37
|
pass
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
register("MyClass", MyClass)
|
|
39
41
|
# Registry:
|
|
40
42
|
# {
|
|
41
43
|
# 'MyClass': [path.to.MyClass],
|
marshmallow/decorators.py
CHANGED
|
@@ -15,39 +15,45 @@ signature.
|
|
|
15
15
|
Example: ::
|
|
16
16
|
|
|
17
17
|
from marshmallow import (
|
|
18
|
-
Schema,
|
|
19
|
-
|
|
18
|
+
Schema,
|
|
19
|
+
pre_load,
|
|
20
|
+
pre_dump,
|
|
21
|
+
post_load,
|
|
22
|
+
validates_schema,
|
|
23
|
+
validates,
|
|
24
|
+
fields,
|
|
25
|
+
ValidationError,
|
|
20
26
|
)
|
|
21
27
|
|
|
22
|
-
class UserSchema(Schema):
|
|
23
28
|
|
|
29
|
+
class UserSchema(Schema):
|
|
24
30
|
email = fields.Str(required=True)
|
|
25
31
|
age = fields.Integer(required=True)
|
|
26
32
|
|
|
27
33
|
@post_load
|
|
28
34
|
def lowerstrip_email(self, item, many, **kwargs):
|
|
29
|
-
item[
|
|
35
|
+
item["email"] = item["email"].lower().strip()
|
|
30
36
|
return item
|
|
31
37
|
|
|
32
38
|
@pre_load(pass_many=True)
|
|
33
39
|
def remove_envelope(self, data, many, **kwargs):
|
|
34
|
-
namespace =
|
|
40
|
+
namespace = "results" if many else "result"
|
|
35
41
|
return data[namespace]
|
|
36
42
|
|
|
37
43
|
@post_dump(pass_many=True)
|
|
38
44
|
def add_envelope(self, data, many, **kwargs):
|
|
39
|
-
namespace =
|
|
45
|
+
namespace = "results" if many else "result"
|
|
40
46
|
return {namespace: data}
|
|
41
47
|
|
|
42
48
|
@validates_schema
|
|
43
49
|
def validate_email(self, data, **kwargs):
|
|
44
|
-
if len(data[
|
|
45
|
-
raise ValidationError(
|
|
50
|
+
if len(data["email"]) < 3:
|
|
51
|
+
raise ValidationError("Email must be more than 3 characters", "email")
|
|
46
52
|
|
|
47
|
-
@validates(
|
|
53
|
+
@validates("age")
|
|
48
54
|
def validate_age(self, data, **kwargs):
|
|
49
55
|
if data < 14:
|
|
50
|
-
raise ValidationError(
|
|
56
|
+
raise ValidationError("Too young!")
|
|
51
57
|
|
|
52
58
|
.. note::
|
|
53
59
|
These decorators only work with instance methods. Class and static
|
|
@@ -58,6 +64,7 @@ Example: ::
|
|
|
58
64
|
If you need to guarantee order of different processing steps, you should put
|
|
59
65
|
them in the same processing method.
|
|
60
66
|
"""
|
|
67
|
+
|
|
61
68
|
from __future__ import annotations
|
|
62
69
|
|
|
63
70
|
import functools
|
marshmallow/exceptions.py
CHANGED
marshmallow/fields.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Field classes for various types of data."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import collections
|
|
@@ -393,7 +394,7 @@ class Field(FieldABC):
|
|
|
393
394
|
class TitleCase(Field):
|
|
394
395
|
def _serialize(self, value, attr, obj, **kwargs):
|
|
395
396
|
if not value:
|
|
396
|
-
return
|
|
397
|
+
return ""
|
|
397
398
|
return str(value).title()
|
|
398
399
|
|
|
399
400
|
:param value: The value to be serialized.
|
|
@@ -495,6 +496,7 @@ class Nested(Field):
|
|
|
495
496
|
parent = fields.Nested(lambda: ParentSchema(only=("id",)), dump_only=True)
|
|
496
497
|
siblings = fields.List(fields.Nested(lambda: ChildSchema(only=("id", "name"))))
|
|
497
498
|
|
|
499
|
+
|
|
498
500
|
class ParentSchema(Schema):
|
|
499
501
|
id = fields.Str()
|
|
500
502
|
children = fields.List(
|
|
@@ -511,10 +513,10 @@ class Nested(Field):
|
|
|
511
513
|
::
|
|
512
514
|
|
|
513
515
|
# Yes
|
|
514
|
-
author = fields.Nested(UserSchema, only=(
|
|
516
|
+
author = fields.Nested(UserSchema, only=("id", "name"))
|
|
515
517
|
|
|
516
518
|
# No
|
|
517
|
-
author = fields.Nested(UserSchema(), only=(
|
|
519
|
+
author = fields.Nested(UserSchema(), only=("id", "name"))
|
|
518
520
|
|
|
519
521
|
:param nested: `Schema` instance, class, class name (string), dictionary, or callable that
|
|
520
522
|
returns a `Schema` or dictionary. Dictionaries are converted with `Schema.from_dict`.
|
|
@@ -626,7 +628,7 @@ class Nested(Field):
|
|
|
626
628
|
return self._schema
|
|
627
629
|
|
|
628
630
|
def _nested_normalized_option(self, option_name: str) -> list[str]:
|
|
629
|
-
nested_field = "
|
|
631
|
+
nested_field = f"{self.name}."
|
|
630
632
|
return [
|
|
631
633
|
field.split(nested_field, 1)[1]
|
|
632
634
|
for field in getattr(self.root, option_name, set())
|
|
@@ -676,16 +678,18 @@ class Pluck(Nested):
|
|
|
676
678
|
|
|
677
679
|
from marshmallow import Schema, fields
|
|
678
680
|
|
|
681
|
+
|
|
679
682
|
class ArtistSchema(Schema):
|
|
680
683
|
id = fields.Int()
|
|
681
684
|
name = fields.Str()
|
|
682
685
|
|
|
686
|
+
|
|
683
687
|
class AlbumSchema(Schema):
|
|
684
|
-
artist = fields.Pluck(ArtistSchema,
|
|
688
|
+
artist = fields.Pluck(ArtistSchema, "id")
|
|
685
689
|
|
|
686
690
|
|
|
687
|
-
in_data = {
|
|
688
|
-
loaded = AlbumSchema().load(in_data)
|
|
691
|
+
in_data = {"artist": 42}
|
|
692
|
+
loaded = AlbumSchema().load(in_data) # => {'artist': {'id': 42}}
|
|
689
693
|
dumped = AlbumSchema().dump(loaded) # => {'artist': 42}
|
|
690
694
|
|
|
691
695
|
:param Schema nested: The Schema class or class name (string)
|
|
@@ -1281,8 +1285,6 @@ class DateTime(Field):
|
|
|
1281
1285
|
return value.strftime(data_format)
|
|
1282
1286
|
|
|
1283
1287
|
def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime:
|
|
1284
|
-
if not value: # Falsy values, e.g. '', None, [] are not valid
|
|
1285
|
-
raise self.make_error("invalid", input=value, obj_type=self.OBJ_TYPE)
|
|
1286
1288
|
data_format = self.format or self.DEFAULT_FORMAT
|
|
1287
1289
|
func = self.DESERIALIZATION_FUNCS.get(data_format)
|
|
1288
1290
|
try:
|
marshmallow/schema.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""The :class:`Schema` class, including its metaclass and options (class Meta)."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import copy
|
|
@@ -1047,9 +1048,9 @@ class Schema(base.SchemaABC, metaclass=SchemaMeta):
|
|
|
1047
1048
|
# the type checker's perspective.
|
|
1048
1049
|
if isinstance(field_obj, type) and issubclass(field_obj, base.FieldABC):
|
|
1049
1050
|
msg = (
|
|
1050
|
-
'Field for "{field_name}" must be declared as a '
|
|
1051
|
+
f'Field for "{field_name}" must be declared as a '
|
|
1051
1052
|
"Field instance, not a class. "
|
|
1052
|
-
'Did you mean "fields.{field_obj.__name__}()"?'
|
|
1053
|
+
f'Did you mean "fields.{field_obj.__name__}()"?' # type: ignore
|
|
1053
1054
|
)
|
|
1054
1055
|
raise TypeError(msg) from error
|
|
1055
1056
|
raise error
|
marshmallow/types.py
CHANGED
marshmallow/utils.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Utility methods for marshmallow."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import collections
|
|
@@ -191,6 +192,8 @@ def from_iso_date(value):
|
|
|
191
192
|
|
|
192
193
|
|
|
193
194
|
def from_timestamp(value: typing.Any) -> dt.datetime:
|
|
195
|
+
if value is True or value is False:
|
|
196
|
+
raise ValueError("Not a valid POSIX timestamp")
|
|
194
197
|
value = float(value)
|
|
195
198
|
if value < 0:
|
|
196
199
|
raise ValueError("Not a valid POSIX timestamp")
|
marshmallow/validate.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Validation classes for various types of data."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import re
|
|
@@ -36,8 +37,7 @@ class Validator(ABC):
|
|
|
36
37
|
return ""
|
|
37
38
|
|
|
38
39
|
@abstractmethod
|
|
39
|
-
def __call__(self, value: typing.Any) -> typing.Any:
|
|
40
|
-
...
|
|
40
|
+
def __call__(self, value: typing.Any) -> typing.Any: ...
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class And(Validator):
|
|
@@ -47,10 +47,12 @@ class And(Validator):
|
|
|
47
47
|
|
|
48
48
|
from marshmallow import validate, ValidationError
|
|
49
49
|
|
|
50
|
+
|
|
50
51
|
def is_even(value):
|
|
51
52
|
if value % 2 != 0:
|
|
52
53
|
raise ValidationError("Not an even value.")
|
|
53
54
|
|
|
55
|
+
|
|
54
56
|
validator = validate.And(validate.Range(min=0), is_even)
|
|
55
57
|
validator(-1)
|
|
56
58
|
# ValidationError: ['Must be greater than or equal to 0.', 'Not an even value.']
|
|
@@ -334,9 +336,7 @@ class Range(Validator):
|
|
|
334
336
|
)
|
|
335
337
|
|
|
336
338
|
def _repr_args(self) -> str:
|
|
337
|
-
return "min={!r}, max={!r}, min_inclusive={!r}, max_inclusive={!r}"
|
|
338
|
-
self.min, self.max, self.min_inclusive, self.max_inclusive
|
|
339
|
-
)
|
|
339
|
+
return f"min={self.min!r}, max={self.max!r}, min_inclusive={self.min_inclusive!r}, max_inclusive={self.max_inclusive!r}"
|
|
340
340
|
|
|
341
341
|
def _format_error(self, value: _T, message: str) -> str:
|
|
342
342
|
return (self.error or message).format(input=value, min=self.min, max=self.max)
|
|
@@ -486,12 +486,10 @@ class Regexp(Validator):
|
|
|
486
486
|
return self.error.format(input=value, regex=self.regex.pattern)
|
|
487
487
|
|
|
488
488
|
@typing.overload
|
|
489
|
-
def __call__(self, value: str) -> str:
|
|
490
|
-
...
|
|
489
|
+
def __call__(self, value: str) -> str: ...
|
|
491
490
|
|
|
492
491
|
@typing.overload
|
|
493
|
-
def __call__(self, value: bytes) -> bytes:
|
|
494
|
-
...
|
|
492
|
+
def __call__(self, value: bytes) -> bytes: ...
|
|
495
493
|
|
|
496
494
|
def __call__(self, value):
|
|
497
495
|
if self.regex.match(value) is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: marshmallow
|
|
3
|
-
Version: 3.21.
|
|
3
|
+
Version: 3.21.2
|
|
4
4
|
Summary: A lightweight library for converting complex datatypes to and from native Python datatypes.
|
|
5
5
|
Author-email: Steven Loria <sloria1@gmail.com>
|
|
6
6
|
Maintainer-email: Steven Loria <sloria1@gmail.com>, Jérôme Lafréchoux <jerome@jolimont.fr>, Jared Deckard <jared@shademaps.com>
|
|
@@ -19,8 +19,8 @@ Requires-Dist: packaging>=17.0
|
|
|
19
19
|
Requires-Dist: marshmallow[tests] ; extra == "dev"
|
|
20
20
|
Requires-Dist: tox ; extra == "dev"
|
|
21
21
|
Requires-Dist: pre-commit~=3.5 ; extra == "dev"
|
|
22
|
-
Requires-Dist: sphinx==7.
|
|
23
|
-
Requires-Dist: sphinx-issues==4.
|
|
22
|
+
Requires-Dist: sphinx==7.3.7 ; extra == "docs"
|
|
23
|
+
Requires-Dist: sphinx-issues==4.1.0 ; extra == "docs"
|
|
24
24
|
Requires-Dist: alabaster==0.7.16 ; extra == "docs"
|
|
25
25
|
Requires-Dist: sphinx-version-warning==1.1.2 ; extra == "docs"
|
|
26
26
|
Requires-Dist: autodocsumm==0.2.12 ; extra == "docs"
|
|
@@ -157,10 +157,6 @@ Your logo will show up here with a link to your website. [`Become a sponsor`_]
|
|
|
157
157
|
|
|
158
158
|
.. _`Become a sponsor`: https://opencollective.com/marshmallow#sponsor
|
|
159
159
|
|
|
160
|
-
.. image:: https://opencollective.com/marshmallow/sponsor/0/avatar.svg
|
|
161
|
-
:target: https://opencollective.com/marshmallow/sponsor/0/website
|
|
162
|
-
:alt: Sponsors
|
|
163
|
-
|
|
164
160
|
.. image:: https://opencollective.com/static/images/become_sponsor.svg
|
|
165
161
|
:target: https://opencollective.com/marshmallow#sponsor
|
|
166
162
|
:alt: Become a sponsor
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
marshmallow/__init__.py,sha256=C-zbaQJ9dlJLJxotIqTa5OOaD6ojGNRqW8moGrMsGr8,2387
|
|
2
|
+
marshmallow/base.py,sha256=jZ68DZxxSCvRg2GTcxQcf2JjTxqEn-xFNrBEMK3CinU,1346
|
|
3
|
+
marshmallow/class_registry.py,sha256=Uvg-Obos0MejwTrpOHNEH4VF_SfGXKgR-4F2LnCbt1A,2811
|
|
4
|
+
marshmallow/decorators.py,sha256=aa0tmqYW7-EJSae0ztZU9fHiQ3YIBdvIgaCrl1ChLNA,8300
|
|
5
|
+
marshmallow/error_store.py,sha256=A7AxgLMw9ffSmaxRH4x3wcBWibx-DuGH4LwSDpVn50I,2223
|
|
6
|
+
marshmallow/exceptions.py,sha256=DuARdOcirCdJxmlp16V97hQKAXOokvdW12jXtYOlGyk,2326
|
|
7
|
+
marshmallow/fields.py,sha256=3mWgT1TiLzKgdhgWTJYsGe6lVgUz02g8sb63FEEn5hc,72995
|
|
8
|
+
marshmallow/orderedset.py,sha256=C2aAG6w1faIL1phinbAltbe3AUAnF5MN6n7fzESNDhI,2922
|
|
9
|
+
marshmallow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
marshmallow/schema.py,sha256=lcaRjOkHph5NwokwIlJOuQmP_96FIwO6TzwSBd3c_98,49057
|
|
11
|
+
marshmallow/types.py,sha256=eHMwQR8-ICX2RHf_i6bgjnhzdanbpBqXuzXuP6jHcNI,332
|
|
12
|
+
marshmallow/utils.py,sha256=sWciesZ6tS08uX9Z9fzu2lbuut5eh8TKABU-TwgqSms,11886
|
|
13
|
+
marshmallow/validate.py,sha256=hS7fYC6byDHK9A7A4is0McDMZEzu6GkKke-7unLt2hE,23857
|
|
14
|
+
marshmallow/warnings.py,sha256=vHQu7AluuWqLhvlw5noXtWWbya13zDXY6JMaVSUzmDs,65
|
|
15
|
+
marshmallow-3.21.2.dist-info/LICENSE,sha256=kGtdkFHkJhRMsXOtkRZnuOvQWpxYTCwmwTWzKj7RIAE,1064
|
|
16
|
+
marshmallow-3.21.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
|
17
|
+
marshmallow-3.21.2.dist-info/METADATA,sha256=C7GEuX08QNTfpUvjjiD3GpZtWcPf4kHOJmMYNe6IoW0,7079
|
|
18
|
+
marshmallow-3.21.2.dist-info/RECORD,,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
marshmallow/__init__.py,sha256=zfCLhifu2WhV5WdSIvF-IgtOocF2Koc1iIJ30V9MCWw,2385
|
|
2
|
-
marshmallow/base.py,sha256=fo3i0f5YiT9MqY0rmdcmVy8iTNK9aOG0hFSGf4MxWEs,1345
|
|
3
|
-
marshmallow/class_registry.py,sha256=h-f1EKajePnuALkjqWInnbyv_xgt92nb_DZhxyk2BVc,2809
|
|
4
|
-
marshmallow/decorators.py,sha256=X9vNZgfrk3JvhHrVV9CPQxy2XMtGwewVwdvEeX_4u_o,8250
|
|
5
|
-
marshmallow/error_store.py,sha256=A7AxgLMw9ffSmaxRH4x3wcBWibx-DuGH4LwSDpVn50I,2223
|
|
6
|
-
marshmallow/exceptions.py,sha256=OIFlC_xY6c_4A6-1fYX-pIsgQegoLPiF5Ccur01MbPU,2325
|
|
7
|
-
marshmallow/fields.py,sha256=G97qL6WjmX2H0Qn9RF78X-bQkw50uUaxMSqRfdmCFe4,73145
|
|
8
|
-
marshmallow/orderedset.py,sha256=C2aAG6w1faIL1phinbAltbe3AUAnF5MN6n7fzESNDhI,2922
|
|
9
|
-
marshmallow/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
marshmallow/schema.py,sha256=L6Cb39l6zE57qmLM2UZxty8g76PCr9MvY-saxzIwo3k,49038
|
|
11
|
-
marshmallow/types.py,sha256=m1IhBT7dWHrYjTm7BQigHGX8UoYyt32WHwDK5Jppxf0,331
|
|
12
|
-
marshmallow/utils.py,sha256=nUZBXDeXxSv6kc1njj_PvmyFRCun2bgZBYZ7mS5gLh8,11789
|
|
13
|
-
marshmallow/validate.py,sha256=fZU2ftt9c-wlBgGmdnB0iZGrHpDLYgY7J7kHp0bAS9U,23914
|
|
14
|
-
marshmallow/warnings.py,sha256=vHQu7AluuWqLhvlw5noXtWWbya13zDXY6JMaVSUzmDs,65
|
|
15
|
-
marshmallow-3.21.0.dist-info/LICENSE,sha256=kGtdkFHkJhRMsXOtkRZnuOvQWpxYTCwmwTWzKj7RIAE,1064
|
|
16
|
-
marshmallow-3.21.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
|
17
|
-
marshmallow-3.21.0.dist-info/METADATA,sha256=y4u7H1p6Hvj8y66QQrXIYjjLpr8QQiQIYMnHSK0E4tw,7240
|
|
18
|
-
marshmallow-3.21.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|