blob: 7a725dfb5208bbcb5647641187a9a04aea2f7fe7 [file] [log] [blame]
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001import sys
2import types
3from copy import deepcopy
4import collections
5import inspect
6
7__all__ = ['dataclass',
8 'field',
9 'FrozenInstanceError',
10 'InitVar',
11
12 # Helper functions.
13 'fields',
14 'asdict',
15 'astuple',
16 'make_dataclass',
17 'replace',
18 ]
19
20# Raised when an attempt is made to modify a frozen class.
21class FrozenInstanceError(AttributeError): pass
22
23# A sentinel object for default values to signal that a
24# default-factory will be used.
25# This is given a nice repr() which will appear in the function
26# signature of dataclasses' constructors.
27class _HAS_DEFAULT_FACTORY_CLASS:
28 def __repr__(self):
29 return '<factory>'
30_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
31
32# A sentinel object to detect if a parameter is supplied or not.
33class _MISSING_FACTORY:
34 def __repr__(self):
35 return '<missing>'
36_MISSING = _MISSING_FACTORY()
37
38# Since most per-field metadata will be unused, create an empty
39# read-only proxy that can be shared among all fields.
40_EMPTY_METADATA = types.MappingProxyType({})
41
42# Markers for the various kinds of fields and pseudo-fields.
43_FIELD = object() # An actual field.
44_FIELD_CLASSVAR = object() # Not a field, but a ClassVar.
45_FIELD_INITVAR = object() # Not a field, but an InitVar.
46
47# The name of an attribute on the class where we store the Field
48# objects. Also used to check if a class is a Data Class.
49_MARKER = '__dataclass_fields__'
50
51# The name of the function, that if it exists, is called at the end of
52# __init__.
53_POST_INIT_NAME = '__post_init__'
54
55
56class _InitVarMeta(type):
57 def __getitem__(self, params):
58 return self
59
60class InitVar(metaclass=_InitVarMeta):
61 pass
62
63
64# Instances of Field are only ever created from within this module,
65# and only from the field() function, although Field instances are
66# exposed externally as (conceptually) read-only objects.
67# name and type are filled in after the fact, not in __init__. They're
68# not known at the time this class is instantiated, but it's
69# convenient if they're available later.
70# When cls._MARKER is filled in with a list of Field objects, the name
71# and type fields will have been populated.
72class Field:
73 __slots__ = ('name',
74 'type',
75 'default',
76 'default_factory',
77 'repr',
78 'hash',
79 'init',
80 'compare',
81 'metadata',
82 '_field_type', # Private: not to be used by user code.
83 )
84
85 def __init__(self, default, default_factory, init, repr, hash, compare,
86 metadata):
87 self.name = None
88 self.type = None
89 self.default = default
90 self.default_factory = default_factory
91 self.init = init
92 self.repr = repr
93 self.hash = hash
94 self.compare = compare
95 self.metadata = (_EMPTY_METADATA
96 if metadata is None or len(metadata) == 0 else
97 types.MappingProxyType(metadata))
98 self._field_type = None
99
100 def __repr__(self):
101 return ('Field('
102 f'name={self.name!r},'
103 f'type={self.type},'
104 f'default={self.default},'
105 f'default_factory={self.default_factory},'
106 f'init={self.init},'
107 f'repr={self.repr},'
108 f'hash={self.hash},'
109 f'compare={self.compare},'
110 f'metadata={self.metadata}'
111 ')')
112
113
114# This function is used instead of exposing Field creation directly,
115# so that a type checker can be told (via overloads) that this is a
116# function whose type depends on its parameters.
117def field(*, default=_MISSING, default_factory=_MISSING, init=True, repr=True,
118 hash=None, compare=True, metadata=None):
119 """Return an object to identify dataclass fields.
120
121 default is the default value of the field. default_factory is a
122 0-argument function called to initialize a field's value. If init
123 is True, the field will be a parameter to the class's __init__()
124 function. If repr is True, the field will be included in the
125 object's repr(). If hash is True, the field will be included in
126 the object's hash(). If compare is True, the field will be used in
127 comparison functions. metadata, if specified, must be a mapping
128 which is stored but not otherwise examined by dataclass.
129
130 It is an error to specify both default and default_factory.
131 """
132
133 if default is not _MISSING and default_factory is not _MISSING:
134 raise ValueError('cannot specify both default and default_factory')
135 return Field(default, default_factory, init, repr, hash, compare,
136 metadata)
137
138
139def _tuple_str(obj_name, fields):
140 # Return a string representing each field of obj_name as a tuple
141 # member. So, if fields is ['x', 'y'] and obj_name is "self",
142 # return "(self.x,self.y)".
143
144 # Special case for the 0-tuple.
145 if len(fields) == 0:
146 return '()'
147 # Note the trailing comma, needed if this turns out to be a 1-tuple.
148 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
149
150
151def _create_fn(name, args, body, globals=None, locals=None,
152 return_type=_MISSING):
153 # Note that we mutate locals when exec() is called. Caller beware!
154 if locals is None:
155 locals = {}
156 return_annotation = ''
157 if return_type is not _MISSING:
158 locals['_return_type'] = return_type
159 return_annotation = '->_return_type'
160 args = ','.join(args)
161 body = '\n'.join(f' {b}' for b in body)
162
163 txt = f'def {name}({args}){return_annotation}:\n{body}'
164
165 exec(txt, globals, locals)
166 return locals[name]
167
168
169def _field_assign(frozen, name, value, self_name):
170 # If we're a frozen class, then assign to our fields in __init__
171 # via object.__setattr__. Otherwise, just use a simple
172 # assignment.
173 # self_name is what "self" is called in this function: don't
174 # hard-code "self", since that might be a field name.
175 if frozen:
176 return f'object.__setattr__({self_name},{name!r},{value})'
177 return f'{self_name}.{name}={value}'
178
179
180def _field_init(f, frozen, globals, self_name):
181 # Return the text of the line in the body of __init__ that will
182 # initialize this field.
183
184 default_name = f'_dflt_{f.name}'
185 if f.default_factory is not _MISSING:
186 if f.init:
187 # This field has a default factory. If a parameter is
188 # given, use it. If not, call the factory.
189 globals[default_name] = f.default_factory
190 value = (f'{default_name}() '
191 f'if {f.name} is _HAS_DEFAULT_FACTORY '
192 f'else {f.name}')
193 else:
194 # This is a field that's not in the __init__ params, but
195 # has a default factory function. It needs to be
196 # initialized here by calling the factory function,
197 # because there's no other way to initialize it.
198
199 # For a field initialized with a default=defaultvalue, the
200 # class dict just has the default value
201 # (cls.fieldname=defaultvalue). But that won't work for a
202 # default factory, the factory must be called in __init__
203 # and we must assign that to self.fieldname. We can't
204 # fall back to the class dict's value, both because it's
205 # not set, and because it might be different per-class
206 # (which, after all, is why we have a factory function!).
207
208 globals[default_name] = f.default_factory
209 value = f'{default_name}()'
210 else:
211 # No default factory.
212 if f.init:
213 if f.default is _MISSING:
214 # There's no default, just do an assignment.
215 value = f.name
216 elif f.default is not _MISSING:
217 globals[default_name] = f.default
218 value = f.name
219 else:
220 # This field does not need initialization. Signify that to
221 # the caller by returning None.
222 return None
223
224 # Only test this now, so that we can create variables for the
225 # default. However, return None to signify that we're not going
226 # to actually do the assignment statement for InitVars.
227 if f._field_type == _FIELD_INITVAR:
228 return None
229
230 # Now, actually generate the field assignment.
231 return _field_assign(frozen, f.name, value, self_name)
232
233
234def _init_param(f):
235 # Return the __init__ parameter string for this field.
236 # For example, the equivalent of 'x:int=3' (except instead of 'int',
237 # reference a variable set to int, and instead of '3', reference a
238 # variable set to 3).
239 if f.default is _MISSING and f.default_factory is _MISSING:
240 # There's no default, and no default_factory, just
241 # output the variable name and type.
242 default = ''
243 elif f.default is not _MISSING:
244 # There's a default, this will be the name that's used to look it up.
245 default = f'=_dflt_{f.name}'
246 elif f.default_factory is not _MISSING:
247 # There's a factory function. Set a marker.
248 default = '=_HAS_DEFAULT_FACTORY'
249 return f'{f.name}:_type_{f.name}{default}'
250
251
252def _init_fn(fields, frozen, has_post_init, self_name):
253 # fields contains both real fields and InitVar pseudo-fields.
254
255 # Make sure we don't have fields without defaults following fields
256 # with defaults. This actually would be caught when exec-ing the
257 # function source code, but catching it here gives a better error
258 # message, and future-proofs us in case we build up the function
259 # using ast.
260 seen_default = False
261 for f in fields:
262 # Only consider fields in the __init__ call.
263 if f.init:
264 if not (f.default is _MISSING and f.default_factory is _MISSING):
265 seen_default = True
266 elif seen_default:
267 raise TypeError(f'non-default argument {f.name!r} '
268 'follows default argument')
269
270 globals = {'_MISSING': _MISSING,
271 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
272
273 body_lines = []
274 for f in fields:
275 # Do not initialize the pseudo-fields, only the real ones.
276 line = _field_init(f, frozen, globals, self_name)
277 if line is not None:
278 # line is None means that this field doesn't require
279 # initialization. Just skip it.
280 body_lines.append(line)
281
282 # Does this class have a post-init function?
283 if has_post_init:
284 params_str = ','.join(f.name for f in fields
285 if f._field_type is _FIELD_INITVAR)
286 body_lines += [f'{self_name}.{_POST_INIT_NAME}({params_str})']
287
288 # If no body lines, use 'pass'.
289 if len(body_lines) == 0:
290 body_lines = ['pass']
291
292 locals = {f'_type_{f.name}': f.type for f in fields}
293 return _create_fn('__init__',
294 [self_name] +[_init_param(f) for f in fields if f.init],
295 body_lines,
296 locals=locals,
297 globals=globals,
298 return_type=None)
299
300
301def _repr_fn(fields):
302 return _create_fn('__repr__',
303 ['self'],
304 ['return self.__class__.__qualname__ + f"(' +
305 ', '.join([f"{f.name}={{self.{f.name}!r}}"
306 for f in fields]) +
307 ')"'])
308
309
310def _frozen_setattr(self, name, value):
311 raise FrozenInstanceError(f'cannot assign to field {name!r}')
312
313
314def _frozen_delattr(self, name):
315 raise FrozenInstanceError(f'cannot delete field {name!r}')
316
317
318def _cmp_fn(name, op, self_tuple, other_tuple):
319 # Create a comparison function. If the fields in the object are
320 # named 'x' and 'y', then self_tuple is the string
321 # '(self.x,self.y)' and other_tuple is the string
322 # '(other.x,other.y)'.
323
324 return _create_fn(name,
325 ['self', 'other'],
326 [ 'if other.__class__ is self.__class__:',
327 f' return {self_tuple}{op}{other_tuple}',
328 'return NotImplemented'])
329
330
331def _set_eq_fns(cls, fields):
332 # Create and set the equality comparison methods on cls.
333 # Pre-compute self_tuple and other_tuple, then re-use them for
334 # each function.
335 self_tuple = _tuple_str('self', fields)
336 other_tuple = _tuple_str('other', fields)
337 for name, op in [('__eq__', '=='),
338 ('__ne__', '!='),
339 ]:
340 _set_attribute(cls, name, _cmp_fn(name, op, self_tuple, other_tuple))
341
342
343def _set_order_fns(cls, fields):
344 # Create and set the ordering methods on cls.
345 # Pre-compute self_tuple and other_tuple, then re-use them for
346 # each function.
347 self_tuple = _tuple_str('self', fields)
348 other_tuple = _tuple_str('other', fields)
349 for name, op in [('__lt__', '<'),
350 ('__le__', '<='),
351 ('__gt__', '>'),
352 ('__ge__', '>='),
353 ]:
354 _set_attribute(cls, name, _cmp_fn(name, op, self_tuple, other_tuple))
355
356
357def _hash_fn(fields):
358 self_tuple = _tuple_str('self', fields)
359 return _create_fn('__hash__',
360 ['self'],
361 [f'return hash({self_tuple})'])
362
363
364def _get_field(cls, a_name, a_type):
365 # Return a Field object, for this field name and type. ClassVars
366 # and InitVars are also returned, but marked as such (see
367 # f._field_type).
368
369 # If the default value isn't derived from field, then it's
370 # only a normal default value. Convert it to a Field().
371 default = getattr(cls, a_name, _MISSING)
372 if isinstance(default, Field):
373 f = default
374 else:
375 f = field(default=default)
376
377 # Assume it's a normal field until proven otherwise.
378 f._field_type = _FIELD
379
380 # Only at this point do we know the name and the type. Set them.
381 f.name = a_name
382 f.type = a_type
383
384 # If typing has not been imported, then it's impossible for
385 # any annotation to be a ClassVar. So, only look for ClassVar
386 # if typing has been imported.
387 typing = sys.modules.get('typing')
388 if typing is not None:
389 # This test uses a typing internal class, but it's the best
390 # way to test if this is a ClassVar.
391 if type(a_type) is typing._ClassVar:
392 # This field is a ClassVar, so it's not a field.
393 f._field_type = _FIELD_CLASSVAR
394
395 if f._field_type is _FIELD:
396 # Check if this is an InitVar.
397 if a_type is InitVar:
398 # InitVars are not fields, either.
399 f._field_type = _FIELD_INITVAR
400
401 # Validations for fields. This is delayed until now, instead of
402 # in the Field() constructor, since only here do we know the field
403 # name, which allows better error reporting.
404
405 # Special restrictions for ClassVar and InitVar.
406 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
407 if f.default_factory is not _MISSING:
408 raise TypeError(f'field {f.name} cannot have a '
409 'default factory')
410 # Should I check for other field settings? default_factory
411 # seems the most serious to check for. Maybe add others. For
412 # example, how about init=False (or really,
413 # init=<not-the-default-init-value>)? It makes no sense for
414 # ClassVar and InitVar to specify init=<anything>.
415
416 # For real fields, disallow mutable defaults for known types.
417 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
418 raise ValueError(f'mutable default {type(f.default)} for field '
419 f'{f.name} is not allowed: use default_factory')
420
421 return f
422
423
424def _find_fields(cls):
425 # Return a list of Field objects, in order, for this class (and no
426 # base classes). Fields are found from __annotations__ (which is
427 # guaranteed to be ordered). Default values are from class
428 # attributes, if a field has a default. If the default value is
429 # a Field(), then it contains additional info beyond (and
430 # possibly including) the actual default value. Pseudo-fields
431 # ClassVars and InitVars are included, despite the fact that
432 # they're not real fields. That's deal with later.
433
434 annotations = getattr(cls, '__annotations__', {})
435
436 return [_get_field(cls, a_name, a_type)
437 for a_name, a_type in annotations.items()]
438
439
440def _set_attribute(cls, name, value):
441 # Raise TypeError if an attribute by this name already exists.
442 if name in cls.__dict__:
443 raise TypeError(f'Cannot overwrite attribute {name} '
444 f'in {cls.__name__}')
445 setattr(cls, name, value)
446
447
448def _process_class(cls, repr, eq, order, hash, init, frozen):
449 # Use an OrderedDict because:
450 # - Order matters!
451 # - Derived class fields overwrite base class fields, but the
452 # order is defined by the base class, which is found first.
453 fields = collections.OrderedDict()
454
455 # Find our base classes in reverse MRO order, and exclude
456 # ourselves. In reversed order so that more derived classes
457 # override earlier field definitions in base classes.
458 for b in cls.__mro__[-1:0:-1]:
459 # Only process classes that have been processed by our
460 # decorator. That is, they have a _MARKER attribute.
461 base_fields = getattr(b, _MARKER, None)
462 if base_fields:
463 for f in base_fields.values():
464 fields[f.name] = f
465
466 # Now find fields in our class. While doing so, validate some
467 # things, and set the default values (as class attributes)
468 # where we can.
469 for f in _find_fields(cls):
470 fields[f.name] = f
471
472 # If the class attribute (which is the default value for
473 # this field) exists and is of type 'Field', replace it
474 # with the real default. This is so that normal class
475 # introspection sees a real default value, not a Field.
476 if isinstance(getattr(cls, f.name, None), Field):
477 if f.default is _MISSING:
478 # If there's no default, delete the class attribute.
479 # This happens if we specify field(repr=False), for
480 # example (that is, we specified a field object, but
481 # no default value). Also if we're using a default
482 # factory. The class attribute should not be set at
483 # all in the post-processed class.
484 delattr(cls, f.name)
485 else:
486 setattr(cls, f.name, f.default)
487
488 # Remember all of the fields on our class (including bases). This
489 # marks this class as being a dataclass.
490 setattr(cls, _MARKER, fields)
491
492 # We also need to check if a parent class is frozen: frozen has to
493 # be inherited down.
494 is_frozen = frozen or cls.__setattr__ is _frozen_setattr
495
496 # If we're generating ordering methods, we must be generating
497 # the eq methods.
498 if order and not eq:
499 raise ValueError('eq must be true if order is true')
500
501 if init:
502 # Does this class have a post-init function?
503 has_post_init = hasattr(cls, _POST_INIT_NAME)
504
505 # Include InitVars and regular fields (so, not ClassVars).
506 _set_attribute(cls, '__init__',
507 _init_fn(list(filter(lambda f: f._field_type
508 in (_FIELD, _FIELD_INITVAR),
509 fields.values())),
510 is_frozen,
511 has_post_init,
512 # The name to use for the "self" param
513 # in __init__. Use "self" if possible.
514 '__dataclass_self__' if 'self' in fields
515 else 'self',
516 ))
517
518 # Get the fields as a list, and include only real fields. This is
519 # used in all of the following methods.
520 field_list = list(filter(lambda f: f._field_type is _FIELD,
521 fields.values()))
522
523 if repr:
524 _set_attribute(cls, '__repr__',
525 _repr_fn(list(filter(lambda f: f.repr, field_list))))
526
527 if is_frozen:
528 _set_attribute(cls, '__setattr__', _frozen_setattr)
529 _set_attribute(cls, '__delattr__', _frozen_delattr)
530
531 generate_hash = False
532 if hash is None:
533 if eq and frozen:
534 # Generate a hash function.
535 generate_hash = True
536 elif eq and not frozen:
537 # Not hashable.
538 _set_attribute(cls, '__hash__', None)
539 elif not eq:
540 # Otherwise, use the base class definition of hash(). That is,
541 # don't set anything on this class.
542 pass
543 else:
544 assert "can't get here"
545 else:
546 generate_hash = hash
547 if generate_hash:
548 _set_attribute(cls, '__hash__',
549 _hash_fn(list(filter(lambda f: f.compare
550 if f.hash is None
551 else f.hash,
552 field_list))))
553
554 if eq:
555 # Create and __eq__ and __ne__ methods.
556 _set_eq_fns(cls, list(filter(lambda f: f.compare, field_list)))
557
558 if order:
559 # Create and __lt__, __le__, __gt__, and __ge__ methods.
560 # Create and set the comparison functions.
561 _set_order_fns(cls, list(filter(lambda f: f.compare, field_list)))
562
563 if not getattr(cls, '__doc__'):
564 # Create a class doc-string.
565 cls.__doc__ = (cls.__name__ +
566 str(inspect.signature(cls)).replace(' -> None', ''))
567
568 return cls
569
570
571# _cls should never be specified by keyword, so start it with an
572# underscore. The presense of _cls is used to detect if this
573# decorator is being called with parameters or not.
574def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
575 hash=None, frozen=False):
576 """Returns the same class as was passed in, with dunder methods
577 added based on the fields defined in the class.
578
579 Examines PEP 526 __annotations__ to determine fields.
580
581 If init is true, an __init__() method is added to the class. If
582 repr is true, a __repr__() method is added. If order is true, rich
583 comparison dunder methods are added. If hash is true, a __hash__()
584 method function is added. If frozen is true, fields may not be
585 assigned to after instance creation.
586 """
587
588 def wrap(cls):
589 return _process_class(cls, repr, eq, order, hash, init, frozen)
590
591 # See if we're being called as @dataclass or @dataclass().
592 if _cls is None:
593 # We're called with parens.
594 return wrap
595
596 # We're called as @dataclass without parens.
597 return wrap(_cls)
598
599
600def fields(class_or_instance):
601 """Return a tuple describing the fields of this dataclass.
602
603 Accepts a dataclass or an instance of one. Tuple elements are of
604 type Field.
605 """
606
607 # Might it be worth caching this, per class?
608 try:
609 fields = getattr(class_or_instance, _MARKER)
610 except AttributeError:
611 raise TypeError('must be called with a dataclass type or instance')
612
613 # Exclude pseudo-fields.
614 return tuple(f for f in fields.values() if f._field_type is _FIELD)
615
616
617def _isdataclass(obj):
618 """Returns True if obj is an instance of a dataclass."""
619 return not isinstance(obj, type) and hasattr(obj, _MARKER)
620
621
622def asdict(obj, *, dict_factory=dict):
623 """Return the fields of a dataclass instance as a new dictionary mapping
624 field names to field values.
625
626 Example usage:
627
628 @dataclass
629 class C:
630 x: int
631 y: int
632
633 c = C(1, 2)
634 assert asdict(c) == {'x': 1, 'y': 2}
635
636 If given, 'dict_factory' will be used instead of built-in dict.
637 The function applies recursively to field values that are
638 dataclass instances. This will also look into built-in containers:
639 tuples, lists, and dicts.
640 """
641 if not _isdataclass(obj):
642 raise TypeError("asdict() should be called on dataclass instances")
643 return _asdict_inner(obj, dict_factory)
644
645def _asdict_inner(obj, dict_factory):
646 if _isdataclass(obj):
647 result = []
648 for f in fields(obj):
649 value = _asdict_inner(getattr(obj, f.name), dict_factory)
650 result.append((f.name, value))
651 return dict_factory(result)
652 elif isinstance(obj, (list, tuple)):
653 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
654 elif isinstance(obj, dict):
655 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
656 for k, v in obj.items())
657 else:
658 return deepcopy(obj)
659
660
661def astuple(obj, *, tuple_factory=tuple):
662 """Return the fields of a dataclass instance as a new tuple of field values.
663
664 Example usage::
665
666 @dataclass
667 class C:
668 x: int
669 y: int
670
671 c = C(1, 2)
672 assert asdtuple(c) == (1, 2)
673
674 If given, 'tuple_factory' will be used instead of built-in tuple.
675 The function applies recursively to field values that are
676 dataclass instances. This will also look into built-in containers:
677 tuples, lists, and dicts.
678 """
679
680 if not _isdataclass(obj):
681 raise TypeError("astuple() should be called on dataclass instances")
682 return _astuple_inner(obj, tuple_factory)
683
684def _astuple_inner(obj, tuple_factory):
685 if _isdataclass(obj):
686 result = []
687 for f in fields(obj):
688 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
689 result.append(value)
690 return tuple_factory(result)
691 elif isinstance(obj, (list, tuple)):
692 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
693 elif isinstance(obj, dict):
694 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
695 for k, v in obj.items())
696 else:
697 return deepcopy(obj)
698
699
700def make_dataclass(cls_name, fields, *, bases=(), namespace=None):
701 """Return a new dynamically created dataclass.
702
703 The dataclass name will be 'cls_name'. 'fields' is an interable
704 of either (name, type) or (name, type, Field) objects. Field
705 objects are created by calling 'field(name, type [, Field])'.
706
707 C = make_class('C', [('a', int', ('b', int, Field(init=False))], bases=Base)
708
709 is equivalent to:
710
711 @dataclass
712 class C(Base):
713 a: int
714 b: int = field(init=False)
715
716 For the bases and namespace paremeters, see the builtin type() function.
717 """
718
719 if namespace is None:
720 namespace = {}
721 else:
722 # Copy namespace since we're going to mutate it.
723 namespace = namespace.copy()
724
725 anns = collections.OrderedDict((name, tp) for name, tp, *_ in fields)
726 namespace['__annotations__'] = anns
727 for item in fields:
728 if len(item) == 3:
729 name, tp, spec = item
730 namespace[name] = spec
731 cls = type(cls_name, bases, namespace)
732 return dataclass(cls)
733
734
735def replace(obj, **changes):
736 """Return a new object replacing specified fields with new values.
737
738 This is especially useful for frozen classes. Example usage:
739
740 @dataclass(frozen=True)
741 class C:
742 x: int
743 y: int
744
745 c = C(1, 2)
746 c1 = replace(c, x=3)
747 assert c1.x == 3 and c1.y == 2
748 """
749
750 # We're going to mutate 'changes', but that's okay because it's a new
751 # dict, even if called with 'replace(obj, **my_changes)'.
752
753 if not _isdataclass(obj):
754 raise TypeError("replace() should be called on dataclass instances")
755
756 # It's an error to have init=False fields in 'changes'.
757 # If a field is not in 'changes', read its value from the provided obj.
758
759 for f in getattr(obj, _MARKER).values():
760 if not f.init:
761 # Error if this field is specified in changes.
762 if f.name in changes:
763 raise ValueError(f'field {f.name} is declared with '
764 'init=False, it cannot be specified with '
765 'replace()')
766 continue
767
768 if f.name not in changes:
769 changes[f.name] = getattr(obj, f.name)
770
771 # Create the new object, which calls __init__() and __post_init__
772 # (if defined), using all of the init fields we've added and/or
773 # left in 'changes'.
774 # If there are values supplied in changes that aren't fields, this
775 # will correctly raise a TypeError.
776 return obj.__class__(**changes)