blob: db92b10960d5af6019c6f938048043d4f42fc394 [file] [log] [blame]
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001import sys
2import types
3from copy import deepcopy
Eric V. Smithf0db54a2017-12-04 16:58:55 -05004import inspect
5
6__all__ = ['dataclass',
7 'field',
8 'FrozenInstanceError',
9 'InitVar',
Eric V. Smith03220fd2017-12-29 13:59:58 -050010 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050011
12 # Helper functions.
13 'fields',
14 'asdict',
15 'astuple',
16 'make_dataclass',
17 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050018 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050019 ]
20
Eric V. Smithea8fc522018-01-27 19:07:40 -050021# Conditions for adding methods. The boxes indicate what action the
22# dataclass decorator takes. For all of these tables, when I talk
Eric V. Smithdbf9cff2018-02-25 21:30:17 -050023# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
24# referring to the arguments to the @dataclass decorator. When
25# checking if a dunder method already exists, I mean check for an
26# entry in the class's __dict__. I never check to see if an
27# attribute is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050028
29# Key:
30# +=========+=========================================+
31# + Value | Meaning |
32# +=========+=========================================+
33# | <blank> | No action: no method is added. |
34# +---------+-----------------------------------------+
35# | add | Generated method is added. |
36# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050037# | raise | TypeError is raised. |
38# +---------+-----------------------------------------+
39# | None | Attribute is set to None. |
40# +=========+=========================================+
41
42# __init__
43#
44# +--- init= parameter
45# |
46# v | | |
47# | no | yes | <--- class has __init__ in __dict__?
48# +=======+=======+=======+
49# | False | | |
50# +-------+-------+-------+
51# | True | add | | <- the default
52# +=======+=======+=======+
53
54# __repr__
55#
56# +--- repr= parameter
57# |
58# v | | |
59# | no | yes | <--- class has __repr__ in __dict__?
60# +=======+=======+=======+
61# | False | | |
62# +-------+-------+-------+
63# | True | add | | <- the default
64# +=======+=======+=======+
65
66
67# __setattr__
68# __delattr__
69#
70# +--- frozen= parameter
71# |
72# v | | |
73# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
74# +=======+=======+=======+
75# | False | | | <- the default
76# +-------+-------+-------+
77# | True | add | raise |
78# +=======+=======+=======+
79# Raise because not adding these methods would break the "frozen-ness"
80# of the class.
81
82# __eq__
83#
84# +--- eq= parameter
85# |
86# v | | |
87# | no | yes | <--- class has __eq__ in __dict__?
88# +=======+=======+=======+
89# | False | | |
90# +-------+-------+-------+
91# | True | add | | <- the default
92# +=======+=======+=======+
93
94# __lt__
95# __le__
96# __gt__
97# __ge__
98#
99# +--- order= parameter
100# |
101# v | | |
102# | no | yes | <--- class has any comparison method in __dict__?
103# +=======+=======+=======+
104# | False | | | <- the default
105# +-------+-------+-------+
106# | True | add | raise |
107# +=======+=======+=======+
108# Raise because to allow this case would interfere with using
109# functools.total_ordering.
110
111# __hash__
112
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500113# +------------------- unsafe_hash= parameter
114# | +----------- eq= parameter
115# | | +--- frozen= parameter
116# | | |
117# v v v | | |
118# | no | yes | <--- class has explicitly defined __hash__
119# +=======+=======+=======+========+========+
120# | False | False | False | | | No __eq__, use the base class __hash__
121# +-------+-------+-------+--------+--------+
122# | False | False | True | | | No __eq__, use the base class __hash__
123# +-------+-------+-------+--------+--------+
124# | False | True | False | None | | <-- the default, not hashable
125# +-------+-------+-------+--------+--------+
126# | False | True | True | add | | Frozen, so hashable, allows override
127# +-------+-------+-------+--------+--------+
128# | True | False | False | add | raise | Has no __eq__, but hashable
129# +-------+-------+-------+--------+--------+
130# | True | False | True | add | raise | Has no __eq__, but hashable
131# +-------+-------+-------+--------+--------+
132# | True | True | False | add | raise | Not frozen, but hashable
133# +-------+-------+-------+--------+--------+
134# | True | True | True | add | raise | Frozen, so hashable
135# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500136# For boxes that are blank, __hash__ is untouched and therefore
137# inherited from the base class. If the base is object, then
138# id-based hashing is used.
139# Note that a class may have already __hash__=None if it specified an
140# __eq__ method in the class body (not one that was created by
141# @dataclass).
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500142# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500143
144
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500145# Raised when an attempt is made to modify a frozen class.
146class FrozenInstanceError(AttributeError): pass
147
148# A sentinel object for default values to signal that a
149# default-factory will be used.
150# This is given a nice repr() which will appear in the function
151# signature of dataclasses' constructors.
152class _HAS_DEFAULT_FACTORY_CLASS:
153 def __repr__(self):
154 return '<factory>'
155_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
156
Eric V. Smith03220fd2017-12-29 13:59:58 -0500157# A sentinel object to detect if a parameter is supplied or not. Use
158# a class to give it a better repr.
159class _MISSING_TYPE:
160 pass
161MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500162
163# Since most per-field metadata will be unused, create an empty
164# read-only proxy that can be shared among all fields.
165_EMPTY_METADATA = types.MappingProxyType({})
166
167# Markers for the various kinds of fields and pseudo-fields.
168_FIELD = object() # An actual field.
169_FIELD_CLASSVAR = object() # Not a field, but a ClassVar.
170_FIELD_INITVAR = object() # Not a field, but an InitVar.
171
172# The name of an attribute on the class where we store the Field
173# objects. Also used to check if a class is a Data Class.
174_MARKER = '__dataclass_fields__'
175
176# The name of the function, that if it exists, is called at the end of
177# __init__.
178_POST_INIT_NAME = '__post_init__'
179
180
181class _InitVarMeta(type):
182 def __getitem__(self, params):
183 return self
184
185class InitVar(metaclass=_InitVarMeta):
186 pass
187
188
189# Instances of Field are only ever created from within this module,
190# and only from the field() function, although Field instances are
191# exposed externally as (conceptually) read-only objects.
192# name and type are filled in after the fact, not in __init__. They're
193# not known at the time this class is instantiated, but it's
194# convenient if they're available later.
195# When cls._MARKER is filled in with a list of Field objects, the name
196# and type fields will have been populated.
197class Field:
198 __slots__ = ('name',
199 'type',
200 'default',
201 'default_factory',
202 'repr',
203 'hash',
204 'init',
205 'compare',
206 'metadata',
207 '_field_type', # Private: not to be used by user code.
208 )
209
210 def __init__(self, default, default_factory, init, repr, hash, compare,
211 metadata):
212 self.name = None
213 self.type = None
214 self.default = default
215 self.default_factory = default_factory
216 self.init = init
217 self.repr = repr
218 self.hash = hash
219 self.compare = compare
220 self.metadata = (_EMPTY_METADATA
221 if metadata is None or len(metadata) == 0 else
222 types.MappingProxyType(metadata))
223 self._field_type = None
224
225 def __repr__(self):
226 return ('Field('
227 f'name={self.name!r},'
228 f'type={self.type},'
229 f'default={self.default},'
230 f'default_factory={self.default_factory},'
231 f'init={self.init},'
232 f'repr={self.repr},'
233 f'hash={self.hash},'
234 f'compare={self.compare},'
235 f'metadata={self.metadata}'
236 ')')
237
238
239# This function is used instead of exposing Field creation directly,
240# so that a type checker can be told (via overloads) that this is a
241# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500242def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500243 hash=None, compare=True, metadata=None):
244 """Return an object to identify dataclass fields.
245
246 default is the default value of the field. default_factory is a
247 0-argument function called to initialize a field's value. If init
248 is True, the field will be a parameter to the class's __init__()
249 function. If repr is True, the field will be included in the
250 object's repr(). If hash is True, the field will be included in
251 the object's hash(). If compare is True, the field will be used in
252 comparison functions. metadata, if specified, must be a mapping
253 which is stored but not otherwise examined by dataclass.
254
255 It is an error to specify both default and default_factory.
256 """
257
Eric V. Smith03220fd2017-12-29 13:59:58 -0500258 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500259 raise ValueError('cannot specify both default and default_factory')
260 return Field(default, default_factory, init, repr, hash, compare,
261 metadata)
262
263
264def _tuple_str(obj_name, fields):
265 # Return a string representing each field of obj_name as a tuple
266 # member. So, if fields is ['x', 'y'] and obj_name is "self",
267 # return "(self.x,self.y)".
268
269 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500270 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500271 return '()'
272 # Note the trailing comma, needed if this turns out to be a 1-tuple.
273 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
274
275
Eric V. Smithea8fc522018-01-27 19:07:40 -0500276def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500277 return_type=MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500278 # Note that we mutate locals when exec() is called. Caller beware!
279 if locals is None:
280 locals = {}
281 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500282 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500283 locals['_return_type'] = return_type
284 return_annotation = '->_return_type'
285 args = ','.join(args)
286 body = '\n'.join(f' {b}' for b in body)
287
288 txt = f'def {name}({args}){return_annotation}:\n{body}'
289
290 exec(txt, globals, locals)
291 return locals[name]
292
293
294def _field_assign(frozen, name, value, self_name):
295 # If we're a frozen class, then assign to our fields in __init__
296 # via object.__setattr__. Otherwise, just use a simple
297 # assignment.
298 # self_name is what "self" is called in this function: don't
299 # hard-code "self", since that might be a field name.
300 if frozen:
301 return f'object.__setattr__({self_name},{name!r},{value})'
302 return f'{self_name}.{name}={value}'
303
304
305def _field_init(f, frozen, globals, self_name):
306 # Return the text of the line in the body of __init__ that will
307 # initialize this field.
308
309 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500310 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500311 if f.init:
312 # This field has a default factory. If a parameter is
313 # given, use it. If not, call the factory.
314 globals[default_name] = f.default_factory
315 value = (f'{default_name}() '
316 f'if {f.name} is _HAS_DEFAULT_FACTORY '
317 f'else {f.name}')
318 else:
319 # This is a field that's not in the __init__ params, but
320 # has a default factory function. It needs to be
321 # initialized here by calling the factory function,
322 # because there's no other way to initialize it.
323
324 # For a field initialized with a default=defaultvalue, the
325 # class dict just has the default value
326 # (cls.fieldname=defaultvalue). But that won't work for a
327 # default factory, the factory must be called in __init__
328 # and we must assign that to self.fieldname. We can't
329 # fall back to the class dict's value, both because it's
330 # not set, and because it might be different per-class
331 # (which, after all, is why we have a factory function!).
332
333 globals[default_name] = f.default_factory
334 value = f'{default_name}()'
335 else:
336 # No default factory.
337 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500338 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500339 # There's no default, just do an assignment.
340 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500341 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500342 globals[default_name] = f.default
343 value = f.name
344 else:
345 # This field does not need initialization. Signify that to
346 # the caller by returning None.
347 return None
348
349 # Only test this now, so that we can create variables for the
350 # default. However, return None to signify that we're not going
351 # to actually do the assignment statement for InitVars.
352 if f._field_type == _FIELD_INITVAR:
353 return None
354
355 # Now, actually generate the field assignment.
356 return _field_assign(frozen, f.name, value, self_name)
357
358
359def _init_param(f):
360 # Return the __init__ parameter string for this field.
361 # For example, the equivalent of 'x:int=3' (except instead of 'int',
362 # reference a variable set to int, and instead of '3', reference a
363 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500364 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500365 # There's no default, and no default_factory, just
366 # output the variable name and type.
367 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500368 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500369 # There's a default, this will be the name that's used to look it up.
370 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500371 elif f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500372 # There's a factory function. Set a marker.
373 default = '=_HAS_DEFAULT_FACTORY'
374 return f'{f.name}:_type_{f.name}{default}'
375
376
377def _init_fn(fields, frozen, has_post_init, self_name):
378 # fields contains both real fields and InitVar pseudo-fields.
379
380 # Make sure we don't have fields without defaults following fields
381 # with defaults. This actually would be caught when exec-ing the
382 # function source code, but catching it here gives a better error
383 # message, and future-proofs us in case we build up the function
384 # using ast.
385 seen_default = False
386 for f in fields:
387 # Only consider fields in the __init__ call.
388 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500389 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500390 seen_default = True
391 elif seen_default:
392 raise TypeError(f'non-default argument {f.name!r} '
393 'follows default argument')
394
Eric V. Smith03220fd2017-12-29 13:59:58 -0500395 globals = {'MISSING': MISSING,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500396 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
397
398 body_lines = []
399 for f in fields:
400 # Do not initialize the pseudo-fields, only the real ones.
401 line = _field_init(f, frozen, globals, self_name)
402 if line is not None:
403 # line is None means that this field doesn't require
404 # initialization. Just skip it.
405 body_lines.append(line)
406
407 # Does this class have a post-init function?
408 if has_post_init:
409 params_str = ','.join(f.name for f in fields
410 if f._field_type is _FIELD_INITVAR)
411 body_lines += [f'{self_name}.{_POST_INIT_NAME}({params_str})']
412
413 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500414 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500415 body_lines = ['pass']
416
417 locals = {f'_type_{f.name}': f.type for f in fields}
418 return _create_fn('__init__',
419 [self_name] +[_init_param(f) for f in fields if f.init],
420 body_lines,
421 locals=locals,
422 globals=globals,
423 return_type=None)
424
425
426def _repr_fn(fields):
427 return _create_fn('__repr__',
428 ['self'],
429 ['return self.__class__.__qualname__ + f"(' +
430 ', '.join([f"{f.name}={{self.{f.name}!r}}"
431 for f in fields]) +
432 ')"'])
433
434
435def _frozen_setattr(self, name, value):
436 raise FrozenInstanceError(f'cannot assign to field {name!r}')
437
438
439def _frozen_delattr(self, name):
440 raise FrozenInstanceError(f'cannot delete field {name!r}')
441
442
443def _cmp_fn(name, op, self_tuple, other_tuple):
444 # Create a comparison function. If the fields in the object are
445 # named 'x' and 'y', then self_tuple is the string
446 # '(self.x,self.y)' and other_tuple is the string
447 # '(other.x,other.y)'.
448
449 return _create_fn(name,
450 ['self', 'other'],
451 [ 'if other.__class__ is self.__class__:',
452 f' return {self_tuple}{op}{other_tuple}',
453 'return NotImplemented'])
454
455
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500456def _hash_fn(fields):
457 self_tuple = _tuple_str('self', fields)
458 return _create_fn('__hash__',
459 ['self'],
460 [f'return hash({self_tuple})'])
461
462
463def _get_field(cls, a_name, a_type):
464 # Return a Field object, for this field name and type. ClassVars
465 # and InitVars are also returned, but marked as such (see
466 # f._field_type).
467
468 # If the default value isn't derived from field, then it's
469 # only a normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500470 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500471 if isinstance(default, Field):
472 f = default
473 else:
474 f = field(default=default)
475
476 # Assume it's a normal field until proven otherwise.
477 f._field_type = _FIELD
478
479 # Only at this point do we know the name and the type. Set them.
480 f.name = a_name
481 f.type = a_type
482
483 # If typing has not been imported, then it's impossible for
484 # any annotation to be a ClassVar. So, only look for ClassVar
485 # if typing has been imported.
486 typing = sys.modules.get('typing')
487 if typing is not None:
488 # This test uses a typing internal class, but it's the best
489 # way to test if this is a ClassVar.
Ivan Levkivskyid911e402018-01-20 11:23:59 +0000490 if (type(a_type) is typing._GenericAlias and
491 a_type.__origin__ is typing.ClassVar):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500492 # This field is a ClassVar, so it's not a field.
493 f._field_type = _FIELD_CLASSVAR
494
495 if f._field_type is _FIELD:
496 # Check if this is an InitVar.
497 if a_type is InitVar:
498 # InitVars are not fields, either.
499 f._field_type = _FIELD_INITVAR
500
501 # Validations for fields. This is delayed until now, instead of
502 # in the Field() constructor, since only here do we know the field
503 # name, which allows better error reporting.
504
505 # Special restrictions for ClassVar and InitVar.
506 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500507 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500508 raise TypeError(f'field {f.name} cannot have a '
509 'default factory')
510 # Should I check for other field settings? default_factory
511 # seems the most serious to check for. Maybe add others. For
512 # example, how about init=False (or really,
513 # init=<not-the-default-init-value>)? It makes no sense for
514 # ClassVar and InitVar to specify init=<anything>.
515
516 # For real fields, disallow mutable defaults for known types.
517 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
518 raise ValueError(f'mutable default {type(f.default)} for field '
519 f'{f.name} is not allowed: use default_factory')
520
521 return f
522
523
524def _find_fields(cls):
525 # Return a list of Field objects, in order, for this class (and no
526 # base classes). Fields are found from __annotations__ (which is
527 # guaranteed to be ordered). Default values are from class
528 # attributes, if a field has a default. If the default value is
529 # a Field(), then it contains additional info beyond (and
530 # possibly including) the actual default value. Pseudo-fields
531 # ClassVars and InitVars are included, despite the fact that
Eric V. Smithea8fc522018-01-27 19:07:40 -0500532 # they're not real fields. That's dealt with later.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500533
534 annotations = getattr(cls, '__annotations__', {})
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500535 return [_get_field(cls, a_name, a_type)
536 for a_name, a_type in annotations.items()]
537
538
Eric V. Smithea8fc522018-01-27 19:07:40 -0500539def _set_new_attribute(cls, name, value):
540 # Never overwrites an existing attribute. Returns True if the
541 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500542 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500543 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500544 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500545 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500546
547
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500548# Decide if/how we're going to create a hash function. Key is
549# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
550# take.
551# Actions:
552# '': Do nothing.
553# 'none': Set __hash__ to None.
554# 'add': Always add a generated __hash__function.
555# 'exception': Raise an exception.
556#
557# +-------------------------------------- unsafe_hash?
558# | +------------------------------- eq?
559# | | +------------------------ frozen?
560# | | | +---------------- has-explicit-hash?
561# | | | |
562# | | | | +------- action
563# | | | | |
564# v v v v v
565_hash_action = {(False, False, False, False): (''),
566 (False, False, False, True ): (''),
567 (False, False, True, False): (''),
568 (False, False, True, True ): (''),
569 (False, True, False, False): ('none'),
570 (False, True, False, True ): (''),
571 (False, True, True, False): ('add'),
572 (False, True, True, True ): (''),
573 (True, False, False, False): ('add'),
574 (True, False, False, True ): ('exception'),
575 (True, False, True, False): ('add'),
576 (True, False, True, True ): ('exception'),
577 (True, True, False, False): ('add'),
578 (True, True, False, True ): ('exception'),
579 (True, True, True, False): ('add'),
580 (True, True, True, True ): ('exception'),
581 }
582# See https://bugs.python.org/issue32929#msg312829 for an if-statement
583# version of this table.
584
585
586def _process_class(cls, repr, eq, order, unsafe_hash, init, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500587 # Now that dicts retain insertion order, there's no reason to use
588 # an ordered dict. I am leveraging that ordering here, because
589 # derived class fields overwrite base class fields, but the order
590 # is defined by the base class, which is found first.
591 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500592
593 # Find our base classes in reverse MRO order, and exclude
594 # ourselves. In reversed order so that more derived classes
595 # override earlier field definitions in base classes.
596 for b in cls.__mro__[-1:0:-1]:
597 # Only process classes that have been processed by our
598 # decorator. That is, they have a _MARKER attribute.
599 base_fields = getattr(b, _MARKER, None)
600 if base_fields:
601 for f in base_fields.values():
602 fields[f.name] = f
603
604 # Now find fields in our class. While doing so, validate some
605 # things, and set the default values (as class attributes)
606 # where we can.
607 for f in _find_fields(cls):
608 fields[f.name] = f
609
610 # If the class attribute (which is the default value for
611 # this field) exists and is of type 'Field', replace it
612 # with the real default. This is so that normal class
613 # introspection sees a real default value, not a Field.
614 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500615 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500616 # If there's no default, delete the class attribute.
617 # This happens if we specify field(repr=False), for
618 # example (that is, we specified a field object, but
619 # no default value). Also if we're using a default
620 # factory. The class attribute should not be set at
621 # all in the post-processed class.
622 delattr(cls, f.name)
623 else:
624 setattr(cls, f.name, f.default)
625
626 # Remember all of the fields on our class (including bases). This
627 # marks this class as being a dataclass.
628 setattr(cls, _MARKER, fields)
629
630 # We also need to check if a parent class is frozen: frozen has to
631 # be inherited down.
632 is_frozen = frozen or cls.__setattr__ is _frozen_setattr
633
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500634 # Was this class defined with an explicit __hash__? Note that if
635 # __eq__ is defined in this class, then python will automatically
636 # set __hash__ to None. This is a heuristic, as it's possible
637 # that such a __hash__ == None was not auto-generated, but it
638 # close enough.
639 class_hash = cls.__dict__.get('__hash__', MISSING)
640 has_explicit_hash = not (class_hash is MISSING or
641 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500642
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500643 # If we're generating ordering methods, we must be generating
644 # the eq methods.
645 if order and not eq:
646 raise ValueError('eq must be true if order is true')
647
648 if init:
649 # Does this class have a post-init function?
650 has_post_init = hasattr(cls, _POST_INIT_NAME)
651
652 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500653 flds = [f for f in fields.values()
654 if f._field_type in (_FIELD, _FIELD_INITVAR)]
655 _set_new_attribute(cls, '__init__',
656 _init_fn(flds,
657 is_frozen,
658 has_post_init,
659 # The name to use for the "self" param
660 # in __init__. Use "self" if possible.
661 '__dataclass_self__' if 'self' in fields
662 else 'self',
663 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500664
665 # Get the fields as a list, and include only real fields. This is
666 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500667 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500668
669 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500670 flds = [f for f in field_list if f.repr]
671 _set_new_attribute(cls, '__repr__', _repr_fn(flds))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500672
673 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500674 # Create _eq__ method. There's no need for a __ne__ method,
675 # since python will call __eq__ and negate it.
676 flds = [f for f in field_list if f.compare]
677 self_tuple = _tuple_str('self', flds)
678 other_tuple = _tuple_str('other', flds)
679 _set_new_attribute(cls, '__eq__',
680 _cmp_fn('__eq__', '==',
681 self_tuple, other_tuple))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500682
683 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500684 # Create and set the ordering methods.
685 flds = [f for f in field_list if f.compare]
686 self_tuple = _tuple_str('self', flds)
687 other_tuple = _tuple_str('other', flds)
688 for name, op in [('__lt__', '<'),
689 ('__le__', '<='),
690 ('__gt__', '>'),
691 ('__ge__', '>='),
692 ]:
693 if _set_new_attribute(cls, name,
694 _cmp_fn(name, op, self_tuple, other_tuple)):
695 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500696 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500697 'functools.total_ordering')
698
699 if is_frozen:
700 for name, fn in [('__setattr__', _frozen_setattr),
701 ('__delattr__', _frozen_delattr)]:
702 if _set_new_attribute(cls, name, fn):
703 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500704 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500705
706 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500707 hash_action = _hash_action[bool(unsafe_hash),
708 bool(eq),
709 bool(frozen),
710 has_explicit_hash]
711
Eric V. Smithea8fc522018-01-27 19:07:40 -0500712 # No need to call _set_new_attribute here, since we already know if
713 # we're overwriting a __hash__ or not.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500714 if hash_action == '':
Eric V. Smithea8fc522018-01-27 19:07:40 -0500715 # Do nothing.
716 pass
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500717 elif hash_action == 'none':
Eric V. Smithea8fc522018-01-27 19:07:40 -0500718 cls.__hash__ = None
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500719 elif hash_action == 'add':
720 flds = [f for f in field_list if (f.compare if f.hash is None else f.hash)]
721 cls.__hash__ = _hash_fn(flds)
722 elif hash_action == 'exception':
723 # Raise an exception.
724 raise TypeError(f'Cannot overwrite attribute __hash__ '
725 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500726 else:
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500727 assert False, f"can't get here: {hash_action}"
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500728
729 if not getattr(cls, '__doc__'):
730 # Create a class doc-string.
731 cls.__doc__ = (cls.__name__ +
732 str(inspect.signature(cls)).replace(' -> None', ''))
733
734 return cls
735
736
737# _cls should never be specified by keyword, so start it with an
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800738# underscore. The presence of _cls is used to detect if this
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500739# decorator is being called with parameters or not.
740def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500741 unsafe_hash=None, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500742 """Returns the same class as was passed in, with dunder methods
743 added based on the fields defined in the class.
744
745 Examines PEP 526 __annotations__ to determine fields.
746
747 If init is true, an __init__() method is added to the class. If
748 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500749 comparison dunder methods are added. If unsafe_hash is true, a
750 __hash__() method function is added. If frozen is true, fields may
751 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500752 """
753
754 def wrap(cls):
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500755 return _process_class(cls, repr, eq, order, unsafe_hash, init, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500756
757 # See if we're being called as @dataclass or @dataclass().
758 if _cls is None:
759 # We're called with parens.
760 return wrap
761
762 # We're called as @dataclass without parens.
763 return wrap(_cls)
764
765
766def fields(class_or_instance):
767 """Return a tuple describing the fields of this dataclass.
768
769 Accepts a dataclass or an instance of one. Tuple elements are of
770 type Field.
771 """
772
773 # Might it be worth caching this, per class?
774 try:
775 fields = getattr(class_or_instance, _MARKER)
776 except AttributeError:
777 raise TypeError('must be called with a dataclass type or instance')
778
Eric V. Smithd1388922018-01-07 14:30:17 -0500779 # Exclude pseudo-fields. Note that fields is sorted by insertion
780 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500781 return tuple(f for f in fields.values() if f._field_type is _FIELD)
782
783
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500784def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500785 """Returns True if obj is an instance of a dataclass."""
786 return not isinstance(obj, type) and hasattr(obj, _MARKER)
787
788
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500789def is_dataclass(obj):
790 """Returns True if obj is a dataclass or an instance of a
791 dataclass."""
792 return hasattr(obj, _MARKER)
793
794
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500795def asdict(obj, *, dict_factory=dict):
796 """Return the fields of a dataclass instance as a new dictionary mapping
797 field names to field values.
798
799 Example usage:
800
801 @dataclass
802 class C:
803 x: int
804 y: int
805
806 c = C(1, 2)
807 assert asdict(c) == {'x': 1, 'y': 2}
808
809 If given, 'dict_factory' will be used instead of built-in dict.
810 The function applies recursively to field values that are
811 dataclass instances. This will also look into built-in containers:
812 tuples, lists, and dicts.
813 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500814 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500815 raise TypeError("asdict() should be called on dataclass instances")
816 return _asdict_inner(obj, dict_factory)
817
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500818
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500819def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500820 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500821 result = []
822 for f in fields(obj):
823 value = _asdict_inner(getattr(obj, f.name), dict_factory)
824 result.append((f.name, value))
825 return dict_factory(result)
826 elif isinstance(obj, (list, tuple)):
827 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
828 elif isinstance(obj, dict):
829 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
830 for k, v in obj.items())
831 else:
832 return deepcopy(obj)
833
834
835def astuple(obj, *, tuple_factory=tuple):
836 """Return the fields of a dataclass instance as a new tuple of field values.
837
838 Example usage::
839
840 @dataclass
841 class C:
842 x: int
843 y: int
844
845 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800846 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500847
848 If given, 'tuple_factory' will be used instead of built-in tuple.
849 The function applies recursively to field values that are
850 dataclass instances. This will also look into built-in containers:
851 tuples, lists, and dicts.
852 """
853
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500854 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500855 raise TypeError("astuple() should be called on dataclass instances")
856 return _astuple_inner(obj, tuple_factory)
857
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500858
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500859def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500860 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500861 result = []
862 for f in fields(obj):
863 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
864 result.append(value)
865 return tuple_factory(result)
866 elif isinstance(obj, (list, tuple)):
867 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
868 elif isinstance(obj, dict):
869 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
870 for k, v in obj.items())
871 else:
872 return deepcopy(obj)
873
874
Eric V. Smithd80b4432018-01-06 17:09:58 -0500875def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500876 repr=True, eq=True, order=False, unsafe_hash=None,
877 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500878 """Return a new dynamically created dataclass.
879
Eric V. Smithed7d4292018-01-06 16:14:03 -0500880 The dataclass name will be 'cls_name'. 'fields' is an iterable
881 of either (name), (name, type) or (name, type, Field) objects. If type is
882 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -0500883 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500884
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800885 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500886
887 is equivalent to:
888
889 @dataclass
890 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800891 x: 'typing.Any'
892 y: int
893 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500894
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800895 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -0500896
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500897 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -0500898 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500899 """
900
901 if namespace is None:
902 namespace = {}
903 else:
904 # Copy namespace since we're going to mutate it.
905 namespace = namespace.copy()
906
Eric V. Smithd1388922018-01-07 14:30:17 -0500907 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500908 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -0500909 if isinstance(item, str):
910 name = item
911 tp = 'typing.Any'
912 elif len(item) == 2:
913 name, tp, = item
914 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500915 name, tp, spec = item
916 namespace[name] = spec
Eric V. Smithed7d4292018-01-06 16:14:03 -0500917 anns[name] = tp
918
919 namespace['__annotations__'] = anns
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500920 cls = type(cls_name, bases, namespace)
Eric V. Smithd80b4432018-01-06 17:09:58 -0500921 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500922 unsafe_hash=unsafe_hash, frozen=frozen)
923
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500924
925def replace(obj, **changes):
926 """Return a new object replacing specified fields with new values.
927
928 This is especially useful for frozen classes. Example usage:
929
930 @dataclass(frozen=True)
931 class C:
932 x: int
933 y: int
934
935 c = C(1, 2)
936 c1 = replace(c, x=3)
937 assert c1.x == 3 and c1.y == 2
938 """
939
940 # We're going to mutate 'changes', but that's okay because it's a new
941 # dict, even if called with 'replace(obj, **my_changes)'.
942
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500943 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500944 raise TypeError("replace() should be called on dataclass instances")
945
946 # It's an error to have init=False fields in 'changes'.
947 # If a field is not in 'changes', read its value from the provided obj.
948
949 for f in getattr(obj, _MARKER).values():
950 if not f.init:
951 # Error if this field is specified in changes.
952 if f.name in changes:
953 raise ValueError(f'field {f.name} is declared with '
954 'init=False, it cannot be specified with '
955 'replace()')
956 continue
957
958 if f.name not in changes:
959 changes[f.name] = getattr(obj, f.name)
960
961 # Create the new object, which calls __init__() and __post_init__
962 # (if defined), using all of the init fields we've added and/or
963 # left in 'changes'.
964 # If there are values supplied in changes that aren't fields, this
965 # will correctly raise a TypeError.
966 return obj.__class__(**changes)