blob: 8c197fe73904d106fe26c55dd23713359f6a0424 [file] [log] [blame]
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001import sys
Eric V. Smithf96ddad2018-03-24 17:20:26 -04002import copy
Eric V. Smithf0db54a2017-12-04 16:58:55 -05003import types
Eric V. Smithf0db54a2017-12-04 16:58:55 -05004import inspect
5
6__all__ = ['dataclass',
7 'field',
Eric V. Smith8e4560a2018-03-21 17:10:22 -04008 'Field',
Eric V. Smithf0db54a2017-12-04 16:58:55 -05009 'FrozenInstanceError',
10 'InitVar',
Eric V. Smith03220fd2017-12-29 13:59:58 -050011 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050012
13 # Helper functions.
14 'fields',
15 'asdict',
16 'astuple',
17 'make_dataclass',
18 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050019 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050020 ]
21
Eric V. Smithea8fc522018-01-27 19:07:40 -050022# Conditions for adding methods. The boxes indicate what action the
23# dataclass decorator takes. For all of these tables, when I talk
Eric V. Smithdbf9cff2018-02-25 21:30:17 -050024# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
25# referring to the arguments to the @dataclass decorator. When
26# checking if a dunder method already exists, I mean check for an
27# entry in the class's __dict__. I never check to see if an
28# attribute is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050029
30# Key:
31# +=========+=========================================+
32# + Value | Meaning |
33# +=========+=========================================+
34# | <blank> | No action: no method is added. |
35# +---------+-----------------------------------------+
36# | add | Generated method is added. |
37# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050038# | raise | TypeError is raised. |
39# +---------+-----------------------------------------+
40# | None | Attribute is set to None. |
41# +=========+=========================================+
42
43# __init__
44#
45# +--- init= parameter
46# |
47# v | | |
48# | no | yes | <--- class has __init__ in __dict__?
49# +=======+=======+=======+
50# | False | | |
51# +-------+-------+-------+
52# | True | add | | <- the default
53# +=======+=======+=======+
54
55# __repr__
56#
57# +--- repr= parameter
58# |
59# v | | |
60# | no | yes | <--- class has __repr__ in __dict__?
61# +=======+=======+=======+
62# | False | | |
63# +-------+-------+-------+
64# | True | add | | <- the default
65# +=======+=======+=======+
66
67
68# __setattr__
69# __delattr__
70#
71# +--- frozen= parameter
72# |
73# v | | |
74# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
75# +=======+=======+=======+
76# | False | | | <- the default
77# +-------+-------+-------+
78# | True | add | raise |
79# +=======+=======+=======+
80# Raise because not adding these methods would break the "frozen-ness"
81# of the class.
82
83# __eq__
84#
85# +--- eq= parameter
86# |
87# v | | |
88# | no | yes | <--- class has __eq__ in __dict__?
89# +=======+=======+=======+
90# | False | | |
91# +-------+-------+-------+
92# | True | add | | <- the default
93# +=======+=======+=======+
94
95# __lt__
96# __le__
97# __gt__
98# __ge__
99#
100# +--- order= parameter
101# |
102# v | | |
103# | no | yes | <--- class has any comparison method in __dict__?
104# +=======+=======+=======+
105# | False | | | <- the default
106# +-------+-------+-------+
107# | True | add | raise |
108# +=======+=======+=======+
109# Raise because to allow this case would interfere with using
110# functools.total_ordering.
111
112# __hash__
113
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500114# +------------------- unsafe_hash= parameter
115# | +----------- eq= parameter
116# | | +--- frozen= parameter
117# | | |
118# v v v | | |
119# | no | yes | <--- class has explicitly defined __hash__
120# +=======+=======+=======+========+========+
121# | False | False | False | | | No __eq__, use the base class __hash__
122# +-------+-------+-------+--------+--------+
123# | False | False | True | | | No __eq__, use the base class __hash__
124# +-------+-------+-------+--------+--------+
125# | False | True | False | None | | <-- the default, not hashable
126# +-------+-------+-------+--------+--------+
127# | False | True | True | add | | Frozen, so hashable, allows override
128# +-------+-------+-------+--------+--------+
129# | True | False | False | add | raise | Has no __eq__, but hashable
130# +-------+-------+-------+--------+--------+
131# | True | False | True | add | raise | Has no __eq__, but hashable
132# +-------+-------+-------+--------+--------+
133# | True | True | False | add | raise | Not frozen, but hashable
134# +-------+-------+-------+--------+--------+
135# | True | True | True | add | raise | Frozen, so hashable
136# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500137# For boxes that are blank, __hash__ is untouched and therefore
138# inherited from the base class. If the base is object, then
139# id-based hashing is used.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400140# Note that a class may already have __hash__=None if it specified an
Eric V. Smithea8fc522018-01-27 19:07:40 -0500141# __eq__ method in the class body (not one that was created by
142# @dataclass).
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500143# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500144
145
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500146# Raised when an attempt is made to modify a frozen class.
147class FrozenInstanceError(AttributeError): pass
148
149# A sentinel object for default values to signal that a
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400150# default factory will be used.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500151# This is given a nice repr() which will appear in the function
152# signature of dataclasses' constructors.
153class _HAS_DEFAULT_FACTORY_CLASS:
154 def __repr__(self):
155 return '<factory>'
156_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
157
Eric V. Smith03220fd2017-12-29 13:59:58 -0500158# A sentinel object to detect if a parameter is supplied or not. Use
159# a class to give it a better repr.
160class _MISSING_TYPE:
161 pass
162MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500163
164# Since most per-field metadata will be unused, create an empty
165# read-only proxy that can be shared among all fields.
166_EMPTY_METADATA = types.MappingProxyType({})
167
168# Markers for the various kinds of fields and pseudo-fields.
169_FIELD = object() # An actual field.
170_FIELD_CLASSVAR = object() # Not a field, but a ClassVar.
171_FIELD_INITVAR = object() # Not a field, but an InitVar.
172
173# The name of an attribute on the class where we store the Field
174# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400175_FIELDS = '__dataclass_fields__'
176
177# The name of an attribute on the class that stores the parameters to
178# @dataclass.
179_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500180
181# The name of the function, that if it exists, is called at the end of
182# __init__.
183_POST_INIT_NAME = '__post_init__'
184
185
186class _InitVarMeta(type):
187 def __getitem__(self, params):
188 return self
189
190class InitVar(metaclass=_InitVarMeta):
191 pass
192
193
194# Instances of Field are only ever created from within this module,
195# and only from the field() function, although Field instances are
196# exposed externally as (conceptually) read-only objects.
197# name and type are filled in after the fact, not in __init__. They're
198# not known at the time this class is instantiated, but it's
199# convenient if they're available later.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400200# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500201# and type fields will have been populated.
202class Field:
203 __slots__ = ('name',
204 'type',
205 'default',
206 'default_factory',
207 'repr',
208 'hash',
209 'init',
210 'compare',
211 'metadata',
212 '_field_type', # Private: not to be used by user code.
213 )
214
215 def __init__(self, default, default_factory, init, repr, hash, compare,
216 metadata):
217 self.name = None
218 self.type = None
219 self.default = default
220 self.default_factory = default_factory
221 self.init = init
222 self.repr = repr
223 self.hash = hash
224 self.compare = compare
225 self.metadata = (_EMPTY_METADATA
226 if metadata is None or len(metadata) == 0 else
227 types.MappingProxyType(metadata))
228 self._field_type = None
229
230 def __repr__(self):
231 return ('Field('
232 f'name={self.name!r},'
233 f'type={self.type},'
234 f'default={self.default},'
235 f'default_factory={self.default_factory},'
236 f'init={self.init},'
237 f'repr={self.repr},'
238 f'hash={self.hash},'
239 f'compare={self.compare},'
240 f'metadata={self.metadata}'
241 ')')
242
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400243 # This is used to support the PEP 487 __set_name__ protocol in the
244 # case where we're using a field that contains a descriptor as a
245 # defaul value. For details on __set_name__, see
246 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
247 # Note that in _process_class, this Field object is overwritten with
248 # the default value, so the end result is a descriptor that had
249 # __set_name__ called on it at the right time.
250 def __set_name__(self, owner, name):
251 func = getattr(self.default, '__set_name__', None)
252 if func:
253 # There is a __set_name__ method on the descriptor,
254 # call it.
255 func(owner, name)
256
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500257
Eric V. Smithf199bc62018-03-18 20:40:34 -0400258class _DataclassParams:
259 __slots__ = ('init',
260 'repr',
261 'eq',
262 'order',
263 'unsafe_hash',
264 'frozen',
265 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400266
Eric V. Smithf199bc62018-03-18 20:40:34 -0400267 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
268 self.init = init
269 self.repr = repr
270 self.eq = eq
271 self.order = order
272 self.unsafe_hash = unsafe_hash
273 self.frozen = frozen
274
275 def __repr__(self):
276 return ('_DataclassParams('
277 f'init={self.init},'
278 f'repr={self.repr},'
279 f'eq={self.eq},'
280 f'order={self.order},'
281 f'unsafe_hash={self.unsafe_hash},'
282 f'frozen={self.frozen}'
283 ')')
284
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400285
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500286# This function is used instead of exposing Field creation directly,
287# so that a type checker can be told (via overloads) that this is a
288# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500289def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500290 hash=None, compare=True, metadata=None):
291 """Return an object to identify dataclass fields.
292
293 default is the default value of the field. default_factory is a
294 0-argument function called to initialize a field's value. If init
295 is True, the field will be a parameter to the class's __init__()
296 function. If repr is True, the field will be included in the
297 object's repr(). If hash is True, the field will be included in
298 the object's hash(). If compare is True, the field will be used in
299 comparison functions. metadata, if specified, must be a mapping
300 which is stored but not otherwise examined by dataclass.
301
302 It is an error to specify both default and default_factory.
303 """
304
Eric V. Smith03220fd2017-12-29 13:59:58 -0500305 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500306 raise ValueError('cannot specify both default and default_factory')
307 return Field(default, default_factory, init, repr, hash, compare,
308 metadata)
309
310
311def _tuple_str(obj_name, fields):
312 # Return a string representing each field of obj_name as a tuple
313 # member. So, if fields is ['x', 'y'] and obj_name is "self",
314 # return "(self.x,self.y)".
315
316 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500317 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500318 return '()'
319 # Note the trailing comma, needed if this turns out to be a 1-tuple.
320 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
321
322
Eric V. Smithea8fc522018-01-27 19:07:40 -0500323def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500324 return_type=MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500325 # Note that we mutate locals when exec() is called. Caller beware!
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400326 # The only callers are internal to this module, so no worries
327 # about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500328 if locals is None:
329 locals = {}
330 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500331 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500332 locals['_return_type'] = return_type
333 return_annotation = '->_return_type'
334 args = ','.join(args)
335 body = '\n'.join(f' {b}' for b in body)
336
Eric V. Smithf199bc62018-03-18 20:40:34 -0400337 # Compute the text of the entire function.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500338 txt = f'def {name}({args}){return_annotation}:\n{body}'
339
340 exec(txt, globals, locals)
341 return locals[name]
342
343
344def _field_assign(frozen, name, value, self_name):
345 # If we're a frozen class, then assign to our fields in __init__
346 # via object.__setattr__. Otherwise, just use a simple
347 # assignment.
348 # self_name is what "self" is called in this function: don't
349 # hard-code "self", since that might be a field name.
350 if frozen:
351 return f'object.__setattr__({self_name},{name!r},{value})'
352 return f'{self_name}.{name}={value}'
353
354
355def _field_init(f, frozen, globals, self_name):
356 # Return the text of the line in the body of __init__ that will
357 # initialize this field.
358
359 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500360 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500361 if f.init:
362 # This field has a default factory. If a parameter is
363 # given, use it. If not, call the factory.
364 globals[default_name] = f.default_factory
365 value = (f'{default_name}() '
366 f'if {f.name} is _HAS_DEFAULT_FACTORY '
367 f'else {f.name}')
368 else:
369 # This is a field that's not in the __init__ params, but
370 # has a default factory function. It needs to be
371 # initialized here by calling the factory function,
372 # because there's no other way to initialize it.
373
374 # For a field initialized with a default=defaultvalue, the
375 # class dict just has the default value
376 # (cls.fieldname=defaultvalue). But that won't work for a
377 # default factory, the factory must be called in __init__
378 # and we must assign that to self.fieldname. We can't
379 # fall back to the class dict's value, both because it's
380 # not set, and because it might be different per-class
381 # (which, after all, is why we have a factory function!).
382
383 globals[default_name] = f.default_factory
384 value = f'{default_name}()'
385 else:
386 # No default factory.
387 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500388 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500389 # There's no default, just do an assignment.
390 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500391 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500392 globals[default_name] = f.default
393 value = f.name
394 else:
395 # This field does not need initialization. Signify that to
396 # the caller by returning None.
397 return None
398
399 # Only test this now, so that we can create variables for the
400 # default. However, return None to signify that we're not going
401 # to actually do the assignment statement for InitVars.
402 if f._field_type == _FIELD_INITVAR:
403 return None
404
405 # Now, actually generate the field assignment.
406 return _field_assign(frozen, f.name, value, self_name)
407
408
409def _init_param(f):
410 # Return the __init__ parameter string for this field.
411 # For example, the equivalent of 'x:int=3' (except instead of 'int',
412 # reference a variable set to int, and instead of '3', reference a
413 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500414 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500415 # There's no default, and no default_factory, just
416 # output the variable name and type.
417 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500418 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500419 # There's a default, this will be the name that's used to look it up.
420 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500421 elif f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500422 # There's a factory function. Set a marker.
423 default = '=_HAS_DEFAULT_FACTORY'
424 return f'{f.name}:_type_{f.name}{default}'
425
426
427def _init_fn(fields, frozen, has_post_init, self_name):
428 # fields contains both real fields and InitVar pseudo-fields.
429
430 # Make sure we don't have fields without defaults following fields
431 # with defaults. This actually would be caught when exec-ing the
432 # function source code, but catching it here gives a better error
433 # message, and future-proofs us in case we build up the function
434 # using ast.
435 seen_default = False
436 for f in fields:
437 # Only consider fields in the __init__ call.
438 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500439 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500440 seen_default = True
441 elif seen_default:
442 raise TypeError(f'non-default argument {f.name!r} '
443 'follows default argument')
444
Eric V. Smith03220fd2017-12-29 13:59:58 -0500445 globals = {'MISSING': MISSING,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500446 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
447
448 body_lines = []
449 for f in fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500450 line = _field_init(f, frozen, globals, self_name)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400451 # line is None means that this field doesn't require
452 # initialization (it's a pseudo-field). Just skip it.
453 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500454 body_lines.append(line)
455
456 # Does this class have a post-init function?
457 if has_post_init:
458 params_str = ','.join(f.name for f in fields
459 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400460 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500461
462 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500463 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500464 body_lines = ['pass']
465
466 locals = {f'_type_{f.name}': f.type for f in fields}
467 return _create_fn('__init__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400468 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500469 body_lines,
470 locals=locals,
471 globals=globals,
472 return_type=None)
473
474
475def _repr_fn(fields):
476 return _create_fn('__repr__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400477 ('self',),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500478 ['return self.__class__.__qualname__ + f"(' +
479 ', '.join([f"{f.name}={{self.{f.name}!r}}"
480 for f in fields]) +
481 ')"'])
482
483
Eric V. Smithf199bc62018-03-18 20:40:34 -0400484def _frozen_get_del_attr(cls, fields):
485 # XXX: globals is modified on the first call to _create_fn, then the
486 # modified version is used in the second call. Is this okay?
487 globals = {'cls': cls,
488 'FrozenInstanceError': FrozenInstanceError}
489 if fields:
490 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
491 else:
492 # Special case for the zero-length tuple.
493 fields_str = '()'
494 return (_create_fn('__setattr__',
495 ('self', 'name', 'value'),
496 (f'if type(self) is cls or name in {fields_str}:',
497 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
498 f'super(cls, self).__setattr__(name, value)'),
499 globals=globals),
500 _create_fn('__delattr__',
501 ('self', 'name'),
502 (f'if type(self) is cls or name in {fields_str}:',
503 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
504 f'super(cls, self).__delattr__(name)'),
505 globals=globals),
506 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500507
508
509def _cmp_fn(name, op, self_tuple, other_tuple):
510 # Create a comparison function. If the fields in the object are
511 # named 'x' and 'y', then self_tuple is the string
512 # '(self.x,self.y)' and other_tuple is the string
513 # '(other.x,other.y)'.
514
515 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400516 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500517 [ 'if other.__class__ is self.__class__:',
518 f' return {self_tuple}{op}{other_tuple}',
519 'return NotImplemented'])
520
521
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500522def _hash_fn(fields):
523 self_tuple = _tuple_str('self', fields)
524 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400525 ('self',),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500526 [f'return hash({self_tuple})'])
527
528
529def _get_field(cls, a_name, a_type):
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400530 # Return a Field object for this field name and type. ClassVars
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500531 # and InitVars are also returned, but marked as such (see
532 # f._field_type).
533
Eric V. Smith8e4560a2018-03-21 17:10:22 -0400534 # If the default value isn't derived from Field, then it's
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500535 # only a normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500536 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500537 if isinstance(default, Field):
538 f = default
539 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400540 if isinstance(default, types.MemberDescriptorType):
541 # This is a field in __slots__, so it has no default value.
542 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500543 f = field(default=default)
544
545 # Assume it's a normal field until proven otherwise.
546 f._field_type = _FIELD
547
548 # Only at this point do we know the name and the type. Set them.
549 f.name = a_name
550 f.type = a_type
551
552 # If typing has not been imported, then it's impossible for
553 # any annotation to be a ClassVar. So, only look for ClassVar
554 # if typing has been imported.
555 typing = sys.modules.get('typing')
556 if typing is not None:
557 # This test uses a typing internal class, but it's the best
558 # way to test if this is a ClassVar.
Ivan Levkivskyid911e402018-01-20 11:23:59 +0000559 if (type(a_type) is typing._GenericAlias and
560 a_type.__origin__ is typing.ClassVar):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500561 # This field is a ClassVar, so it's not a field.
562 f._field_type = _FIELD_CLASSVAR
563
564 if f._field_type is _FIELD:
565 # Check if this is an InitVar.
566 if a_type is InitVar:
567 # InitVars are not fields, either.
568 f._field_type = _FIELD_INITVAR
569
570 # Validations for fields. This is delayed until now, instead of
571 # in the Field() constructor, since only here do we know the field
572 # name, which allows better error reporting.
573
574 # Special restrictions for ClassVar and InitVar.
575 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500576 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500577 raise TypeError(f'field {f.name} cannot have a '
578 'default factory')
579 # Should I check for other field settings? default_factory
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400580 # seems the most serious to check for. Maybe add others.
581 # For example, how about init=False (or really,
582 # init=<not-the-default-init-value>)? It makes no sense for
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500583 # ClassVar and InitVar to specify init=<anything>.
584
585 # For real fields, disallow mutable defaults for known types.
586 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
587 raise ValueError(f'mutable default {type(f.default)} for field '
588 f'{f.name} is not allowed: use default_factory')
589
590 return f
591
592
Eric V. Smithea8fc522018-01-27 19:07:40 -0500593def _set_new_attribute(cls, name, value):
594 # Never overwrites an existing attribute. Returns True if the
595 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500596 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500597 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500598 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500599 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500600
601
Eric V. Smith01d618c2018-03-24 22:10:14 -0400602
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500603# Decide if/how we're going to create a hash function. Key is
604# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
Eric V. Smith01d618c2018-03-24 22:10:14 -0400605# take. The common case is to do nothing, so instead of providing a
606# function that is a no-op, use None to signify that.
607
608def _hash_set_none(cls, fields):
609 return None
610
611def _hash_add(cls, fields):
612 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
613 return _hash_fn(flds)
614
615def _hash_exception(cls, fields):
616 # Raise an exception.
617 raise TypeError(f'Cannot overwrite attribute __hash__ '
618 f'in class {cls.__name__}')
619
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500620#
621# +-------------------------------------- unsafe_hash?
622# | +------------------------------- eq?
623# | | +------------------------ frozen?
624# | | | +---------------- has-explicit-hash?
625# | | | |
626# | | | | +------- action
627# | | | | |
628# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400629_hash_action = {(False, False, False, False): None,
630 (False, False, False, True ): None,
631 (False, False, True, False): None,
632 (False, False, True, True ): None,
633 (False, True, False, False): _hash_set_none,
634 (False, True, False, True ): None,
635 (False, True, True, False): _hash_add,
636 (False, True, True, True ): None,
637 (True, False, False, False): _hash_add,
638 (True, False, False, True ): _hash_exception,
639 (True, False, True, False): _hash_add,
640 (True, False, True, True ): _hash_exception,
641 (True, True, False, False): _hash_add,
642 (True, True, False, True ): _hash_exception,
643 (True, True, True, False): _hash_add,
644 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500645 }
646# See https://bugs.python.org/issue32929#msg312829 for an if-statement
647# version of this table.
648
649
Eric V. Smithf199bc62018-03-18 20:40:34 -0400650def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500651 # Now that dicts retain insertion order, there's no reason to use
652 # an ordered dict. I am leveraging that ordering here, because
653 # derived class fields overwrite base class fields, but the order
654 # is defined by the base class, which is found first.
655 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500656
Eric V. Smithf199bc62018-03-18 20:40:34 -0400657 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
658 unsafe_hash, frozen))
659
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500660 # Find our base classes in reverse MRO order, and exclude
661 # ourselves. In reversed order so that more derived classes
662 # override earlier field definitions in base classes.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400663 # As long as we're iterating over them, see if any are frozen.
664 any_frozen_base = False
665 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500666 for b in cls.__mro__[-1:0:-1]:
667 # Only process classes that have been processed by our
Eric V. Smithf199bc62018-03-18 20:40:34 -0400668 # decorator. That is, they have a _FIELDS attribute.
669 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500670 if base_fields:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400671 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500672 for f in base_fields.values():
673 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400674 if getattr(b, _PARAMS).frozen:
675 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500676
Eric V. Smith56970b82018-03-22 16:28:48 -0400677 # Annotations that are defined in this class (not in base
678 # classes). If __annotations__ isn't present, then this class
679 # adds no new annotations. We use this to compute fields that
680 # are added by this class.
681 # Fields are found from cls_annotations, which is guaranteed to be
682 # ordered. Default values are from class attributes, if a field
683 # has a default. If the default value is a Field(), then it
684 # contains additional info beyond (and possibly including) the
685 # actual default value. Pseudo-fields ClassVars and InitVars are
686 # included, despite the fact that they're not real fields.
687 # That's dealt with later.
688 cls_annotations = cls.__dict__.get('__annotations__', {})
689
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500690 # Now find fields in our class. While doing so, validate some
691 # things, and set the default values (as class attributes)
692 # where we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400693 cls_fields = [_get_field(cls, name, type)
694 for name, type in cls_annotations.items()]
695 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500696 fields[f.name] = f
697
698 # If the class attribute (which is the default value for
699 # this field) exists and is of type 'Field', replace it
700 # with the real default. This is so that normal class
701 # introspection sees a real default value, not a Field.
702 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500703 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500704 # If there's no default, delete the class attribute.
705 # This happens if we specify field(repr=False), for
706 # example (that is, we specified a field object, but
707 # no default value). Also if we're using a default
708 # factory. The class attribute should not be set at
709 # all in the post-processed class.
710 delattr(cls, f.name)
711 else:
712 setattr(cls, f.name, f.default)
713
Eric V. Smith56970b82018-03-22 16:28:48 -0400714 # Do we have any Field members that don't also have annotations?
715 for name, value in cls.__dict__.items():
716 if isinstance(value, Field) and not name in cls_annotations:
717 raise TypeError(f'{name!r} is a field but has no type annotation')
718
Eric V. Smithf199bc62018-03-18 20:40:34 -0400719 # Check rules that apply if we are derived from any dataclasses.
720 if has_dataclass_bases:
721 # Raise an exception if any of our bases are frozen, but we're not.
722 if any_frozen_base and not frozen:
723 raise TypeError('cannot inherit non-frozen dataclass from a '
724 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500725
Eric V. Smithf199bc62018-03-18 20:40:34 -0400726 # Raise an exception if we're frozen, but none of our bases are.
727 if not any_frozen_base and frozen:
728 raise TypeError('cannot inherit frozen dataclass from a '
729 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500730
Eric V. Smithf199bc62018-03-18 20:40:34 -0400731 # Remember all of the fields on our class (including bases). This also
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500732 # marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400733 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500734
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500735 # Was this class defined with an explicit __hash__? Note that if
736 # __eq__ is defined in this class, then python will automatically
737 # set __hash__ to None. This is a heuristic, as it's possible
738 # that such a __hash__ == None was not auto-generated, but it
739 # close enough.
740 class_hash = cls.__dict__.get('__hash__', MISSING)
741 has_explicit_hash = not (class_hash is MISSING or
742 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500743
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500744 # If we're generating ordering methods, we must be generating
745 # the eq methods.
746 if order and not eq:
747 raise ValueError('eq must be true if order is true')
748
749 if init:
750 # Does this class have a post-init function?
751 has_post_init = hasattr(cls, _POST_INIT_NAME)
752
753 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500754 flds = [f for f in fields.values()
755 if f._field_type in (_FIELD, _FIELD_INITVAR)]
756 _set_new_attribute(cls, '__init__',
757 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500758 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500759 has_post_init,
760 # The name to use for the "self" param
761 # in __init__. Use "self" if possible.
762 '__dataclass_self__' if 'self' in fields
763 else 'self',
764 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500765
766 # Get the fields as a list, and include only real fields. This is
767 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500768 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500769
770 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500771 flds = [f for f in field_list if f.repr]
772 _set_new_attribute(cls, '__repr__', _repr_fn(flds))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500773
774 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500775 # Create _eq__ method. There's no need for a __ne__ method,
776 # since python will call __eq__ and negate it.
777 flds = [f for f in field_list if f.compare]
778 self_tuple = _tuple_str('self', flds)
779 other_tuple = _tuple_str('other', flds)
780 _set_new_attribute(cls, '__eq__',
781 _cmp_fn('__eq__', '==',
782 self_tuple, other_tuple))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500783
784 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500785 # Create and set the ordering methods.
786 flds = [f for f in field_list if f.compare]
787 self_tuple = _tuple_str('self', flds)
788 other_tuple = _tuple_str('other', flds)
789 for name, op in [('__lt__', '<'),
790 ('__le__', '<='),
791 ('__gt__', '>'),
792 ('__ge__', '>='),
793 ]:
794 if _set_new_attribute(cls, name,
795 _cmp_fn(name, op, self_tuple, other_tuple)):
796 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500797 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500798 'functools.total_ordering')
799
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500800 if frozen:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400801 for fn in _frozen_get_del_attr(cls, field_list):
802 if _set_new_attribute(cls, fn.__name__, fn):
803 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500804 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500805
806 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500807 hash_action = _hash_action[bool(unsafe_hash),
808 bool(eq),
809 bool(frozen),
810 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -0400811 if hash_action:
812 # No need to call _set_new_attribute here, since by the time
813 # we're here the overwriting is unconditional.
814 cls.__hash__ = hash_action(cls, field_list)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500815
816 if not getattr(cls, '__doc__'):
817 # Create a class doc-string.
818 cls.__doc__ = (cls.__name__ +
819 str(inspect.signature(cls)).replace(' -> None', ''))
820
821 return cls
822
823
824# _cls should never be specified by keyword, so start it with an
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800825# underscore. The presence of _cls is used to detect if this
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500826# decorator is being called with parameters or not.
827def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -0500828 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500829 """Returns the same class as was passed in, with dunder methods
830 added based on the fields defined in the class.
831
832 Examines PEP 526 __annotations__ to determine fields.
833
834 If init is true, an __init__() method is added to the class. If
835 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500836 comparison dunder methods are added. If unsafe_hash is true, a
837 __hash__() method function is added. If frozen is true, fields may
838 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500839 """
840
841 def wrap(cls):
Eric V. Smithf199bc62018-03-18 20:40:34 -0400842 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500843
844 # See if we're being called as @dataclass or @dataclass().
845 if _cls is None:
846 # We're called with parens.
847 return wrap
848
849 # We're called as @dataclass without parens.
850 return wrap(_cls)
851
852
853def fields(class_or_instance):
854 """Return a tuple describing the fields of this dataclass.
855
856 Accepts a dataclass or an instance of one. Tuple elements are of
857 type Field.
858 """
859
860 # Might it be worth caching this, per class?
861 try:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400862 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500863 except AttributeError:
864 raise TypeError('must be called with a dataclass type or instance')
865
Eric V. Smithd1388922018-01-07 14:30:17 -0500866 # Exclude pseudo-fields. Note that fields is sorted by insertion
867 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500868 return tuple(f for f in fields.values() if f._field_type is _FIELD)
869
870
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500871def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500872 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithf199bc62018-03-18 20:40:34 -0400873 return not isinstance(obj, type) and hasattr(obj, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500874
875
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500876def is_dataclass(obj):
877 """Returns True if obj is a dataclass or an instance of a
878 dataclass."""
Eric V. Smithf199bc62018-03-18 20:40:34 -0400879 return hasattr(obj, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500880
881
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500882def asdict(obj, *, dict_factory=dict):
883 """Return the fields of a dataclass instance as a new dictionary mapping
884 field names to field values.
885
886 Example usage:
887
888 @dataclass
889 class C:
890 x: int
891 y: int
892
893 c = C(1, 2)
894 assert asdict(c) == {'x': 1, 'y': 2}
895
896 If given, 'dict_factory' will be used instead of built-in dict.
897 The function applies recursively to field values that are
898 dataclass instances. This will also look into built-in containers:
899 tuples, lists, and dicts.
900 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500901 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500902 raise TypeError("asdict() should be called on dataclass instances")
903 return _asdict_inner(obj, dict_factory)
904
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500905
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500906def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500907 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500908 result = []
909 for f in fields(obj):
910 value = _asdict_inner(getattr(obj, f.name), dict_factory)
911 result.append((f.name, value))
912 return dict_factory(result)
913 elif isinstance(obj, (list, tuple)):
914 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
915 elif isinstance(obj, dict):
916 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
917 for k, v in obj.items())
918 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400919 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500920
921
922def astuple(obj, *, tuple_factory=tuple):
923 """Return the fields of a dataclass instance as a new tuple of field values.
924
925 Example usage::
926
927 @dataclass
928 class C:
929 x: int
930 y: int
931
932 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800933 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500934
935 If given, 'tuple_factory' will be used instead of built-in tuple.
936 The function applies recursively to field values that are
937 dataclass instances. This will also look into built-in containers:
938 tuples, lists, and dicts.
939 """
940
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500941 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500942 raise TypeError("astuple() should be called on dataclass instances")
943 return _astuple_inner(obj, tuple_factory)
944
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500945
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500946def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500947 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500948 result = []
949 for f in fields(obj):
950 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
951 result.append(value)
952 return tuple_factory(result)
953 elif isinstance(obj, (list, tuple)):
954 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
955 elif isinstance(obj, dict):
956 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
957 for k, v in obj.items())
958 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400959 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500960
961
Eric V. Smithd80b4432018-01-06 17:09:58 -0500962def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -0500963 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500964 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500965 """Return a new dynamically created dataclass.
966
Eric V. Smithed7d4292018-01-06 16:14:03 -0500967 The dataclass name will be 'cls_name'. 'fields' is an iterable
968 of either (name), (name, type) or (name, type, Field) objects. If type is
969 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -0500970 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500971
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800972 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500973
974 is equivalent to:
975
976 @dataclass
977 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800978 x: 'typing.Any'
979 y: int
980 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500981
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800982 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -0500983
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500984 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -0500985 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500986 """
987
988 if namespace is None:
989 namespace = {}
990 else:
991 # Copy namespace since we're going to mutate it.
992 namespace = namespace.copy()
993
Eric V. Smithd1388922018-01-07 14:30:17 -0500994 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500995 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -0500996 if isinstance(item, str):
997 name = item
998 tp = 'typing.Any'
999 elif len(item) == 2:
1000 name, tp, = item
1001 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001002 name, tp, spec = item
1003 namespace[name] = spec
Eric V. Smithed7d4292018-01-06 16:14:03 -05001004 anns[name] = tp
1005
1006 namespace['__annotations__'] = anns
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001007 cls = type(cls_name, bases, namespace)
Eric V. Smithd80b4432018-01-06 17:09:58 -05001008 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001009 unsafe_hash=unsafe_hash, frozen=frozen)
1010
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001011
1012def replace(obj, **changes):
1013 """Return a new object replacing specified fields with new values.
1014
1015 This is especially useful for frozen classes. Example usage:
1016
1017 @dataclass(frozen=True)
1018 class C:
1019 x: int
1020 y: int
1021
1022 c = C(1, 2)
1023 c1 = replace(c, x=3)
1024 assert c1.x == 3 and c1.y == 2
1025 """
1026
1027 # We're going to mutate 'changes', but that's okay because it's a new
1028 # dict, even if called with 'replace(obj, **my_changes)'.
1029
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001030 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001031 raise TypeError("replace() should be called on dataclass instances")
1032
1033 # It's an error to have init=False fields in 'changes'.
1034 # If a field is not in 'changes', read its value from the provided obj.
1035
Eric V. Smithf199bc62018-03-18 20:40:34 -04001036 for f in getattr(obj, _FIELDS).values():
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001037 if not f.init:
1038 # Error if this field is specified in changes.
1039 if f.name in changes:
1040 raise ValueError(f'field {f.name} is declared with '
1041 'init=False, it cannot be specified with '
1042 'replace()')
1043 continue
1044
1045 if f.name not in changes:
1046 changes[f.name] = getattr(obj, f.name)
1047
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001048 # Create the new object, which calls __init__() and
1049 # __post_init__() (if defined), using all of the init fields
1050 # we've added and/or left in 'changes'. If there are values
1051 # supplied in changes that aren't fields, this will correctly
1052 # raise a TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001053 return obj.__class__(**changes)