davidtran999 commited on
Commit
c71e75d
·
verified ·
1 Parent(s): 0958857

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

Browse files
backend/venv/lib/python3.10/site-packages/marshmallow/decorators.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Decorators for registering schema pre-processing and post-processing methods.
2
+ These should be imported from the top-level `marshmallow` module.
3
+
4
+ Methods decorated with
5
+ `pre_load <marshmallow.decorators.pre_load>`, `post_load <marshmallow.decorators.post_load>`,
6
+ `pre_dump <marshmallow.decorators.pre_dump>`, `post_dump <marshmallow.decorators.post_dump>`,
7
+ and `validates_schema <marshmallow.decorators.validates_schema>` receive
8
+ ``many`` as a keyword argument. In addition, `pre_load <marshmallow.decorators.pre_load>`,
9
+ `post_load <marshmallow.decorators.post_load>`,
10
+ and `validates_schema <marshmallow.decorators.validates_schema>` receive
11
+ ``partial``. If you don't need these arguments, add ``**kwargs`` to your method
12
+ signature.
13
+
14
+
15
+ Example: ::
16
+
17
+ from marshmallow import (
18
+ Schema,
19
+ pre_load,
20
+ pre_dump,
21
+ post_load,
22
+ validates_schema,
23
+ validates,
24
+ fields,
25
+ ValidationError,
26
+ )
27
+
28
+
29
+ class UserSchema(Schema):
30
+ email = fields.Str(required=True)
31
+ age = fields.Integer(required=True)
32
+
33
+ @post_load
34
+ def lowerstrip_email(self, item, many, **kwargs):
35
+ item["email"] = item["email"].lower().strip()
36
+ return item
37
+
38
+ @pre_load(pass_many=True)
39
+ def remove_envelope(self, data, many, **kwargs):
40
+ namespace = "results" if many else "result"
41
+ return data[namespace]
42
+
43
+ @post_dump(pass_many=True)
44
+ def add_envelope(self, data, many, **kwargs):
45
+ namespace = "results" if many else "result"
46
+ return {namespace: data}
47
+
48
+ @validates_schema
49
+ def validate_email(self, data, **kwargs):
50
+ if len(data["email"]) < 3:
51
+ raise ValidationError("Email must be more than 3 characters", "email")
52
+
53
+ @validates("age")
54
+ def validate_age(self, data, **kwargs):
55
+ if data < 14:
56
+ raise ValidationError("Too young!")
57
+
58
+ .. note::
59
+ These decorators only work with instance methods. Class and static
60
+ methods are not supported.
61
+
62
+ .. warning::
63
+ The invocation order of decorated methods of the same type is not guaranteed.
64
+ If you need to guarantee order of different processing steps, you should put
65
+ them in the same processing method.
66
+ """
67
+
68
+ from __future__ import annotations
69
+
70
+ import functools
71
+ from collections import defaultdict
72
+ from typing import Any, Callable, cast
73
+
74
+ PRE_DUMP = "pre_dump"
75
+ POST_DUMP = "post_dump"
76
+ PRE_LOAD = "pre_load"
77
+ POST_LOAD = "post_load"
78
+ VALIDATES = "validates"
79
+ VALIDATES_SCHEMA = "validates_schema"
80
+
81
+
82
+ class MarshmallowHook:
83
+ __marshmallow_hook__: dict[str, list[tuple[bool, Any]]] | None = None
84
+
85
+
86
+ def validates(field_name: str) -> Callable[..., Any]:
87
+ """Register a field validator.
88
+
89
+ :param field_name: Name of the field that the method validates.
90
+ """
91
+ return set_hook(None, VALIDATES, field_name=field_name)
92
+
93
+
94
+ def validates_schema(
95
+ fn: Callable[..., Any] | None = None,
96
+ pass_many: bool = False, # noqa: FBT001, FBT002
97
+ pass_original: bool = False, # noqa: FBT001, FBT002
98
+ skip_on_field_errors: bool = True, # noqa: FBT001, FBT002
99
+ ) -> Callable[..., Any]:
100
+ """Register a schema-level validator.
101
+
102
+ By default it receives a single object at a time, transparently handling the ``many``
103
+ argument passed to the `Schema <marshmallow.Schema>`'s :func:`~marshmallow.Schema.validate` call.
104
+ If ``pass_many=True``, the raw data (which may be a collection) is passed.
105
+
106
+ If ``pass_original=True``, the original data (before unmarshalling) will be passed as
107
+ an additional argument to the method.
108
+
109
+ If ``skip_on_field_errors=True``, this validation method will be skipped whenever
110
+ validation errors have been detected when validating fields.
111
+
112
+ .. versionchanged:: 3.0.0b1
113
+ ``skip_on_field_errors`` defaults to `True`.
114
+
115
+ .. versionchanged:: 3.0.0
116
+ ``partial`` and ``many`` are always passed as keyword arguments to
117
+ the decorated method.
118
+ """
119
+ return set_hook(
120
+ fn,
121
+ VALIDATES_SCHEMA,
122
+ many=pass_many,
123
+ pass_original=pass_original,
124
+ skip_on_field_errors=skip_on_field_errors,
125
+ )
126
+
127
+
128
+ def pre_dump(
129
+ fn: Callable[..., Any] | None = None,
130
+ pass_many: bool = False, # noqa: FBT001, FBT002
131
+ ) -> Callable[..., Any]:
132
+ """Register a method to invoke before serializing an object. The method
133
+ receives the object to be serialized and returns the processed object.
134
+
135
+ By default it receives a single object at a time, transparently handling the ``many``
136
+ argument passed to the `Schema <marshmallow.Schema>`'s :func:`~marshmallow.Schema.dump` call.
137
+ If ``pass_many=True``, the raw data (which may be a collection) is passed.
138
+
139
+ .. versionchanged:: 3.0.0
140
+ ``many`` is always passed as a keyword arguments to the decorated method.
141
+ """
142
+ return set_hook(fn, PRE_DUMP, many=pass_many)
143
+
144
+
145
+ def post_dump(
146
+ fn: Callable[..., Any] | None = None,
147
+ pass_many: bool = False, # noqa: FBT001, FBT002
148
+ pass_original: bool = False, # noqa: FBT001, FBT002
149
+ ) -> Callable[..., Any]:
150
+ """Register a method to invoke after serializing an object. The method
151
+ receives the serialized object and returns the processed object.
152
+
153
+ By default it receives a single object at a time, transparently handling the ``many``
154
+ argument passed to the `Schema <marshmallow.Schema>`'s :func:`~marshmallow.Schema.dump` call.
155
+ If ``pass_many=True``, the raw data (which may be a collection) is passed.
156
+
157
+ If ``pass_original=True``, the original data (before serializing) will be passed as
158
+ an additional argument to the method.
159
+
160
+ .. versionchanged:: 3.0.0
161
+ ``many`` is always passed as a keyword arguments to the decorated method.
162
+ """
163
+ return set_hook(fn, POST_DUMP, many=pass_many, pass_original=pass_original)
164
+
165
+
166
+ def pre_load(
167
+ fn: Callable[..., Any] | None = None,
168
+ pass_many: bool = False, # noqa: FBT001, FBT002
169
+ ) -> Callable[..., Any]:
170
+ """Register a method to invoke before deserializing an object. The method
171
+ receives the data to be deserialized and returns the processed data.
172
+
173
+ By default it receives a single object at a time, transparently handling the ``many``
174
+ argument passed to the `Schema <marshmallow.Schema>`'s :func:`~marshmallow.Schema.load` call.
175
+ If ``pass_many=True``, the raw data (which may be a collection) is passed.
176
+
177
+ .. versionchanged:: 3.0.0
178
+ ``partial`` and ``many`` are always passed as keyword arguments to
179
+ the decorated method.
180
+ """
181
+ return set_hook(fn, PRE_LOAD, many=pass_many)
182
+
183
+
184
+ def post_load(
185
+ fn: Callable[..., Any] | None = None,
186
+ pass_many: bool = False, # noqa: FBT001, FBT002
187
+ pass_original: bool = False, # noqa: FBT001, FBT002
188
+ ) -> Callable[..., Any]:
189
+ """Register a method to invoke after deserializing an object. The method
190
+ receives the deserialized data and returns the processed data.
191
+
192
+ By default it receives a single object at a time, transparently handling the ``many``
193
+ argument passed to the `Schema <marshmallow.Schema>`'s :func:`~marshmallow.Schema.load` call.
194
+ If ``pass_many=True``, the raw data (which may be a collection) is passed.
195
+
196
+ If ``pass_original=True``, the original data (before deserializing) will be passed as
197
+ an additional argument to the method.
198
+
199
+ .. versionchanged:: 3.0.0
200
+ ``partial`` and ``many`` are always passed as keyword arguments to
201
+ the decorated method.
202
+ """
203
+ return set_hook(fn, POST_LOAD, many=pass_many, pass_original=pass_original)
204
+
205
+
206
+ def set_hook(
207
+ fn: Callable[..., Any] | None,
208
+ tag: str,
209
+ many: bool = False, # noqa: FBT001, FBT002
210
+ **kwargs: Any,
211
+ ) -> Callable[..., Any]:
212
+ """Mark decorated function as a hook to be picked up later.
213
+ You should not need to use this method directly.
214
+
215
+ .. note::
216
+ Currently only works with functions and instance methods. Class and
217
+ static methods are not supported.
218
+
219
+ :return: Decorated function if supplied, else this decorator with its args
220
+ bound.
221
+ """
222
+ # Allow using this as either a decorator or a decorator factory.
223
+ if fn is None:
224
+ return functools.partial(set_hook, tag=tag, many=many, **kwargs)
225
+
226
+ # Set a __marshmallow_hook__ attribute instead of wrapping in some class,
227
+ # because I still want this to end up as a normal (unbound) method.
228
+ function = cast(MarshmallowHook, fn)
229
+ try:
230
+ hook_config = function.__marshmallow_hook__
231
+ except AttributeError:
232
+ function.__marshmallow_hook__ = hook_config = defaultdict(list)
233
+ # Also save the kwargs for the tagged function on
234
+ # __marshmallow_hook__, keyed by <tag>
235
+ if hook_config is not None:
236
+ hook_config[tag].append((many, kwargs))
237
+
238
+ return fn