@@ -220,8 +220,8 @@ def field_for_schema(
220
220
221
221
if default is not marshmallow .missing :
222
222
desert_metadata .setdefault ("dump_default" , default )
223
- desert_metadata .setdefault ("allow_none" , True )
224
223
desert_metadata .setdefault ("load_default" , default )
224
+ desert_metadata .setdefault ("allow_none" , True )
225
225
226
226
field = None
227
227
@@ -235,9 +235,20 @@ def field_for_schema(
235
235
field .metadata .update (metadata )
236
236
return field
237
237
238
+ field_args = {
239
+ k : v
240
+ for k , v in desert_metadata .items ()
241
+ if k
242
+ in [
243
+ "dump_default" ,
244
+ "load_default" ,
245
+ "allow_none" ,
246
+ ]
247
+ }
248
+
238
249
# Base types
239
250
if not field and typ in _native_to_marshmallow :
240
- field = _native_to_marshmallow [typ ](dump_default = default )
251
+ field = _native_to_marshmallow [typ ](** field_args )
241
252
242
253
# Generic types
243
254
origin = typing_inspect .get_origin (typ )
@@ -253,16 +264,18 @@ def field_for_schema(
253
264
collections .abc .Sequence ,
254
265
collections .abc .MutableSequence ,
255
266
):
256
- field = marshmallow .fields .List (field_for_schema (arguments [0 ]))
267
+ field = marshmallow .fields .List (
268
+ field_for_schema (arguments [0 ]), ** field_args
269
+ )
257
270
258
271
if origin in (tuple , t .Tuple ) and Ellipsis not in arguments :
259
272
field = marshmallow .fields .Tuple ( # type: ignore[no-untyped-call]
260
- tuple (field_for_schema (arg ) for arg in arguments )
273
+ tuple (field_for_schema (arg ) for arg in arguments ), ** field_args
261
274
)
262
275
elif origin in (tuple , t .Tuple ) and Ellipsis in arguments :
263
-
264
276
field = VariadicTuple (
265
- field_for_schema (only (arg for arg in arguments if arg != Ellipsis ))
277
+ field_for_schema (only (arg for arg in arguments if arg != Ellipsis )),
278
+ ** field_args ,
266
279
)
267
280
elif origin in (
268
281
dict ,
@@ -275,47 +288,40 @@ def field_for_schema(
275
288
field = marshmallow .fields .Dict (
276
289
keys = field_for_schema (arguments [0 ]),
277
290
values = field_for_schema (arguments [1 ]),
291
+ ** field_args ,
278
292
)
279
293
elif typing_inspect .is_optional_type (typ ):
280
294
[subtyp ] = (t for t in arguments if t is not NoneType )
281
295
# Treat optional types as types with a None default
282
- metadata [_DESERT_SENTINEL ]["dump_default" ] = metadata .get (
283
- "dump_default" , None
284
- )
285
- metadata [_DESERT_SENTINEL ]["load_default" ] = metadata .get (
286
- "load_default" , None
287
- )
288
- metadata [_DESERT_SENTINEL ]["required" ] = False
289
-
290
- field = field_for_schema (subtyp , metadata = metadata , default = None )
291
- field .dump_default = None
292
- field .load_default = None
293
- field .allow_none = True
296
+ metadata [_DESERT_SENTINEL ]["allow_none" ] = True
297
+ if default is marshmallow .missing :
298
+ default = None
299
+ field = field_for_schema (subtyp , metadata = metadata , default = default )
294
300
295
301
elif typing_inspect .is_union_type (typ ):
296
302
subfields = [field_for_schema (subtyp ) for subtyp in arguments ]
297
303
import marshmallow_union
298
304
299
- field = marshmallow_union .Union (subfields )
305
+ field = marshmallow_union .Union (subfields , ** field_args )
300
306
301
307
# t.NewType returns a function with a __supertype__ attribute
302
308
newtype_supertype = getattr (typ , "__supertype__" , None )
303
309
if newtype_supertype and typing_inspect .is_new_type (typ ):
304
310
metadata .setdefault ("description" , typ .__name__ )
305
- field = field_for_schema (newtype_supertype , default = default )
311
+ field = field_for_schema (newtype_supertype , metadata = metadata , default = default )
306
312
307
313
# enumerations
308
314
if type (typ ) is enum .EnumMeta :
309
315
import marshmallow_enum
310
316
311
- field = marshmallow_enum .EnumField (typ , metadata = metadata )
317
+ field = marshmallow_enum .EnumField (typ , metadata = metadata , ** field_args )
312
318
313
319
# Nested dataclasses
314
320
forward_reference = getattr (typ , "__forward_arg__" , None )
315
321
316
322
if field is None :
317
323
nested = forward_reference or class_schema (typ )
318
- field = marshmallow .fields .Nested (nested )
324
+ field = marshmallow .fields .Nested (nested , ** field_args )
319
325
320
326
field .metadata .update (metadata )
321
327
@@ -350,11 +356,11 @@ def _get_field_default(
350
356
if isinstance (field , dataclasses .Field ):
351
357
# misc: https://github.com/python/mypy/issues/10750
352
358
# comparison-overlap: https://github.com/python/typeshed/pull/5900
353
- if field .default_factory != dataclasses .MISSING :
354
- return dataclasses . MISSING
355
- if field .default is dataclasses .MISSING :
356
- return marshmallow . missing
357
- return field . default
359
+ if field .default_factory is not dataclasses .MISSING :
360
+ return field . default_factory
361
+ if field .default is not dataclasses .MISSING :
362
+ return field . default
363
+ return marshmallow . missing
358
364
elif isinstance (field , attr .Attribute ):
359
365
if field .default == attr .NOTHING :
360
366
return marshmallow .missing
0 commit comments