8
8
'field' ,
9
9
'FrozenInstanceError' ,
10
10
'InitVar' ,
11
+ 'MISSING' ,
11
12
12
13
# Helper functions.
13
14
'fields' ,
@@ -29,11 +30,11 @@ def __repr__(self):
29
30
return '<factory>'
30
31
_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS ()
31
32
32
- # A sentinel object to detect if a parameter is supplied or not.
33
- class _MISSING_FACTORY :
34
- def __repr__ ( self ) :
35
- return '<missing>'
36
- _MISSING = _MISSING_FACTORY ()
33
+ # A sentinel object to detect if a parameter is supplied or not. Use
34
+ # a class to give it a better repr.
35
+ class _MISSING_TYPE :
36
+ pass
37
+ MISSING = _MISSING_TYPE ()
37
38
38
39
# Since most per-field metadata will be unused, create an empty
39
40
# read-only proxy that can be shared among all fields.
@@ -114,7 +115,7 @@ def __repr__(self):
114
115
# This function is used instead of exposing Field creation directly,
115
116
# so that a type checker can be told (via overloads) that this is a
116
117
# function whose type depends on its parameters.
117
- def field (* , default = _MISSING , default_factory = _MISSING , init = True , repr = True ,
118
+ def field (* , default = MISSING , default_factory = MISSING , init = True , repr = True ,
118
119
hash = None , compare = True , metadata = None ):
119
120
"""Return an object to identify dataclass fields.
120
121
@@ -130,7 +131,7 @@ def field(*, default=_MISSING, default_factory=_MISSING, init=True, repr=True,
130
131
It is an error to specify both default and default_factory.
131
132
"""
132
133
133
- if default is not _MISSING and default_factory is not _MISSING :
134
+ if default is not MISSING and default_factory is not MISSING :
134
135
raise ValueError ('cannot specify both default and default_factory' )
135
136
return Field (default , default_factory , init , repr , hash , compare ,
136
137
metadata )
@@ -149,12 +150,12 @@ def _tuple_str(obj_name, fields):
149
150
150
151
151
152
def _create_fn (name , args , body , globals = None , locals = None ,
152
- return_type = _MISSING ):
153
+ return_type = MISSING ):
153
154
# Note that we mutate locals when exec() is called. Caller beware!
154
155
if locals is None :
155
156
locals = {}
156
157
return_annotation = ''
157
- if return_type is not _MISSING :
158
+ if return_type is not MISSING :
158
159
locals ['_return_type' ] = return_type
159
160
return_annotation = '->_return_type'
160
161
args = ',' .join (args )
@@ -182,7 +183,7 @@ def _field_init(f, frozen, globals, self_name):
182
183
# initialize this field.
183
184
184
185
default_name = f'_dflt_{ f .name } '
185
- if f .default_factory is not _MISSING :
186
+ if f .default_factory is not MISSING :
186
187
if f .init :
187
188
# This field has a default factory. If a parameter is
188
189
# given, use it. If not, call the factory.
@@ -210,10 +211,10 @@ def _field_init(f, frozen, globals, self_name):
210
211
else :
211
212
# No default factory.
212
213
if f .init :
213
- if f .default is _MISSING :
214
+ if f .default is MISSING :
214
215
# There's no default, just do an assignment.
215
216
value = f .name
216
- elif f .default is not _MISSING :
217
+ elif f .default is not MISSING :
217
218
globals [default_name ] = f .default
218
219
value = f .name
219
220
else :
@@ -236,14 +237,14 @@ def _init_param(f):
236
237
# For example, the equivalent of 'x:int=3' (except instead of 'int',
237
238
# reference a variable set to int, and instead of '3', reference a
238
239
# variable set to 3).
239
- if f .default is _MISSING and f .default_factory is _MISSING :
240
+ if f .default is MISSING and f .default_factory is MISSING :
240
241
# There's no default, and no default_factory, just
241
242
# output the variable name and type.
242
243
default = ''
243
- elif f .default is not _MISSING :
244
+ elif f .default is not MISSING :
244
245
# There's a default, this will be the name that's used to look it up.
245
246
default = f'=_dflt_{ f .name } '
246
- elif f .default_factory is not _MISSING :
247
+ elif f .default_factory is not MISSING :
247
248
# There's a factory function. Set a marker.
248
249
default = '=_HAS_DEFAULT_FACTORY'
249
250
return f'{ f .name } :_type_{ f .name } { default } '
@@ -261,13 +262,13 @@ def _init_fn(fields, frozen, has_post_init, self_name):
261
262
for f in fields :
262
263
# Only consider fields in the __init__ call.
263
264
if f .init :
264
- if not (f .default is _MISSING and f .default_factory is _MISSING ):
265
+ if not (f .default is MISSING and f .default_factory is MISSING ):
265
266
seen_default = True
266
267
elif seen_default :
267
268
raise TypeError (f'non-default argument { f .name !r} '
268
269
'follows default argument' )
269
270
270
- globals = {'_MISSING ' : _MISSING ,
271
+ globals = {'MISSING ' : MISSING ,
271
272
'_HAS_DEFAULT_FACTORY' : _HAS_DEFAULT_FACTORY }
272
273
273
274
body_lines = []
@@ -368,7 +369,7 @@ def _get_field(cls, a_name, a_type):
368
369
369
370
# If the default value isn't derived from field, then it's
370
371
# only a normal default value. Convert it to a Field().
371
- default = getattr (cls , a_name , _MISSING )
372
+ default = getattr (cls , a_name , MISSING )
372
373
if isinstance (default , Field ):
373
374
f = default
374
375
else :
@@ -404,7 +405,7 @@ def _get_field(cls, a_name, a_type):
404
405
405
406
# Special restrictions for ClassVar and InitVar.
406
407
if f ._field_type in (_FIELD_CLASSVAR , _FIELD_INITVAR ):
407
- if f .default_factory is not _MISSING :
408
+ if f .default_factory is not MISSING :
408
409
raise TypeError (f'field { f .name } cannot have a '
409
410
'default factory' )
410
411
# Should I check for other field settings? default_factory
@@ -474,7 +475,7 @@ def _process_class(cls, repr, eq, order, hash, init, frozen):
474
475
# with the real default. This is so that normal class
475
476
# introspection sees a real default value, not a Field.
476
477
if isinstance (getattr (cls , f .name , None ), Field ):
477
- if f .default is _MISSING :
478
+ if f .default is MISSING :
478
479
# If there's no default, delete the class attribute.
479
480
# This happens if we specify field(repr=False), for
480
481
# example (that is, we specified a field object, but
0 commit comments