@@ -54,8 +54,6 @@ class User:
54
54
Schema: t.ClassVar[Type[Schema]] = Schema # For the type checker
55
55
"""
56
56
57
- __all__ = ("schema_class" , "schema" )
58
-
59
57
import dataclasses
60
58
import datetime
61
59
import decimal
@@ -99,7 +97,7 @@ def class_schema(
99
97
``marshmallow_field`` key in the metadata dictionary.
100
98
"""
101
99
102
- fields : t .Union [t .Tuple [dataclasses .Field ], t .Tuple [attr .Attribute ]]
100
+ fields : t .Union [t .Tuple [dataclasses .Field , ... ], t .Tuple [attr .Attribute , ... ]]
103
101
104
102
if not isinstance (clazz , type ):
105
103
raise desert .exceptions .UnknownType (
@@ -119,9 +117,9 @@ def class_schema(
119
117
raise desert .exceptions .NotAnAttrsClassOrDataclass (clazz )
120
118
121
119
# Copy all public fields of the dataclass to the schema
122
- attributes = {
123
- field . name : field for field in fields if not field . name . startswith ( "_" )
124
- }
120
+ attributes : t . Dict [
121
+ str , t . Union [ dataclasses . Field , attr . Attribute , marshmallow . fields . Field ]
122
+ ] = { field . name : field for field in fields if not field . name . startswith ( "_" ) }
125
123
126
124
# Update the schema members to contain marshmallow fields instead of dataclass fields.
127
125
hints = t .get_type_hints (clazz )
@@ -133,16 +131,23 @@ def class_schema(
133
131
field .metadata ,
134
132
)
135
133
134
+ class_attributes : t .Dict [str , t .Any ] = {
135
+ ** attributes ,
136
+ "Meta" : type ("Meta" , (), meta ),
137
+ }
138
+
136
139
cls_schema = type (
137
140
clazz .__name__ ,
138
141
(_base_schema (clazz ),),
139
- { ** attributes , "Meta" : type ( "Meta" , (), meta )} ,
142
+ class_attributes ,
140
143
)
141
144
142
145
return t .cast (t .Type [marshmallow .Schema ], cls_schema )
143
146
144
147
145
- _native_to_marshmallow : t .Dict [type , t .Type [marshmallow .fields .Field ]] = {
148
+ _native_to_marshmallow : t .Dict [
149
+ t .Union [type , t .Any ], t .Type [marshmallow .fields .Field ]
150
+ ] = {
146
151
int : marshmallow .fields .Integer ,
147
152
float : marshmallow .fields .Float ,
148
153
str : marshmallow .fields .String ,
@@ -171,7 +176,7 @@ def only(items: t.Iterable[T]) -> T:
171
176
172
177
173
178
def field_for_schema (
174
- typ : type , default = marshmallow .missing , metadata : t .Mapping [str , t .Any ] = None
179
+ typ : type , default = marshmallow .missing , metadata : t .Mapping [t . Any , t .Any ] = None
175
180
) -> marshmallow .fields .Field :
176
181
"""
177
182
Get a marshmallow Field corresponding to the given python type.
@@ -319,25 +324,30 @@ def _get_field_default(field: t.Union[dataclasses.Field, attr.Attribute]):
319
324
<marshmallow.missing>
320
325
"""
321
326
if isinstance (field , dataclasses .Field ):
322
- if field .default_factory != dataclasses .MISSING :
327
+ # https://github.com/python/mypy/issues/10750
328
+ if field .default_factory != dataclasses .MISSING : # type: ignore[misc]
323
329
return dataclasses .MISSING
324
330
if field .default is dataclasses .MISSING :
325
331
return marshmallow .missing
326
332
return field .default
327
333
elif isinstance (field , attr .Attribute ):
328
334
if field .default == attr .NOTHING :
329
335
return marshmallow .missing
330
- if isinstance (field .default , attr .Factory ):
331
- if field .default .takes_self :
336
+ if isinstance (field .default , attr .Factory ): # type: ignore[arg-type]
337
+ # attrs specifically doesn't support this so as to support the
338
+ # primary use case.
339
+ # https://github.com/python-attrs/attrs/blob/38580632ceac1cd6e477db71e1d190a4130beed4/src/attr/__init__.pyi#L63-L65
340
+ if field .default .takes_self : # type: ignore[union-attr]
332
341
return attr .NOTHING
333
- return field .default .factory
342
+ return field .default .factory # type: ignore[union-attr]
334
343
return field .default
335
344
else :
336
345
raise TypeError (field )
337
346
338
347
339
- def sentinel (name ):
340
- return attr .make_class (name , [], frozen = True )()
348
+ @attr .frozen
349
+ class _DesertSentinel :
350
+ pass
341
351
342
352
343
- _DESERT_SENTINEL = sentinel ( " _DesertSentinel" )
353
+ _DESERT_SENTINEL = _DesertSentinel ( )
0 commit comments