davidtran999 commited on
Commit
334dfdb
·
verified ·
1 Parent(s): 281ad51

Upload backend/venv/lib/python3.10/site-packages/marshmallow/fields.py with huggingface_hub

Browse files
backend/venv/lib/python3.10/site-packages/marshmallow/fields.py ADDED
@@ -0,0 +1,2153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ruff: noqa: F841, SLF001
2
+ from __future__ import annotations
3
+
4
+ import collections
5
+ import copy
6
+ import datetime as dt
7
+ import decimal
8
+ import ipaddress
9
+ import math
10
+ import numbers
11
+ import typing
12
+ import uuid
13
+ import warnings
14
+ from collections.abc import Mapping as _Mapping
15
+
16
+ from marshmallow import class_registry, types, utils, validate
17
+ from marshmallow.base import FieldABC
18
+ from marshmallow.exceptions import (
19
+ FieldInstanceResolutionError,
20
+ StringNotCollectionError,
21
+ ValidationError,
22
+ )
23
+ from marshmallow.utils import (
24
+ is_aware,
25
+ is_collection,
26
+ resolve_field_instance,
27
+ )
28
+ from marshmallow.utils import (
29
+ missing as missing_,
30
+ )
31
+ from marshmallow.validate import And, Length
32
+ from marshmallow.warnings import (
33
+ ChangedInMarshmallow4Warning,
34
+ RemovedInMarshmallow4Warning,
35
+ )
36
+
37
+ if typing.TYPE_CHECKING:
38
+ from enum import Enum as EnumType
39
+
40
+ from marshmallow.schema import Schema, SchemaMeta
41
+
42
+
43
+ __all__ = [
44
+ "IP",
45
+ "URL",
46
+ "UUID",
47
+ "AwareDateTime",
48
+ "Bool",
49
+ "Boolean",
50
+ "Constant",
51
+ "Date",
52
+ "DateTime",
53
+ "Decimal",
54
+ "Dict",
55
+ "Email",
56
+ "Enum",
57
+ "Field",
58
+ "Float",
59
+ "Function",
60
+ "IPInterface",
61
+ "IPv4",
62
+ "IPv4Interface",
63
+ "IPv6",
64
+ "IPv6Interface",
65
+ "Int",
66
+ "Integer",
67
+ "List",
68
+ "Mapping",
69
+ "Method",
70
+ "NaiveDateTime",
71
+ "Nested",
72
+ "Number",
73
+ "Pluck",
74
+ "Raw",
75
+ "Str",
76
+ "String",
77
+ "Time",
78
+ "TimeDelta",
79
+ "Tuple",
80
+ "Url",
81
+ ]
82
+
83
+
84
+ class Field(FieldABC):
85
+ """Base field from which other fields inherit.
86
+
87
+ :param dump_default: If set, this value will be used during serialization if the
88
+ input value is missing. If not set, the field will be excluded from the
89
+ serialized output if the input value is missing. May be a value or a callable.
90
+ :param load_default: Default deserialization value for the field if the field is not
91
+ found in the input data. May be a value or a callable.
92
+ :param data_key: The name of the dict key in the external representation, i.e.
93
+ the input of `load` and the output of `dump`.
94
+ If `None`, the key will match the name of the field.
95
+ :param attribute: The name of the key/attribute in the internal representation, i.e.
96
+ the output of `load` and the input of `dump`.
97
+ If `None`, the key/attribute will match the name of the field.
98
+ Note: This should only be used for very specific use cases such as
99
+ outputting multiple fields for a single attribute, or using keys/attributes
100
+ that are invalid variable names, unsuitable for field names. In most cases,
101
+ you should use ``data_key`` instead.
102
+ :param validate: Validator or collection of validators that are called
103
+ during deserialization. Validator takes a field's input value as
104
+ its only parameter and returns a boolean.
105
+ If it returns `False`, an :exc:`ValidationError` is raised.
106
+ :param required: Raise a :exc:`ValidationError` if the field value
107
+ is not supplied during deserialization.
108
+ :param allow_none: Set this to `True` if `None` should be considered a valid value during
109
+ validation/deserialization. If set to `False` (the default), `None` is considered invalid input.
110
+ If ``load_default`` is explicitly set to `None` and ``allow_none`` is unset,
111
+ `allow_none` is implicitly set to ``True``.
112
+ :param load_only: If `True` skip this field during serialization, otherwise
113
+ its value will be present in the serialized data.
114
+ :param dump_only: If `True` skip this field during deserialization, otherwise
115
+ its value will be present in the deserialized object. In the context of an
116
+ HTTP API, this effectively marks the field as "read-only".
117
+ :param error_messages: Overrides for `Field.default_error_messages`.
118
+ :param metadata: Extra information to be stored as field metadata.
119
+
120
+ .. versionchanged:: 3.0.0b8
121
+ Add ``data_key`` parameter for the specifying the key in the input and
122
+ output data. This parameter replaced both ``load_from`` and ``dump_to``.
123
+
124
+ .. versionchanged:: 3.13.0
125
+ Replace ``missing`` and ``default`` parameters with ``load_default`` and ``dump_default``.
126
+
127
+ .. versionchanged:: 3.24.0
128
+ `Field <marshmallow.fields.Field>` should no longer be used as a field within a `Schema <marshmallow.Schema>`.
129
+ Use `Raw <marshmallow.fields.Raw>` or another `Field <marshmallow.fields.Field>` subclass instead.
130
+ """
131
+
132
+ # Some fields, such as Method fields and Function fields, are not expected
133
+ # to exist as attributes on the objects to serialize. Set this to False
134
+ # for those fields
135
+ _CHECK_ATTRIBUTE = True
136
+
137
+ #: Default error messages for various kinds of errors. The keys in this dictionary
138
+ #: are passed to `Field.make_error`. The values are error messages passed to
139
+ #: :exc:`marshmallow.exceptions.ValidationError`.
140
+ default_error_messages: dict[str, str] = {
141
+ "required": "Missing data for required field.",
142
+ "null": "Field may not be null.",
143
+ "validator_failed": "Invalid value.",
144
+ }
145
+
146
+ def __init__(
147
+ self,
148
+ *,
149
+ load_default: typing.Any = missing_,
150
+ missing: typing.Any = missing_,
151
+ dump_default: typing.Any = missing_,
152
+ default: typing.Any = missing_,
153
+ data_key: str | None = None,
154
+ attribute: str | None = None,
155
+ validate: types.Validator | typing.Iterable[types.Validator] | None = None,
156
+ required: bool = False,
157
+ allow_none: bool | None = None,
158
+ load_only: bool = False,
159
+ dump_only: bool = False,
160
+ error_messages: dict[str, str] | None = None,
161
+ metadata: typing.Mapping[str, typing.Any] | None = None,
162
+ **additional_metadata,
163
+ ) -> None:
164
+ if self.__class__ is Field:
165
+ warnings.warn(
166
+ "`Field` should not be instantiated. Use `fields.Raw` or "
167
+ "another field subclass instead.",
168
+ ChangedInMarshmallow4Warning,
169
+ stacklevel=2,
170
+ )
171
+ # handle deprecated `default` and `missing` parameters
172
+ if default is not missing_:
173
+ warnings.warn(
174
+ "The 'default' argument to fields is deprecated. "
175
+ "Use 'dump_default' instead.",
176
+ RemovedInMarshmallow4Warning,
177
+ stacklevel=2,
178
+ )
179
+ if dump_default is missing_:
180
+ dump_default = default
181
+ if missing is not missing_:
182
+ warnings.warn(
183
+ "The 'missing' argument to fields is deprecated. "
184
+ "Use 'load_default' instead.",
185
+ RemovedInMarshmallow4Warning,
186
+ stacklevel=2,
187
+ )
188
+ if load_default is missing_:
189
+ load_default = missing
190
+ self.dump_default = dump_default
191
+ self.load_default = load_default
192
+
193
+ self.attribute = attribute
194
+ self.data_key = data_key
195
+ self.validate = validate
196
+ if validate is None:
197
+ self.validators = []
198
+ elif callable(validate):
199
+ self.validators = [validate]
200
+ elif utils.is_iterable_but_not_string(validate):
201
+ self.validators = list(validate)
202
+ else:
203
+ raise ValueError(
204
+ "The 'validate' parameter must be a callable "
205
+ "or a collection of callables."
206
+ )
207
+
208
+ # If allow_none is None and load_default is None
209
+ # None should be considered valid by default
210
+ self.allow_none = load_default is None if allow_none is None else allow_none
211
+ self.load_only = load_only
212
+ self.dump_only = dump_only
213
+ if required is True and load_default is not missing_:
214
+ raise ValueError("'load_default' must not be set for required fields.")
215
+ self.required = required
216
+
217
+ metadata = metadata or {}
218
+ self.metadata = {**metadata, **additional_metadata}
219
+ if additional_metadata:
220
+ warnings.warn(
221
+ "Passing field metadata as keyword arguments is deprecated. Use the "
222
+ "explicit `metadata=...` argument instead. "
223
+ f"Additional metadata: {additional_metadata}",
224
+ RemovedInMarshmallow4Warning,
225
+ stacklevel=2,
226
+ )
227
+
228
+ # Collect default error message from self and parent classes
229
+ messages: dict[str, str] = {}
230
+ for cls in reversed(self.__class__.__mro__):
231
+ messages.update(getattr(cls, "default_error_messages", {}))
232
+ messages.update(error_messages or {})
233
+ self.error_messages = messages
234
+
235
+ self.parent: Field | Schema | None = None
236
+ self.name: str | None = None
237
+ self.root: Schema | None = None
238
+
239
+ def __repr__(self) -> str:
240
+ return (
241
+ f"<fields.{self.__class__.__name__}(dump_default={self.dump_default!r}, "
242
+ f"attribute={self.attribute!r}, "
243
+ f"validate={self.validate}, required={self.required}, "
244
+ f"load_only={self.load_only}, dump_only={self.dump_only}, "
245
+ f"load_default={self.load_default}, allow_none={self.allow_none}, "
246
+ f"error_messages={self.error_messages})>"
247
+ )
248
+
249
+ def __deepcopy__(self, memo):
250
+ return copy.copy(self)
251
+
252
+ def get_value(
253
+ self,
254
+ obj: typing.Any,
255
+ attr: str,
256
+ accessor: (
257
+ typing.Callable[[typing.Any, str, typing.Any], typing.Any] | None
258
+ ) = None,
259
+ default: typing.Any = missing_,
260
+ ):
261
+ """Return the value for a given key from an object.
262
+
263
+ :param obj: The object to get the value from.
264
+ :param attr: The attribute/key in `obj` to get the value from.
265
+ :param accessor: A callable used to retrieve the value of `attr` from
266
+ the object `obj`. Defaults to `marshmallow.utils.get_value`.
267
+ """
268
+ accessor_func = accessor or utils.get_value
269
+ check_key = attr if self.attribute is None else self.attribute
270
+ return accessor_func(obj, check_key, default)
271
+
272
+ def _validate(self, value: typing.Any):
273
+ """Perform validation on ``value``. Raise a :exc:`ValidationError` if validation
274
+ does not succeed.
275
+ """
276
+ self._validate_all(value)
277
+
278
+ @property
279
+ def _validate_all(self) -> typing.Callable[[typing.Any], None]:
280
+ return And(*self.validators, error=self.error_messages["validator_failed"])
281
+
282
+ def make_error(self, key: str, **kwargs) -> ValidationError:
283
+ """Helper method to make a `ValidationError` with an error message
284
+ from ``self.error_messages``.
285
+ """
286
+ try:
287
+ msg = self.error_messages[key]
288
+ except KeyError as error:
289
+ class_name = self.__class__.__name__
290
+ message = (
291
+ f"ValidationError raised by `{class_name}`, but error key `{key}` does "
292
+ "not exist in the `error_messages` dictionary."
293
+ )
294
+ raise AssertionError(message) from error
295
+ if isinstance(msg, (str, bytes)):
296
+ msg = msg.format(**kwargs)
297
+ return ValidationError(msg)
298
+
299
+ def fail(self, key: str, **kwargs):
300
+ """Helper method that raises a `ValidationError` with an error message
301
+ from ``self.error_messages``.
302
+
303
+ .. deprecated:: 3.0.0
304
+ Use `make_error <marshmallow.fields.Field.make_error>` instead.
305
+ """
306
+ warnings.warn(
307
+ f'`Field.fail` is deprecated. Use `raise self.make_error("{key}", ...)` instead.',
308
+ RemovedInMarshmallow4Warning,
309
+ stacklevel=2,
310
+ )
311
+ raise self.make_error(key=key, **kwargs)
312
+
313
+ def _validate_missing(self, value: typing.Any) -> None:
314
+ """Validate missing values. Raise a :exc:`ValidationError` if
315
+ `value` should be considered missing.
316
+ """
317
+ if value is missing_ and self.required:
318
+ raise self.make_error("required")
319
+ if value is None and not self.allow_none:
320
+ raise self.make_error("null")
321
+
322
+ def serialize(
323
+ self,
324
+ attr: str,
325
+ obj: typing.Any,
326
+ accessor: (
327
+ typing.Callable[[typing.Any, str, typing.Any], typing.Any] | None
328
+ ) = None,
329
+ **kwargs,
330
+ ):
331
+ """Pulls the value for the given key from the object, applies the
332
+ field's formatting and returns the result.
333
+
334
+ :param attr: The attribute/key to get from the object.
335
+ :param obj: The object to access the attribute/key from.
336
+ :param accessor: Function used to access values from ``obj``.
337
+ :param kwargs: Field-specific keyword arguments.
338
+ """
339
+ if self._CHECK_ATTRIBUTE:
340
+ value = self.get_value(obj, attr, accessor=accessor)
341
+ if value is missing_:
342
+ default = self.dump_default
343
+ value = default() if callable(default) else default
344
+ if value is missing_:
345
+ return value
346
+ else:
347
+ value = None
348
+ return self._serialize(value, attr, obj, **kwargs)
349
+
350
+ def deserialize(
351
+ self,
352
+ value: typing.Any,
353
+ attr: str | None = None,
354
+ data: typing.Mapping[str, typing.Any] | None = None,
355
+ **kwargs,
356
+ ):
357
+ """Deserialize ``value``.
358
+
359
+ :param value: The value to deserialize.
360
+ :param attr: The attribute/key in `data` to deserialize.
361
+ :param data: The raw input data passed to `Schema.load <marshmallow.Schema.load>`.
362
+ :param kwargs: Field-specific keyword arguments.
363
+ :raise ValidationError: If an invalid value is passed or if a required value
364
+ is missing.
365
+ """
366
+ # Validate required fields, deserialize, then validate
367
+ # deserialized value
368
+ self._validate_missing(value)
369
+ if value is missing_:
370
+ _miss = self.load_default
371
+ return _miss() if callable(_miss) else _miss
372
+ if self.allow_none and value is None:
373
+ return None
374
+ output = self._deserialize(value, attr, data, **kwargs)
375
+ self._validate(output)
376
+ return output
377
+
378
+ # Methods for concrete classes to override.
379
+
380
+ def _bind_to_schema(self, field_name: str, schema: Schema | Field) -> None:
381
+ """Update field with values from its parent schema. Called by
382
+ `Schema._bind_field <marshmallow.Schema._bind_field>`.
383
+
384
+ :param field_name: Field name set in schema.
385
+ :param schema: Parent object.
386
+ """
387
+ self.parent = self.parent or schema
388
+ self.name = self.name or field_name
389
+ self.root = self.root or (
390
+ self.parent.root if isinstance(self.parent, FieldABC) else self.parent
391
+ )
392
+
393
+ def _serialize(
394
+ self, value: typing.Any, attr: str | None, obj: typing.Any, **kwargs
395
+ ) -> typing.Any:
396
+ """Serializes ``value`` to a basic Python datatype. Noop by default.
397
+ Concrete :class:`Field` classes should implement this method.
398
+
399
+ Example: ::
400
+
401
+ class TitleCase(Field):
402
+ def _serialize(self, value, attr, obj, **kwargs):
403
+ if not value:
404
+ return ""
405
+ return str(value).title()
406
+
407
+ :param value: The value to be serialized.
408
+ :param attr: The attribute or key on the object to be serialized.
409
+ :param obj: The object the value was pulled from.
410
+ :param kwargs: Field-specific keyword arguments.
411
+ :return: The serialized value
412
+ """
413
+ return value
414
+
415
+ def _deserialize(
416
+ self,
417
+ value: typing.Any,
418
+ attr: str | None,
419
+ data: typing.Mapping[str, typing.Any] | None,
420
+ **kwargs,
421
+ ) -> typing.Any:
422
+ """Deserialize value. Concrete :class:`Field` classes should implement this method.
423
+
424
+ :param value: The value to be deserialized.
425
+ :param attr: The attribute/key in `data` to be deserialized.
426
+ :param data: The raw input data passed to the `Schema.load <marshmallow.Schema.load>`.
427
+ :param kwargs: Field-specific keyword arguments.
428
+ :raise ValidationError: In case of formatting or validation failure.
429
+ :return: The deserialized value.
430
+
431
+ .. versionchanged:: 3.0.0
432
+ Added ``**kwargs`` to signature.
433
+ """
434
+ return value
435
+
436
+ # Properties
437
+
438
+ @property
439
+ def context(self) -> dict | None:
440
+ """The context dictionary for the parent `Schema <marshmallow.Schema>`."""
441
+ if self.parent:
442
+ return self.parent.context
443
+ return None
444
+
445
+ # the default and missing properties are provided for compatibility and
446
+ # emit warnings when they are accessed and set
447
+ @property
448
+ def default(self):
449
+ warnings.warn(
450
+ "The 'default' attribute of fields is deprecated. "
451
+ "Use 'dump_default' instead.",
452
+ RemovedInMarshmallow4Warning,
453
+ stacklevel=2,
454
+ )
455
+ return self.dump_default
456
+
457
+ @default.setter
458
+ def default(self, value):
459
+ warnings.warn(
460
+ "The 'default' attribute of fields is deprecated. "
461
+ "Use 'dump_default' instead.",
462
+ RemovedInMarshmallow4Warning,
463
+ stacklevel=2,
464
+ )
465
+ self.dump_default = value
466
+
467
+ @property
468
+ def missing(self):
469
+ warnings.warn(
470
+ "The 'missing' attribute of fields is deprecated. "
471
+ "Use 'load_default' instead.",
472
+ RemovedInMarshmallow4Warning,
473
+ stacklevel=2,
474
+ )
475
+ return self.load_default
476
+
477
+ @missing.setter
478
+ def missing(self, value):
479
+ warnings.warn(
480
+ "The 'missing' attribute of fields is deprecated. "
481
+ "Use 'load_default' instead.",
482
+ RemovedInMarshmallow4Warning,
483
+ stacklevel=2,
484
+ )
485
+ self.load_default = value
486
+
487
+
488
+ class Raw(Field):
489
+ """Field that applies no formatting."""
490
+
491
+
492
+ class Nested(Field):
493
+ """Allows you to nest a :class:`Schema <marshmallow.Schema>`
494
+ inside a field.
495
+
496
+ Examples: ::
497
+
498
+ class ChildSchema(Schema):
499
+ id = fields.Str()
500
+ name = fields.Str()
501
+ # Use lambda functions when you need two-way nesting or self-nesting
502
+ parent = fields.Nested(lambda: ParentSchema(only=("id",)), dump_only=True)
503
+ siblings = fields.List(
504
+ fields.Nested(lambda: ChildSchema(only=("id", "name")))
505
+ )
506
+
507
+
508
+ class ParentSchema(Schema):
509
+ id = fields.Str()
510
+ children = fields.List(
511
+ fields.Nested(ChildSchema(only=("id", "parent", "siblings")))
512
+ )
513
+ spouse = fields.Nested(lambda: ParentSchema(only=("id",)))
514
+
515
+ When passing a `Schema <marshmallow.Schema>` instance as the first argument,
516
+ the instance's ``exclude``, ``only``, and ``many`` attributes will be respected.
517
+
518
+ Therefore, when passing the ``exclude``, ``only``, or ``many`` arguments to `fields.Nested`,
519
+ you should pass a `Schema <marshmallow.Schema>` class (not an instance) as the first argument.
520
+
521
+ ::
522
+
523
+ # Yes
524
+ author = fields.Nested(UserSchema, only=("id", "name"))
525
+
526
+ # No
527
+ author = fields.Nested(UserSchema(), only=("id", "name"))
528
+
529
+ :param nested: `Schema <marshmallow.Schema>` instance, class, class name (string), dictionary, or callable that
530
+ returns a `Schema <marshmallow.Schema>` or dictionary.
531
+ Dictionaries are converted with `Schema.from_dict <marshmallow.Schema.from_dict>`.
532
+ :param exclude: A list or tuple of fields to exclude.
533
+ :param only: A list or tuple of fields to marshal. If `None`, all fields are marshalled.
534
+ This parameter takes precedence over ``exclude``.
535
+ :param many: Whether the field is a collection of objects.
536
+ :param unknown: Whether to exclude, include, or raise an error for unknown
537
+ fields in the data. Use `EXCLUDE`, `INCLUDE` or `RAISE`.
538
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
539
+ """
540
+
541
+ #: Default error messages.
542
+ default_error_messages = {"type": "Invalid type."}
543
+
544
+ def __init__(
545
+ self,
546
+ nested: (
547
+ Schema
548
+ | SchemaMeta
549
+ | str
550
+ | dict[str, Field]
551
+ | typing.Callable[[], Schema | SchemaMeta | dict[str, Field]]
552
+ ),
553
+ *,
554
+ dump_default: typing.Any = missing_,
555
+ default: typing.Any = missing_,
556
+ only: types.StrSequenceOrSet | None = None,
557
+ exclude: types.StrSequenceOrSet = (),
558
+ many: bool = False,
559
+ unknown: str | None = None,
560
+ **kwargs,
561
+ ):
562
+ # Raise error if only or exclude is passed as string, not list of strings
563
+ if only is not None and not is_collection(only):
564
+ raise StringNotCollectionError('"only" should be a collection of strings.')
565
+ if not is_collection(exclude):
566
+ raise StringNotCollectionError(
567
+ '"exclude" should be a collection of strings.'
568
+ )
569
+ if nested == "self":
570
+ warnings.warn(
571
+ "Passing 'self' to `Nested` is deprecated. "
572
+ "Use `Nested(lambda: MySchema(...))` instead.",
573
+ RemovedInMarshmallow4Warning,
574
+ stacklevel=2,
575
+ )
576
+ self.nested = nested
577
+ self.only = only
578
+ self.exclude = exclude
579
+ self.many = many
580
+ self.unknown = unknown
581
+ self._schema: Schema | None = None # Cached Schema instance
582
+ super().__init__(default=default, dump_default=dump_default, **kwargs)
583
+
584
+ @property
585
+ def schema(self) -> Schema:
586
+ """The nested `Schema <marshmallow.Schema>` object.
587
+
588
+ .. versionchanged:: 1.0.0
589
+ Renamed from ``serializer`` to ``schema``.
590
+ """
591
+ if not self._schema:
592
+ # Inherit context from parent.
593
+ context = getattr(self.parent, "context", {})
594
+ if callable(self.nested) and not isinstance(self.nested, type):
595
+ nested = self.nested()
596
+ else:
597
+ nested = typing.cast("Schema", self.nested)
598
+ # defer the import of `marshmallow.schema` to avoid circular imports
599
+ from marshmallow.schema import Schema
600
+
601
+ if isinstance(nested, dict):
602
+ nested = Schema.from_dict(nested)
603
+
604
+ if isinstance(nested, Schema):
605
+ self._schema = copy.copy(nested)
606
+ self._schema.context.update(context)
607
+ # Respect only and exclude passed from parent and re-initialize fields
608
+ set_class = typing.cast(type[set], self._schema.set_class)
609
+ if self.only is not None:
610
+ if self._schema.only is not None:
611
+ original = self._schema.only
612
+ else: # only=None -> all fields
613
+ original = self._schema.fields.keys()
614
+ self._schema.only = set_class(self.only) & set_class(original)
615
+ if self.exclude:
616
+ original = self._schema.exclude
617
+ self._schema.exclude = set_class(self.exclude) | set_class(original)
618
+ self._schema._init_fields()
619
+ else:
620
+ if isinstance(nested, type) and issubclass(nested, Schema):
621
+ schema_class: type[Schema] = nested
622
+ elif not isinstance(nested, (str, bytes)):
623
+ raise ValueError(
624
+ "`Nested` fields must be passed a "
625
+ f"`Schema`, not {nested.__class__}."
626
+ )
627
+ elif nested == "self":
628
+ schema_class = typing.cast(Schema, self.root).__class__
629
+ else:
630
+ schema_class = class_registry.get_class(nested, all=False)
631
+ self._schema = schema_class(
632
+ many=self.many,
633
+ only=self.only,
634
+ exclude=self.exclude,
635
+ context=context,
636
+ load_only=self._nested_normalized_option("load_only"),
637
+ dump_only=self._nested_normalized_option("dump_only"),
638
+ )
639
+ return self._schema
640
+
641
+ def _nested_normalized_option(self, option_name: str) -> list[str]:
642
+ nested_field = f"{self.name}."
643
+ return [
644
+ field.split(nested_field, 1)[1]
645
+ for field in getattr(self.root, option_name, set())
646
+ if field.startswith(nested_field)
647
+ ]
648
+
649
+ def _serialize(self, nested_obj, attr, obj, **kwargs):
650
+ # Load up the schema first. This allows a RegistryError to be raised
651
+ # if an invalid schema name was passed
652
+ schema = self.schema
653
+ if nested_obj is None:
654
+ return None
655
+ many = schema.many or self.many
656
+ return schema.dump(nested_obj, many=many)
657
+
658
+ def _test_collection(self, value: typing.Any) -> None:
659
+ many = self.schema.many or self.many
660
+ if many and not utils.is_collection(value):
661
+ raise self.make_error("type", input=value, type=value.__class__.__name__)
662
+
663
+ def _load(
664
+ self, value: typing.Any, partial: bool | types.StrSequenceOrSet | None = None
665
+ ):
666
+ try:
667
+ valid_data = self.schema.load(value, unknown=self.unknown, partial=partial)
668
+ except ValidationError as error:
669
+ raise ValidationError(
670
+ error.messages, valid_data=error.valid_data
671
+ ) from error
672
+ return valid_data
673
+
674
+ def _deserialize(
675
+ self,
676
+ value: typing.Any,
677
+ attr: str | None,
678
+ data: typing.Mapping[str, typing.Any] | None,
679
+ partial: bool | types.StrSequenceOrSet | None = None,
680
+ **kwargs,
681
+ ) -> typing.Any:
682
+ """Same as :meth:`Field._deserialize` with additional ``partial`` argument.
683
+
684
+ :param partial: For nested schemas, the ``partial``
685
+ parameter passed to `marshmallow.Schema.load`.
686
+
687
+ .. versionchanged:: 3.0.0
688
+ Add ``partial`` parameter.
689
+ """
690
+ self._test_collection(value)
691
+ return self._load(value, partial=partial)
692
+
693
+
694
+ class Pluck(Nested):
695
+ """Allows you to replace nested data with one of the data's fields.
696
+
697
+ Example: ::
698
+
699
+ from marshmallow import Schema, fields
700
+
701
+
702
+ class ArtistSchema(Schema):
703
+ id = fields.Int()
704
+ name = fields.Str()
705
+
706
+
707
+ class AlbumSchema(Schema):
708
+ artist = fields.Pluck(ArtistSchema, "id")
709
+
710
+
711
+ in_data = {"artist": 42}
712
+ loaded = AlbumSchema().load(in_data) # => {'artist': {'id': 42}}
713
+ dumped = AlbumSchema().dump(loaded) # => {'artist': 42}
714
+
715
+ :param nested: The Schema class or class name (string)
716
+ to nest, or ``"self"`` to nest the `Schema <marshmallow.Schema>` within itself.
717
+ :param field_name: The key to pluck a value from.
718
+ :param kwargs: The same keyword arguments that :class:`Nested` receives.
719
+ """
720
+
721
+ def __init__(
722
+ self,
723
+ nested: Schema | SchemaMeta | str | typing.Callable[[], Schema],
724
+ field_name: str,
725
+ *,
726
+ many: bool = False,
727
+ unknown: str | None = None,
728
+ **kwargs,
729
+ ):
730
+ super().__init__(
731
+ nested, only=(field_name,), many=many, unknown=unknown, **kwargs
732
+ )
733
+ self.field_name = field_name
734
+
735
+ @property
736
+ def _field_data_key(self) -> str:
737
+ only_field = self.schema.fields[self.field_name]
738
+ return only_field.data_key or self.field_name
739
+
740
+ def _serialize(self, nested_obj, attr, obj, **kwargs):
741
+ ret = super()._serialize(nested_obj, attr, obj, **kwargs)
742
+ if ret is None:
743
+ return None
744
+ if self.many:
745
+ return utils.pluck(ret, key=self._field_data_key)
746
+ return ret[self._field_data_key]
747
+
748
+ def _deserialize(self, value, attr, data, partial=None, **kwargs):
749
+ self._test_collection(value)
750
+ if self.many:
751
+ value = [{self._field_data_key: v} for v in value]
752
+ else:
753
+ value = {self._field_data_key: value}
754
+ return self._load(value, partial=partial)
755
+
756
+
757
+ class List(Field):
758
+ """A list field, composed with another `Field` class or
759
+ instance.
760
+
761
+ Example: ::
762
+
763
+ numbers = fields.List(fields.Float())
764
+
765
+ :param cls_or_instance: A field class or instance.
766
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
767
+
768
+ .. versionchanged:: 3.0.0rc9
769
+ Does not serialize scalar values to single-item lists.
770
+ """
771
+
772
+ #: Default error messages.
773
+ default_error_messages = {"invalid": "Not a valid list."}
774
+
775
+ def __init__(self, cls_or_instance: Field | type[Field], **kwargs):
776
+ super().__init__(**kwargs)
777
+ try:
778
+ self.inner = resolve_field_instance(cls_or_instance)
779
+ except FieldInstanceResolutionError as error:
780
+ raise ValueError(
781
+ "The list elements must be a subclass or instance of "
782
+ "marshmallow.base.FieldABC."
783
+ ) from error
784
+ if isinstance(self.inner, Nested):
785
+ self.only = self.inner.only
786
+ self.exclude = self.inner.exclude
787
+
788
+ def _bind_to_schema(self, field_name: str, schema: Schema | Field) -> None:
789
+ super()._bind_to_schema(field_name, schema)
790
+ self.inner = copy.deepcopy(self.inner)
791
+ self.inner._bind_to_schema(field_name, self)
792
+ if isinstance(self.inner, Nested):
793
+ self.inner.only = self.only
794
+ self.inner.exclude = self.exclude
795
+
796
+ def _serialize(self, value, attr, obj, **kwargs) -> list[typing.Any] | None:
797
+ if value is None:
798
+ return None
799
+ return [self.inner._serialize(each, attr, obj, **kwargs) for each in value]
800
+
801
+ def _deserialize(self, value, attr, data, **kwargs) -> list[typing.Any]:
802
+ if not utils.is_collection(value):
803
+ raise self.make_error("invalid")
804
+
805
+ result = []
806
+ errors = {}
807
+ for idx, each in enumerate(value):
808
+ try:
809
+ result.append(self.inner.deserialize(each, **kwargs))
810
+ except ValidationError as error:
811
+ if error.valid_data is not None:
812
+ result.append(error.valid_data)
813
+ errors.update({idx: error.messages})
814
+ if errors:
815
+ raise ValidationError(errors, valid_data=result)
816
+ return result
817
+
818
+
819
+ class Tuple(Field):
820
+ """A tuple field, composed of a fixed number of other `Field` classes or
821
+ instances
822
+
823
+ Example: ::
824
+
825
+ row = Tuple((fields.String(), fields.Integer(), fields.Float()))
826
+
827
+ .. note::
828
+ Because of the structured nature of `collections.namedtuple` and
829
+ `typing.NamedTuple`, using a Schema within a Nested field for them is
830
+ more appropriate than using a `Tuple` field.
831
+
832
+ :param tuple_fields: An iterable of field classes or
833
+ instances.
834
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
835
+
836
+ .. versionadded:: 3.0.0rc4
837
+ """
838
+
839
+ #: Default error messages.
840
+ default_error_messages = {"invalid": "Not a valid tuple."}
841
+
842
+ def __init__(
843
+ self,
844
+ tuple_fields: typing.Iterable[Field] | typing.Iterable[type[Field]],
845
+ **kwargs,
846
+ ):
847
+ super().__init__(**kwargs)
848
+ if not utils.is_collection(tuple_fields):
849
+ raise ValueError(
850
+ "tuple_fields must be an iterable of Field classes or instances."
851
+ )
852
+
853
+ try:
854
+ self.tuple_fields = [
855
+ resolve_field_instance(cls_or_instance)
856
+ for cls_or_instance in tuple_fields
857
+ ]
858
+ except FieldInstanceResolutionError as error:
859
+ raise ValueError(
860
+ 'Elements of "tuple_fields" must be subclasses or '
861
+ "instances of marshmallow.base.FieldABC."
862
+ ) from error
863
+
864
+ self.validate_length = Length(equal=len(self.tuple_fields))
865
+
866
+ def _bind_to_schema(self, field_name: str, schema: Schema | Field) -> None:
867
+ super()._bind_to_schema(field_name, schema)
868
+ new_tuple_fields = []
869
+ for field in self.tuple_fields:
870
+ new_field = copy.deepcopy(field)
871
+ new_field._bind_to_schema(field_name, self)
872
+ new_tuple_fields.append(new_field)
873
+
874
+ self.tuple_fields = new_tuple_fields
875
+
876
+ def _serialize(self, value, attr, obj, **kwargs) -> tuple | None:
877
+ if value is None:
878
+ return None
879
+
880
+ return tuple(
881
+ field._serialize(each, attr, obj, **kwargs)
882
+ for field, each in zip(self.tuple_fields, value)
883
+ )
884
+
885
+ def _deserialize(self, value, attr, data, **kwargs) -> tuple:
886
+ if not utils.is_collection(value):
887
+ raise self.make_error("invalid")
888
+
889
+ self.validate_length(value)
890
+
891
+ result = []
892
+ errors = {}
893
+
894
+ for idx, (field, each) in enumerate(zip(self.tuple_fields, value)):
895
+ try:
896
+ result.append(field.deserialize(each, **kwargs))
897
+ except ValidationError as error:
898
+ if error.valid_data is not None:
899
+ result.append(error.valid_data)
900
+ errors.update({idx: error.messages})
901
+ if errors:
902
+ raise ValidationError(errors, valid_data=result)
903
+
904
+ return tuple(result)
905
+
906
+
907
+ class String(Field):
908
+ """A string field.
909
+
910
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
911
+ """
912
+
913
+ #: Default error messages.
914
+ default_error_messages = {
915
+ "invalid": "Not a valid string.",
916
+ "invalid_utf8": "Not a valid utf-8 string.",
917
+ }
918
+
919
+ def _serialize(self, value, attr, obj, **kwargs) -> str | None:
920
+ if value is None:
921
+ return None
922
+ return utils.ensure_text_type(value)
923
+
924
+ def _deserialize(self, value, attr, data, **kwargs) -> typing.Any:
925
+ if not isinstance(value, (str, bytes)):
926
+ raise self.make_error("invalid")
927
+ try:
928
+ return utils.ensure_text_type(value)
929
+ except UnicodeDecodeError as error:
930
+ raise self.make_error("invalid_utf8") from error
931
+
932
+
933
+ class UUID(String):
934
+ """A UUID field."""
935
+
936
+ #: Default error messages.
937
+ default_error_messages = {"invalid_uuid": "Not a valid UUID."}
938
+
939
+ def _validated(self, value) -> uuid.UUID | None:
940
+ """Format the value or raise a :exc:`ValidationError` if an error occurs."""
941
+ if value is None:
942
+ return None
943
+ if isinstance(value, uuid.UUID):
944
+ return value
945
+ try:
946
+ if isinstance(value, bytes) and len(value) == 16:
947
+ return uuid.UUID(bytes=value)
948
+ return uuid.UUID(value)
949
+ except (ValueError, AttributeError, TypeError) as error:
950
+ raise self.make_error("invalid_uuid") from error
951
+
952
+ def _deserialize(self, value, attr, data, **kwargs) -> uuid.UUID | None:
953
+ return self._validated(value)
954
+
955
+
956
+ _NumType = typing.TypeVar("_NumType")
957
+
958
+
959
+ class Number(Field, typing.Generic[_NumType]):
960
+ """Base class for number fields.
961
+
962
+ :param as_string: If `True`, format the serialized value as a string.
963
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
964
+
965
+ .. versionchanged:: 3.24.0
966
+ `Number <marshmallow.fields.Number>` should no longer be used as a field within a `Schema <marshmallow.Schema>`.
967
+ Use `Integer <marshmallow.fields.Integer>`, `Float <marshmallow.fields.Float>`, or `Decimal <marshmallow.fields.Decimal>` instead.
968
+ """
969
+
970
+ num_type: type = float
971
+
972
+ #: Default error messages.
973
+ default_error_messages = {
974
+ "invalid": "Not a valid number.",
975
+ "too_large": "Number too large.",
976
+ }
977
+
978
+ def __init__(self, *, as_string: bool = False, **kwargs):
979
+ if self.__class__ is Number:
980
+ warnings.warn(
981
+ "`Number` field should not be instantiated. Use `Integer`, `Float`, or `Decimal` instead.",
982
+ ChangedInMarshmallow4Warning,
983
+ stacklevel=2,
984
+ )
985
+ self.as_string = as_string
986
+ super().__init__(**kwargs)
987
+
988
+ def _format_num(self, value) -> _NumType:
989
+ """Return the number value for value, given this field's `num_type`."""
990
+ return self.num_type(value)
991
+
992
+ def _validated(self, value: typing.Any) -> _NumType:
993
+ """Format the value or raise a :exc:`ValidationError` if an error occurs."""
994
+ # (value is True or value is False) is ~5x faster than isinstance(value, bool)
995
+ if value is True or value is False:
996
+ raise self.make_error("invalid", input=value)
997
+ try:
998
+ return self._format_num(value)
999
+ except (TypeError, ValueError) as error:
1000
+ raise self.make_error("invalid", input=value) from error
1001
+ except OverflowError as error:
1002
+ raise self.make_error("too_large", input=value) from error
1003
+
1004
+ def _to_string(self, value: _NumType) -> str:
1005
+ return str(value)
1006
+
1007
+ def _serialize(self, value, attr, obj, **kwargs) -> str | _NumType | None:
1008
+ """Return a string if `self.as_string=True`, otherwise return this field's `num_type`."""
1009
+ if value is None:
1010
+ return None
1011
+ ret: _NumType = self._format_num(value)
1012
+ return self._to_string(ret) if self.as_string else ret
1013
+
1014
+ def _deserialize(self, value, attr, data, **kwargs) -> _NumType | None:
1015
+ return self._validated(value)
1016
+
1017
+
1018
+ class Integer(Number[int]):
1019
+ """An integer field.
1020
+
1021
+ :param strict: If `True`, only integer types are valid.
1022
+ Otherwise, any value castable to `int` is valid.
1023
+ :param kwargs: The same keyword arguments that :class:`Number` receives.
1024
+ """
1025
+
1026
+ num_type = int
1027
+
1028
+ #: Default error messages.
1029
+ default_error_messages = {"invalid": "Not a valid integer."}
1030
+
1031
+ def __init__(self, *, strict: bool = False, **kwargs):
1032
+ self.strict = strict
1033
+ super().__init__(**kwargs)
1034
+
1035
+ # override Number
1036
+ def _validated(self, value: typing.Any) -> int:
1037
+ if self.strict and not isinstance(value, numbers.Integral):
1038
+ raise self.make_error("invalid", input=value)
1039
+ return super()._validated(value)
1040
+
1041
+
1042
+ class Float(Number[float]):
1043
+ """A double as an IEEE-754 double precision string.
1044
+
1045
+ :param allow_nan: If `True`, `NaN`, `Infinity` and `-Infinity` are allowed,
1046
+ even though they are illegal according to the JSON specification.
1047
+ :param as_string: If `True`, format the value as a string.
1048
+ :param kwargs: The same keyword arguments that :class:`Number` receives.
1049
+ """
1050
+
1051
+ num_type = float
1052
+
1053
+ #: Default error messages.
1054
+ default_error_messages = {
1055
+ "special": "Special numeric values (nan or infinity) are not permitted."
1056
+ }
1057
+
1058
+ def __init__(self, *, allow_nan: bool = False, as_string: bool = False, **kwargs):
1059
+ self.allow_nan = allow_nan
1060
+ super().__init__(as_string=as_string, **kwargs)
1061
+
1062
+ def _validated(self, value: typing.Any) -> float:
1063
+ num = super()._validated(value)
1064
+ if self.allow_nan is False:
1065
+ if math.isnan(num) or num == float("inf") or num == float("-inf"):
1066
+ raise self.make_error("special")
1067
+ return num
1068
+
1069
+
1070
+ class Decimal(Number[decimal.Decimal]):
1071
+ """A field that (de)serializes to the Python ``decimal.Decimal`` type.
1072
+ It's safe to use when dealing with money values, percentages, ratios
1073
+ or other numbers where precision is critical.
1074
+
1075
+ .. warning::
1076
+
1077
+ This field serializes to a `decimal.Decimal` object by default. If you need
1078
+ to render your data as JSON, keep in mind that the `json` module from the
1079
+ standard library does not encode `decimal.Decimal`. Therefore, you must use
1080
+ a JSON library that can handle decimals, such as `simplejson`, or serialize
1081
+ to a string by passing ``as_string=True``.
1082
+
1083
+ .. warning::
1084
+
1085
+ If a JSON `float` value is passed to this field for deserialization it will
1086
+ first be cast to its corresponding `string` value before being deserialized
1087
+ to a `decimal.Decimal` object. The default `__str__` implementation of the
1088
+ built-in Python `float` type may apply a destructive transformation upon
1089
+ its input data and therefore cannot be relied upon to preserve precision.
1090
+ To avoid this, you can instead pass a JSON `string` to be deserialized
1091
+ directly.
1092
+
1093
+ :param places: How many decimal places to quantize the value. If `None`, does
1094
+ not quantize the value.
1095
+ :param rounding: How to round the value during quantize, for example
1096
+ `decimal.ROUND_UP`. If `None`, uses the rounding value from
1097
+ the current thread's context.
1098
+ :param allow_nan: If `True`, `NaN`, `Infinity` and `-Infinity` are allowed,
1099
+ even though they are illegal according to the JSON specification.
1100
+ :param as_string: If `True`, serialize to a string instead of a Python
1101
+ `decimal.Decimal` type.
1102
+ :param kwargs: The same keyword arguments that :class:`Number` receives.
1103
+
1104
+ .. versionadded:: 1.2.0
1105
+ """
1106
+
1107
+ num_type = decimal.Decimal
1108
+
1109
+ #: Default error messages.
1110
+ default_error_messages = {
1111
+ "special": "Special numeric values (nan or infinity) are not permitted."
1112
+ }
1113
+
1114
+ def __init__(
1115
+ self,
1116
+ places: int | None = None,
1117
+ rounding: str | None = None,
1118
+ *,
1119
+ allow_nan: bool = False,
1120
+ as_string: bool = False,
1121
+ **kwargs,
1122
+ ):
1123
+ self.places = (
1124
+ decimal.Decimal((0, (1,), -places)) if places is not None else None
1125
+ )
1126
+ self.rounding = rounding
1127
+ self.allow_nan = allow_nan
1128
+ super().__init__(as_string=as_string, **kwargs)
1129
+
1130
+ # override Number
1131
+ def _format_num(self, value):
1132
+ num = decimal.Decimal(str(value))
1133
+ if self.allow_nan:
1134
+ if num.is_nan():
1135
+ return decimal.Decimal("NaN") # avoid sNaN, -sNaN and -NaN
1136
+ if self.places is not None and num.is_finite():
1137
+ num = num.quantize(self.places, rounding=self.rounding)
1138
+ return num
1139
+
1140
+ # override Number
1141
+ def _validated(self, value: typing.Any) -> decimal.Decimal:
1142
+ try:
1143
+ num = super()._validated(value)
1144
+ except decimal.InvalidOperation as error:
1145
+ raise self.make_error("invalid") from error
1146
+ if not self.allow_nan and (num.is_nan() or num.is_infinite()):
1147
+ raise self.make_error("special")
1148
+ return num
1149
+
1150
+ # override Number
1151
+ def _to_string(self, value: decimal.Decimal) -> str:
1152
+ return format(value, "f")
1153
+
1154
+
1155
+ class Boolean(Field):
1156
+ """A boolean field.
1157
+
1158
+ :param truthy: Values that will (de)serialize to `True`. If an empty
1159
+ set, any non-falsy value will deserialize to `True`. If `None`,
1160
+ `marshmallow.fields.Boolean.truthy` will be used.
1161
+ :param falsy: Values that will (de)serialize to `False`. If `None`,
1162
+ `marshmallow.fields.Boolean.falsy` will be used.
1163
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1164
+ """
1165
+
1166
+ #: Default truthy values.
1167
+ truthy = {
1168
+ "t",
1169
+ "T",
1170
+ "true",
1171
+ "True",
1172
+ "TRUE",
1173
+ "on",
1174
+ "On",
1175
+ "ON",
1176
+ "y",
1177
+ "Y",
1178
+ "yes",
1179
+ "Yes",
1180
+ "YES",
1181
+ "1",
1182
+ 1,
1183
+ # Equal to 1
1184
+ # True,
1185
+ }
1186
+ #: Default falsy values.
1187
+ falsy = {
1188
+ "f",
1189
+ "F",
1190
+ "false",
1191
+ "False",
1192
+ "FALSE",
1193
+ "off",
1194
+ "Off",
1195
+ "OFF",
1196
+ "n",
1197
+ "N",
1198
+ "no",
1199
+ "No",
1200
+ "NO",
1201
+ "0",
1202
+ 0,
1203
+ # Equal to 0
1204
+ # 0.0,
1205
+ # False,
1206
+ }
1207
+
1208
+ #: Default error messages.
1209
+ default_error_messages = {"invalid": "Not a valid boolean."}
1210
+
1211
+ def __init__(
1212
+ self,
1213
+ *,
1214
+ truthy: typing.Iterable | None = None,
1215
+ falsy: typing.Iterable | None = None,
1216
+ **kwargs,
1217
+ ):
1218
+ super().__init__(**kwargs)
1219
+
1220
+ if truthy is not None:
1221
+ self.truthy = set(truthy)
1222
+ if falsy is not None:
1223
+ self.falsy = set(falsy)
1224
+
1225
+ def _serialize(
1226
+ self, value: typing.Any, attr: str | None, obj: typing.Any, **kwargs
1227
+ ):
1228
+ if value is None:
1229
+ return None
1230
+
1231
+ try:
1232
+ if value in self.truthy:
1233
+ return True
1234
+ if value in self.falsy:
1235
+ return False
1236
+ except TypeError:
1237
+ pass
1238
+
1239
+ return bool(value)
1240
+
1241
+ def _deserialize(self, value, attr, data, **kwargs):
1242
+ if not self.truthy:
1243
+ return bool(value)
1244
+ try:
1245
+ if value in self.truthy:
1246
+ return True
1247
+ if value in self.falsy:
1248
+ return False
1249
+ except TypeError as error:
1250
+ raise self.make_error("invalid", input=value) from error
1251
+ raise self.make_error("invalid", input=value)
1252
+
1253
+
1254
+ class DateTime(Field):
1255
+ """A formatted datetime string.
1256
+
1257
+ Example: ``'2014-12-22T03:12:58.019077+00:00'``
1258
+
1259
+ :param format: Either ``"rfc"`` (for RFC822), ``"iso"`` (for ISO8601),
1260
+ ``"timestamp"``, ``"timestamp_ms"`` (for a POSIX timestamp) or a date format string.
1261
+ If `None`, defaults to "iso".
1262
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1263
+
1264
+ .. versionchanged:: 3.0.0rc9
1265
+ Does not modify timezone information on (de)serialization.
1266
+ .. versionchanged:: 3.19
1267
+ Add timestamp as a format.
1268
+ """
1269
+
1270
+ SERIALIZATION_FUNCS: dict[str, typing.Callable[[typing.Any], str | float]] = {
1271
+ "iso": utils.isoformat,
1272
+ "iso8601": utils.isoformat,
1273
+ "rfc": utils.rfcformat,
1274
+ "rfc822": utils.rfcformat,
1275
+ "timestamp": utils.timestamp,
1276
+ "timestamp_ms": utils.timestamp_ms,
1277
+ }
1278
+
1279
+ DESERIALIZATION_FUNCS: dict[str, typing.Callable[[str], typing.Any]] = {
1280
+ "iso": utils.from_iso_datetime,
1281
+ "iso8601": utils.from_iso_datetime,
1282
+ "rfc": utils.from_rfc,
1283
+ "rfc822": utils.from_rfc,
1284
+ "timestamp": utils.from_timestamp,
1285
+ "timestamp_ms": utils.from_timestamp_ms,
1286
+ }
1287
+
1288
+ DEFAULT_FORMAT = "iso"
1289
+
1290
+ OBJ_TYPE = "datetime"
1291
+
1292
+ SCHEMA_OPTS_VAR_NAME = "datetimeformat"
1293
+
1294
+ #: Default error messages.
1295
+ default_error_messages = {
1296
+ "invalid": "Not a valid {obj_type}.",
1297
+ "invalid_awareness": "Not a valid {awareness} {obj_type}.",
1298
+ "format": '"{input}" cannot be formatted as a {obj_type}.',
1299
+ }
1300
+
1301
+ def __init__(self, format: str | None = None, **kwargs) -> None: # noqa: A002
1302
+ super().__init__(**kwargs)
1303
+ # Allow this to be None. It may be set later in the ``_serialize``
1304
+ # or ``_deserialize`` methods. This allows a Schema to dynamically set the
1305
+ # format, e.g. from a Meta option
1306
+ self.format = format
1307
+
1308
+ def _bind_to_schema(self, field_name, schema):
1309
+ super()._bind_to_schema(field_name, schema)
1310
+ self.format = (
1311
+ self.format
1312
+ or getattr(self.root.opts, self.SCHEMA_OPTS_VAR_NAME)
1313
+ or self.DEFAULT_FORMAT
1314
+ )
1315
+
1316
+ def _serialize(self, value, attr, obj, **kwargs) -> str | float | None:
1317
+ if value is None:
1318
+ return None
1319
+ data_format = self.format or self.DEFAULT_FORMAT
1320
+ format_func = self.SERIALIZATION_FUNCS.get(data_format)
1321
+ if format_func:
1322
+ return format_func(value)
1323
+ return value.strftime(data_format)
1324
+
1325
+ def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime:
1326
+ data_format = self.format or self.DEFAULT_FORMAT
1327
+ func = self.DESERIALIZATION_FUNCS.get(data_format)
1328
+ try:
1329
+ if func:
1330
+ return func(value)
1331
+ return self._make_object_from_format(value, data_format)
1332
+ except (TypeError, AttributeError, ValueError) as error:
1333
+ raise self.make_error(
1334
+ "invalid", input=value, obj_type=self.OBJ_TYPE
1335
+ ) from error
1336
+
1337
+ @staticmethod
1338
+ def _make_object_from_format(value, data_format) -> dt.datetime:
1339
+ return dt.datetime.strptime(value, data_format)
1340
+
1341
+
1342
+ class NaiveDateTime(DateTime):
1343
+ """A formatted naive datetime string.
1344
+
1345
+ :param format: See :class:`DateTime`.
1346
+ :param timezone: Used on deserialization. If `None`,
1347
+ aware datetimes are rejected. If not `None`, aware datetimes are
1348
+ converted to this timezone before their timezone information is
1349
+ removed.
1350
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1351
+
1352
+ .. versionadded:: 3.0.0rc9
1353
+ """
1354
+
1355
+ AWARENESS = "naive"
1356
+
1357
+ def __init__(
1358
+ self,
1359
+ format: str | None = None, # noqa: A002
1360
+ *,
1361
+ timezone: dt.timezone | None = None,
1362
+ **kwargs,
1363
+ ) -> None:
1364
+ super().__init__(format=format, **kwargs)
1365
+ self.timezone = timezone
1366
+
1367
+ def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime:
1368
+ ret = super()._deserialize(value, attr, data, **kwargs)
1369
+ if is_aware(ret):
1370
+ if self.timezone is None:
1371
+ raise self.make_error(
1372
+ "invalid_awareness",
1373
+ awareness=self.AWARENESS,
1374
+ obj_type=self.OBJ_TYPE,
1375
+ )
1376
+ ret = ret.astimezone(self.timezone).replace(tzinfo=None)
1377
+ return ret
1378
+
1379
+
1380
+ class AwareDateTime(DateTime):
1381
+ """A formatted aware datetime string.
1382
+
1383
+ :param format: See :class:`DateTime`.
1384
+ :param default_timezone: Used on deserialization. If `None`, naive
1385
+ datetimes are rejected. If not `None`, naive datetimes are set this
1386
+ timezone.
1387
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1388
+
1389
+ .. versionadded:: 3.0.0rc9
1390
+ """
1391
+
1392
+ AWARENESS = "aware"
1393
+
1394
+ def __init__(
1395
+ self,
1396
+ format: str | None = None, # noqa: A002
1397
+ *,
1398
+ default_timezone: dt.tzinfo | None = None,
1399
+ **kwargs,
1400
+ ) -> None:
1401
+ super().__init__(format=format, **kwargs)
1402
+ self.default_timezone = default_timezone
1403
+
1404
+ def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime:
1405
+ ret = super()._deserialize(value, attr, data, **kwargs)
1406
+ if not is_aware(ret):
1407
+ if self.default_timezone is None:
1408
+ raise self.make_error(
1409
+ "invalid_awareness",
1410
+ awareness=self.AWARENESS,
1411
+ obj_type=self.OBJ_TYPE,
1412
+ )
1413
+ ret = ret.replace(tzinfo=self.default_timezone)
1414
+ return ret
1415
+
1416
+
1417
+ class Time(DateTime):
1418
+ """A formatted time string.
1419
+
1420
+ Example: ``'03:12:58.019077'``
1421
+
1422
+ :param format: Either ``"iso"`` (for ISO8601) or a date format string.
1423
+ If `None`, defaults to "iso".
1424
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1425
+ """
1426
+
1427
+ SERIALIZATION_FUNCS = {"iso": utils.to_iso_time, "iso8601": utils.to_iso_time}
1428
+
1429
+ DESERIALIZATION_FUNCS = {"iso": utils.from_iso_time, "iso8601": utils.from_iso_time}
1430
+
1431
+ DEFAULT_FORMAT = "iso"
1432
+
1433
+ OBJ_TYPE = "time"
1434
+
1435
+ SCHEMA_OPTS_VAR_NAME = "timeformat"
1436
+
1437
+ @staticmethod
1438
+ def _make_object_from_format(value, data_format):
1439
+ return dt.datetime.strptime(value, data_format).time()
1440
+
1441
+
1442
+ class Date(DateTime):
1443
+ """ISO8601-formatted date string.
1444
+
1445
+ :param format: Either ``"iso"`` (for ISO8601) or a date format string.
1446
+ If `None`, defaults to "iso".
1447
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1448
+ """
1449
+
1450
+ #: Default error messages.
1451
+ default_error_messages = {
1452
+ "invalid": "Not a valid date.",
1453
+ "format": '"{input}" cannot be formatted as a date.',
1454
+ }
1455
+
1456
+ SERIALIZATION_FUNCS = {"iso": utils.to_iso_date, "iso8601": utils.to_iso_date}
1457
+
1458
+ DESERIALIZATION_FUNCS = {"iso": utils.from_iso_date, "iso8601": utils.from_iso_date}
1459
+
1460
+ DEFAULT_FORMAT = "iso"
1461
+
1462
+ OBJ_TYPE = "date"
1463
+
1464
+ SCHEMA_OPTS_VAR_NAME = "dateformat"
1465
+
1466
+ @staticmethod
1467
+ def _make_object_from_format(value, data_format):
1468
+ return dt.datetime.strptime(value, data_format).date()
1469
+
1470
+
1471
+ class TimeDelta(Field):
1472
+ """A field that (de)serializes a :class:`datetime.timedelta` object to an
1473
+ integer or float and vice versa. The integer or float can represent the
1474
+ number of days, seconds or microseconds.
1475
+
1476
+ :param precision: Influences how the integer or float is interpreted during
1477
+ (de)serialization. Must be 'days', 'seconds', 'microseconds',
1478
+ 'milliseconds', 'minutes', 'hours' or 'weeks'.
1479
+ :param serialization_type: Whether to (de)serialize to a `int` or `float`.
1480
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1481
+
1482
+ Integer Caveats
1483
+ ---------------
1484
+ Any fractional parts (which depends on the precision used) will be truncated
1485
+ when serializing using `int`.
1486
+
1487
+ Float Caveats
1488
+ -------------
1489
+ Use of `float` when (de)serializing may result in data precision loss due
1490
+ to the way machines handle floating point values.
1491
+
1492
+ Regardless of the precision chosen, the fractional part when using `float`
1493
+ will always be truncated to microseconds.
1494
+ For example, `1.12345` interpreted as microseconds will result in `timedelta(microseconds=1)`.
1495
+
1496
+ .. versionchanged:: 3.17.0
1497
+ Allow (de)serialization to `float` through use of a new `serialization_type` parameter.
1498
+ `int` is the default to retain previous behaviour.
1499
+ """
1500
+
1501
+ DAYS = "days"
1502
+ SECONDS = "seconds"
1503
+ MICROSECONDS = "microseconds"
1504
+ MILLISECONDS = "milliseconds"
1505
+ MINUTES = "minutes"
1506
+ HOURS = "hours"
1507
+ WEEKS = "weeks"
1508
+
1509
+ #: Default error messages.
1510
+ default_error_messages = {
1511
+ "invalid": "Not a valid period of time.",
1512
+ "format": "{input!r} cannot be formatted as a timedelta.",
1513
+ }
1514
+
1515
+ def __init__(
1516
+ self,
1517
+ precision: str = SECONDS,
1518
+ serialization_type: type[int | float] = int,
1519
+ **kwargs,
1520
+ ):
1521
+ precision = precision.lower()
1522
+ units = (
1523
+ self.DAYS,
1524
+ self.SECONDS,
1525
+ self.MICROSECONDS,
1526
+ self.MILLISECONDS,
1527
+ self.MINUTES,
1528
+ self.HOURS,
1529
+ self.WEEKS,
1530
+ )
1531
+
1532
+ if precision not in units:
1533
+ msg = 'The precision must be {} or "{}".'.format(
1534
+ ", ".join([f'"{each}"' for each in units[:-1]]), units[-1]
1535
+ )
1536
+ raise ValueError(msg)
1537
+
1538
+ if serialization_type not in (int, float):
1539
+ raise ValueError("The serialization type must be one of int or float")
1540
+
1541
+ self.precision = precision
1542
+ self.serialization_type = serialization_type
1543
+ super().__init__(**kwargs)
1544
+
1545
+ def _serialize(self, value, attr, obj, **kwargs):
1546
+ if value is None:
1547
+ return None
1548
+
1549
+ base_unit = dt.timedelta(**{self.precision: 1})
1550
+
1551
+ if self.serialization_type is int:
1552
+ delta = utils.timedelta_to_microseconds(value)
1553
+ unit = utils.timedelta_to_microseconds(base_unit)
1554
+ return delta // unit
1555
+ assert self.serialization_type is float # noqa: S101
1556
+ return value.total_seconds() / base_unit.total_seconds()
1557
+
1558
+ def _deserialize(self, value, attr, data, **kwargs):
1559
+ try:
1560
+ value = self.serialization_type(value)
1561
+ except (TypeError, ValueError) as error:
1562
+ raise self.make_error("invalid") from error
1563
+
1564
+ kwargs = {self.precision: value}
1565
+
1566
+ try:
1567
+ return dt.timedelta(**kwargs)
1568
+ except OverflowError as error:
1569
+ raise self.make_error("invalid") from error
1570
+
1571
+
1572
+ class Mapping(Field):
1573
+ """An abstract class for objects with key-value pairs. This class should not be used within schemas.
1574
+
1575
+ :param keys: A field class or instance for dict keys.
1576
+ :param values: A field class or instance for dict values.
1577
+ :param kwargs: The same keyword arguments that :class:`Field` receives.
1578
+
1579
+ .. note::
1580
+ When the structure of nested data is not known, you may omit the
1581
+ `keys` and `values` arguments to prevent content validation.
1582
+
1583
+ .. versionadded:: 3.0.0rc4
1584
+ .. versionchanged:: 3.24.0
1585
+ `Mapping <marshmallow.fields.Mapping>` should no longer be used as a field within a `Schema <marshmallow.Schema>`.
1586
+ Use `Dict <marshmallow.fields.Dict>` instead.
1587
+ """
1588
+
1589
+ mapping_type = dict
1590
+
1591
+ #: Default error messages.
1592
+ default_error_messages = {"invalid": "Not a valid mapping type."}
1593
+
1594
+ def __init__(
1595
+ self,
1596
+ keys: Field | type[Field] | None = None,
1597
+ values: Field | type[Field] | None = None,
1598
+ **kwargs,
1599
+ ):
1600
+ if self.__class__ is Mapping:
1601
+ warnings.warn(
1602
+ "`Mapping` field should not be instantiated. Use `Dict` instead.",
1603
+ ChangedInMarshmallow4Warning,
1604
+ stacklevel=2,
1605
+ )
1606
+ super().__init__(**kwargs)
1607
+ if keys is None:
1608
+ self.key_field = None
1609
+ else:
1610
+ try:
1611
+ self.key_field = resolve_field_instance(keys)
1612
+ except FieldInstanceResolutionError as error:
1613
+ raise ValueError(
1614
+ '"keys" must be a subclass or instance of '
1615
+ "marshmallow.base.FieldABC."
1616
+ ) from error
1617
+
1618
+ if values is None:
1619
+ self.value_field = None
1620
+ else:
1621
+ try:
1622
+ self.value_field = resolve_field_instance(values)
1623
+ except FieldInstanceResolutionError as error:
1624
+ raise ValueError(
1625
+ '"values" must be a subclass or instance of '
1626
+ "marshmallow.base.FieldABC."
1627
+ ) from error
1628
+ if isinstance(self.value_field, Nested):
1629
+ self.only = self.value_field.only
1630
+ self.exclude = self.value_field.exclude
1631
+
1632
+ def _bind_to_schema(self, field_name, schema):
1633
+ super()._bind_to_schema(field_name, schema)
1634
+ if self.value_field:
1635
+ self.value_field = copy.deepcopy(self.value_field)
1636
+ self.value_field._bind_to_schema(field_name, self)
1637
+ if isinstance(self.value_field, Nested):
1638
+ self.value_field.only = self.only
1639
+ self.value_field.exclude = self.exclude
1640
+ if self.key_field:
1641
+ self.key_field = copy.deepcopy(self.key_field)
1642
+ self.key_field._bind_to_schema(field_name, self)
1643
+
1644
+ def _serialize(self, value, attr, obj, **kwargs):
1645
+ if value is None:
1646
+ return None
1647
+ if not self.value_field and not self.key_field:
1648
+ return self.mapping_type(value)
1649
+
1650
+ # Serialize keys
1651
+ if self.key_field is None:
1652
+ keys = {k: k for k in value}
1653
+ else:
1654
+ keys = {
1655
+ k: self.key_field._serialize(k, None, None, **kwargs) for k in value
1656
+ }
1657
+
1658
+ # Serialize values
1659
+ result = self.mapping_type()
1660
+ if self.value_field is None:
1661
+ for k, v in value.items():
1662
+ if k in keys:
1663
+ result[keys[k]] = v
1664
+ else:
1665
+ for k, v in value.items():
1666
+ result[keys[k]] = self.value_field._serialize(v, None, None, **kwargs)
1667
+
1668
+ return result
1669
+
1670
+ def _deserialize(self, value, attr, data, **kwargs):
1671
+ if not isinstance(value, _Mapping):
1672
+ raise self.make_error("invalid")
1673
+ if not self.value_field and not self.key_field:
1674
+ return self.mapping_type(value)
1675
+
1676
+ errors = collections.defaultdict(dict)
1677
+
1678
+ # Deserialize keys
1679
+ if self.key_field is None:
1680
+ keys = {k: k for k in value}
1681
+ else:
1682
+ keys = {}
1683
+ for key in value:
1684
+ try:
1685
+ keys[key] = self.key_field.deserialize(key, **kwargs)
1686
+ except ValidationError as error:
1687
+ errors[key]["key"] = error.messages
1688
+
1689
+ # Deserialize values
1690
+ result = self.mapping_type()
1691
+ if self.value_field is None:
1692
+ for k, v in value.items():
1693
+ if k in keys:
1694
+ result[keys[k]] = v
1695
+ else:
1696
+ for key, val in value.items():
1697
+ try:
1698
+ deser_val = self.value_field.deserialize(val, **kwargs)
1699
+ except ValidationError as error:
1700
+ errors[key]["value"] = error.messages
1701
+ if error.valid_data is not None and key in keys:
1702
+ result[keys[key]] = error.valid_data
1703
+ else:
1704
+ if key in keys:
1705
+ result[keys[key]] = deser_val
1706
+
1707
+ if errors:
1708
+ raise ValidationError(errors, valid_data=result)
1709
+
1710
+ return result
1711
+
1712
+
1713
+ class Dict(Mapping):
1714
+ """A dict field. Supports dicts and dict-like objects. Extends
1715
+ Mapping with dict as the mapping_type.
1716
+
1717
+ Example: ::
1718
+
1719
+ numbers = fields.Dict(keys=fields.Str(), values=fields.Float())
1720
+
1721
+ :param kwargs: The same keyword arguments that :class:`Mapping` receives.
1722
+
1723
+ .. versionadded:: 2.1.0
1724
+ """
1725
+
1726
+ mapping_type = dict
1727
+
1728
+
1729
+ class Url(String):
1730
+ """An URL field.
1731
+
1732
+ :param default: Default value for the field if the attribute is not set.
1733
+ :param relative: Whether to allow relative URLs.
1734
+ :param absolute: Whether to allow absolute URLs.
1735
+ :param require_tld: Whether to reject non-FQDN hostnames.
1736
+ :param schemes: Valid schemes. By default, ``http``, ``https``,
1737
+ ``ftp``, and ``ftps`` are allowed.
1738
+ :param kwargs: The same keyword arguments that :class:`String` receives.
1739
+ """
1740
+
1741
+ #: Default error messages.
1742
+ default_error_messages = {"invalid": "Not a valid URL."}
1743
+
1744
+ def __init__(
1745
+ self,
1746
+ *,
1747
+ relative: bool = False,
1748
+ absolute: bool = True,
1749
+ schemes: types.StrSequenceOrSet | None = None,
1750
+ require_tld: bool = True,
1751
+ **kwargs,
1752
+ ):
1753
+ super().__init__(**kwargs)
1754
+
1755
+ self.relative = relative
1756
+ self.absolute = absolute
1757
+ self.require_tld = require_tld
1758
+ # Insert validation into self.validators so that multiple errors can be stored.
1759
+ validator = validate.URL(
1760
+ relative=self.relative,
1761
+ absolute=self.absolute,
1762
+ schemes=schemes,
1763
+ require_tld=self.require_tld,
1764
+ error=self.error_messages["invalid"],
1765
+ )
1766
+ self.validators.insert(0, validator)
1767
+
1768
+
1769
+ class Email(String):
1770
+ """An email field.
1771
+
1772
+ :param args: The same positional arguments that :class:`String` receives.
1773
+ :param kwargs: The same keyword arguments that :class:`String` receives.
1774
+ """
1775
+
1776
+ #: Default error messages.
1777
+ default_error_messages = {"invalid": "Not a valid email address."}
1778
+
1779
+ def __init__(self, *args, **kwargs) -> None:
1780
+ super().__init__(*args, **kwargs)
1781
+ # Insert validation into self.validators so that multiple errors can be stored.
1782
+ validator = validate.Email(error=self.error_messages["invalid"])
1783
+ self.validators.insert(0, validator)
1784
+
1785
+
1786
+ class IP(Field):
1787
+ """A IP address field.
1788
+
1789
+ :param exploded: If `True`, serialize ipv6 address in long form, ie. with groups
1790
+ consisting entirely of zeros included.
1791
+
1792
+ .. versionadded:: 3.8.0
1793
+ """
1794
+
1795
+ default_error_messages = {"invalid_ip": "Not a valid IP address."}
1796
+
1797
+ DESERIALIZATION_CLASS: type | None = None
1798
+
1799
+ def __init__(self, *args, exploded=False, **kwargs):
1800
+ super().__init__(*args, **kwargs)
1801
+ self.exploded = exploded
1802
+
1803
+ def _serialize(self, value, attr, obj, **kwargs) -> str | None:
1804
+ if value is None:
1805
+ return None
1806
+ if self.exploded:
1807
+ return value.exploded
1808
+ return value.compressed
1809
+
1810
+ def _deserialize(
1811
+ self, value, attr, data, **kwargs
1812
+ ) -> ipaddress.IPv4Address | ipaddress.IPv6Address | None:
1813
+ if value is None:
1814
+ return None
1815
+ try:
1816
+ return (self.DESERIALIZATION_CLASS or ipaddress.ip_address)(
1817
+ utils.ensure_text_type(value)
1818
+ )
1819
+ except (ValueError, TypeError) as error:
1820
+ raise self.make_error("invalid_ip") from error
1821
+
1822
+
1823
+ class IPv4(IP):
1824
+ """A IPv4 address field.
1825
+
1826
+ .. versionadded:: 3.8.0
1827
+ """
1828
+
1829
+ default_error_messages = {"invalid_ip": "Not a valid IPv4 address."}
1830
+
1831
+ DESERIALIZATION_CLASS = ipaddress.IPv4Address
1832
+
1833
+
1834
+ class IPv6(IP):
1835
+ """A IPv6 address field.
1836
+
1837
+ .. versionadded:: 3.8.0
1838
+ """
1839
+
1840
+ default_error_messages = {"invalid_ip": "Not a valid IPv6 address."}
1841
+
1842
+ DESERIALIZATION_CLASS = ipaddress.IPv6Address
1843
+
1844
+
1845
+ class IPInterface(Field):
1846
+ """A IPInterface field.
1847
+
1848
+ IP interface is the non-strict form of the IPNetwork type where arbitrary host
1849
+ addresses are always accepted.
1850
+
1851
+ IPAddress and mask e.g. '192.168.0.2/24' or '192.168.0.2/255.255.255.0'
1852
+
1853
+ see https://python.readthedocs.io/en/latest/library/ipaddress.html#interface-objects
1854
+
1855
+ :param exploded: If `True`, serialize ipv6 interface in long form, ie. with groups
1856
+ consisting entirely of zeros included.
1857
+ """
1858
+
1859
+ default_error_messages = {"invalid_ip_interface": "Not a valid IP interface."}
1860
+
1861
+ DESERIALIZATION_CLASS: type | None = None
1862
+
1863
+ def __init__(self, *args, exploded: bool = False, **kwargs):
1864
+ super().__init__(*args, **kwargs)
1865
+ self.exploded = exploded
1866
+
1867
+ def _serialize(self, value, attr, obj, **kwargs) -> str | None:
1868
+ if value is None:
1869
+ return None
1870
+ if self.exploded:
1871
+ return value.exploded
1872
+ return value.compressed
1873
+
1874
+ def _deserialize(self, value, attr, data, **kwargs) -> None | (
1875
+ ipaddress.IPv4Interface | ipaddress.IPv6Interface
1876
+ ):
1877
+ if value is None:
1878
+ return None
1879
+ try:
1880
+ return (self.DESERIALIZATION_CLASS or ipaddress.ip_interface)(
1881
+ utils.ensure_text_type(value)
1882
+ )
1883
+ except (ValueError, TypeError) as error:
1884
+ raise self.make_error("invalid_ip_interface") from error
1885
+
1886
+
1887
+ class IPv4Interface(IPInterface):
1888
+ """A IPv4 Network Interface field."""
1889
+
1890
+ default_error_messages = {"invalid_ip_interface": "Not a valid IPv4 interface."}
1891
+
1892
+ DESERIALIZATION_CLASS = ipaddress.IPv4Interface
1893
+
1894
+
1895
+ class IPv6Interface(IPInterface):
1896
+ """A IPv6 Network Interface field."""
1897
+
1898
+ default_error_messages = {"invalid_ip_interface": "Not a valid IPv6 interface."}
1899
+
1900
+ DESERIALIZATION_CLASS = ipaddress.IPv6Interface
1901
+
1902
+
1903
+ class Enum(Field):
1904
+ """An Enum field (de)serializing enum members by symbol (name) or by value.
1905
+
1906
+ :param enum: Enum class
1907
+ :param by_value: Whether to (de)serialize by value or by name,
1908
+ or Field class or instance to use to (de)serialize by value. Defaults to False.
1909
+
1910
+ If `by_value` is `False` (default), enum members are (de)serialized by symbol (name).
1911
+ If it is `True`, they are (de)serialized by value using :class:`Raw`.
1912
+ If it is a field instance or class, they are (de)serialized by value using this field.
1913
+
1914
+ .. versionadded:: 3.18.0
1915
+ """
1916
+
1917
+ default_error_messages = {
1918
+ "unknown": "Must be one of: {choices}.",
1919
+ }
1920
+
1921
+ def __init__(
1922
+ self,
1923
+ enum: type[EnumType],
1924
+ *,
1925
+ by_value: bool | Field | type[Field] = False,
1926
+ **kwargs,
1927
+ ):
1928
+ super().__init__(**kwargs)
1929
+ self.enum = enum
1930
+ self.by_value = by_value
1931
+
1932
+ # Serialization by name
1933
+ if by_value is False:
1934
+ self.field: Field = String()
1935
+ self.choices_text = ", ".join(
1936
+ str(self.field._serialize(m, None, None)) for m in enum.__members__
1937
+ )
1938
+ # Serialization by value
1939
+ else:
1940
+ if by_value is True:
1941
+ self.field = Raw()
1942
+ else:
1943
+ try:
1944
+ self.field = resolve_field_instance(by_value)
1945
+ except FieldInstanceResolutionError as error:
1946
+ raise ValueError(
1947
+ '"by_value" must be either a bool or a subclass or instance of '
1948
+ "marshmallow.base.FieldABC."
1949
+ ) from error
1950
+ self.choices_text = ", ".join(
1951
+ str(self.field._serialize(m.value, None, None)) for m in enum
1952
+ )
1953
+
1954
+ def _serialize(self, value, attr, obj, **kwargs):
1955
+ if value is None:
1956
+ return None
1957
+ if self.by_value:
1958
+ val = value.value
1959
+ else:
1960
+ val = value.name
1961
+ return self.field._serialize(val, attr, obj, **kwargs)
1962
+
1963
+ def _deserialize(self, value, attr, data, **kwargs):
1964
+ val = self.field._deserialize(value, attr, data, **kwargs)
1965
+ if self.by_value:
1966
+ try:
1967
+ return self.enum(val)
1968
+ except ValueError as error:
1969
+ raise self.make_error("unknown", choices=self.choices_text) from error
1970
+ try:
1971
+ return getattr(self.enum, val)
1972
+ except AttributeError as error:
1973
+ raise self.make_error("unknown", choices=self.choices_text) from error
1974
+
1975
+
1976
+ class Method(Field):
1977
+ """A field that takes the value returned by a `Schema <marshmallow.Schema>` method.
1978
+
1979
+ :param serialize: The name of the Schema method from which
1980
+ to retrieve the value. The method must take an argument ``obj``
1981
+ (in addition to self) that is the object to be serialized.
1982
+ :param deserialize: Optional name of the Schema method for deserializing
1983
+ a value The method must take a single argument ``value``, which is the
1984
+ value to deserialize.
1985
+
1986
+ .. versionchanged:: 2.3.0
1987
+ Deprecated ``method_name`` parameter in favor of ``serialize`` and allow
1988
+ ``serialize`` to not be passed at all.
1989
+
1990
+ .. versionchanged:: 3.0.0
1991
+ Removed ``method_name`` parameter.
1992
+ """
1993
+
1994
+ _CHECK_ATTRIBUTE = False
1995
+
1996
+ def __init__(
1997
+ self,
1998
+ serialize: str | None = None,
1999
+ deserialize: str | None = None,
2000
+ **kwargs,
2001
+ ):
2002
+ # Set dump_only and load_only based on arguments
2003
+ kwargs["dump_only"] = bool(serialize) and not bool(deserialize)
2004
+ kwargs["load_only"] = bool(deserialize) and not bool(serialize)
2005
+ super().__init__(**kwargs)
2006
+ self.serialize_method_name = serialize
2007
+ self.deserialize_method_name = deserialize
2008
+ self._serialize_method = None
2009
+ self._deserialize_method = None
2010
+
2011
+ def _bind_to_schema(self, field_name, schema):
2012
+ if self.serialize_method_name:
2013
+ self._serialize_method = utils.callable_or_raise(
2014
+ getattr(schema, self.serialize_method_name)
2015
+ )
2016
+
2017
+ if self.deserialize_method_name:
2018
+ self._deserialize_method = utils.callable_or_raise(
2019
+ getattr(schema, self.deserialize_method_name)
2020
+ )
2021
+
2022
+ super()._bind_to_schema(field_name, schema)
2023
+
2024
+ def _serialize(self, value, attr, obj, **kwargs):
2025
+ if self._serialize_method is not None:
2026
+ return self._serialize_method(obj)
2027
+ return missing_
2028
+
2029
+ def _deserialize(self, value, attr, data, **kwargs):
2030
+ if self._deserialize_method is not None:
2031
+ return self._deserialize_method(value)
2032
+ return value
2033
+
2034
+
2035
+ class Function(Field):
2036
+ """A field that takes the value returned by a function.
2037
+
2038
+ :param serialize: A callable from which to retrieve the value.
2039
+ The function must take a single argument ``obj`` which is the object
2040
+ to be serialized. It can also optionally take a ``context`` argument,
2041
+ which is a dictionary of context variables passed to the serializer.
2042
+ If no callable is provided then the ```load_only``` flag will be set
2043
+ to True.
2044
+ :param deserialize: A callable from which to retrieve the value.
2045
+ The function must take a single argument ``value`` which is the value
2046
+ to be deserialized. It can also optionally take a ``context`` argument,
2047
+ which is a dictionary of context variables passed to the deserializer.
2048
+ If no callable is provided then ```value``` will be passed through
2049
+ unchanged.
2050
+
2051
+ .. versionchanged:: 2.3.0
2052
+ Deprecated ``func`` parameter in favor of ``serialize``.
2053
+
2054
+ .. versionchanged:: 3.0.0a1
2055
+ Removed ``func`` parameter.
2056
+ """
2057
+
2058
+ _CHECK_ATTRIBUTE = False
2059
+
2060
+ def __init__(
2061
+ self,
2062
+ serialize: (
2063
+ typing.Callable[[typing.Any], typing.Any]
2064
+ | typing.Callable[[typing.Any, dict], typing.Any]
2065
+ | None
2066
+ ) = None,
2067
+ deserialize: (
2068
+ typing.Callable[[typing.Any], typing.Any]
2069
+ | typing.Callable[[typing.Any, dict], typing.Any]
2070
+ | None
2071
+ ) = None,
2072
+ **kwargs,
2073
+ ):
2074
+ # Set dump_only and load_only based on arguments
2075
+ kwargs["dump_only"] = bool(serialize) and not bool(deserialize)
2076
+ kwargs["load_only"] = bool(deserialize) and not bool(serialize)
2077
+ super().__init__(**kwargs)
2078
+ self.serialize_func = serialize and utils.callable_or_raise(serialize)
2079
+ self.deserialize_func = deserialize and utils.callable_or_raise(deserialize)
2080
+
2081
+ def _serialize(self, value, attr, obj, **kwargs):
2082
+ return self._call_or_raise(self.serialize_func, obj, attr)
2083
+
2084
+ def _deserialize(self, value, attr, data, **kwargs):
2085
+ if self.deserialize_func:
2086
+ return self._call_or_raise(self.deserialize_func, value, attr)
2087
+ return value
2088
+
2089
+ def _call_or_raise(self, func, value, attr):
2090
+ if len(utils.get_func_args(func)) > 1:
2091
+ if self.parent.context is None:
2092
+ msg = f"No context available for Function field {attr!r}"
2093
+ raise ValidationError(msg)
2094
+ return func(value, self.parent.context)
2095
+ return func(value)
2096
+
2097
+
2098
+ class Constant(Field):
2099
+ """A field that (de)serializes to a preset constant. If you only want the
2100
+ constant added for serialization or deserialization, you should use
2101
+ ``dump_only=True`` or ``load_only=True`` respectively.
2102
+
2103
+ :param constant: The constant to return for the field attribute.
2104
+ """
2105
+
2106
+ _CHECK_ATTRIBUTE = False
2107
+
2108
+ def __init__(self, constant: typing.Any, **kwargs):
2109
+ super().__init__(**kwargs)
2110
+ self.constant = constant
2111
+ self.load_default = constant
2112
+ self.dump_default = constant
2113
+
2114
+ def _serialize(self, value, *args, **kwargs):
2115
+ return self.constant
2116
+
2117
+ def _deserialize(self, value, *args, **kwargs):
2118
+ return self.constant
2119
+
2120
+
2121
+ class Inferred(Field):
2122
+ """A field that infers how to serialize, based on the value type.
2123
+
2124
+ .. warning::
2125
+
2126
+ This class is treated as private API.
2127
+ Users should not need to use this class directly.
2128
+ """
2129
+
2130
+ def __init__(self):
2131
+ super().__init__()
2132
+ # We memoize the fields to avoid creating and binding new fields
2133
+ # every time on serialization.
2134
+ self._field_cache = {}
2135
+
2136
+ def _serialize(self, value, attr, obj, **kwargs):
2137
+ field_cls = self.root.TYPE_MAPPING.get(type(value))
2138
+ if field_cls is None:
2139
+ field = super()
2140
+ else:
2141
+ field = self._field_cache.get(field_cls)
2142
+ if field is None:
2143
+ field = field_cls()
2144
+ field._bind_to_schema(self.name, self.parent)
2145
+ self._field_cache[field_cls] = field
2146
+ return field._serialize(value, attr, obj, **kwargs)
2147
+
2148
+
2149
+ # Aliases
2150
+ URL = Url
2151
+ Str = String
2152
+ Bool = Boolean
2153
+ Int = Integer