blob: 5d4d4a6100ca71e86ac8fc7b08bee280c05d1126 [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',
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.
140# Note that a class may have already __hash__=None if it specified an
141# __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
150# default-factory will be used.
151# 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
243
Eric V. Smithf199bc62018-03-18 20:40:34 -0400244class _DataclassParams:
245 __slots__ = ('init',
246 'repr',
247 'eq',
248 'order',
249 'unsafe_hash',
250 'frozen',
251 )
252 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
253 self.init = init
254 self.repr = repr
255 self.eq = eq
256 self.order = order
257 self.unsafe_hash = unsafe_hash
258 self.frozen = frozen
259
260 def __repr__(self):
261 return ('_DataclassParams('
262 f'init={self.init},'
263 f'repr={self.repr},'
264 f'eq={self.eq},'
265 f'order={self.order},'
266 f'unsafe_hash={self.unsafe_hash},'
267 f'frozen={self.frozen}'
268 ')')
269
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500270# This function is used instead of exposing Field creation directly,
271# so that a type checker can be told (via overloads) that this is a
272# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500273def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500274 hash=None, compare=True, metadata=None):
275 """Return an object to identify dataclass fields.
276
277 default is the default value of the field. default_factory is a
278 0-argument function called to initialize a field's value. If init
279 is True, the field will be a parameter to the class's __init__()
280 function. If repr is True, the field will be included in the
281 object's repr(). If hash is True, the field will be included in
282 the object's hash(). If compare is True, the field will be used in
283 comparison functions. metadata, if specified, must be a mapping
284 which is stored but not otherwise examined by dataclass.
285
286 It is an error to specify both default and default_factory.
287 """
288
Eric V. Smith03220fd2017-12-29 13:59:58 -0500289 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500290 raise ValueError('cannot specify both default and default_factory')
291 return Field(default, default_factory, init, repr, hash, compare,
292 metadata)
293
294
295def _tuple_str(obj_name, fields):
296 # Return a string representing each field of obj_name as a tuple
297 # member. So, if fields is ['x', 'y'] and obj_name is "self",
298 # return "(self.x,self.y)".
299
300 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500301 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500302 return '()'
303 # Note the trailing comma, needed if this turns out to be a 1-tuple.
304 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
305
306
Eric V. Smithea8fc522018-01-27 19:07:40 -0500307def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500308 return_type=MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500309 # Note that we mutate locals when exec() is called. Caller beware!
310 if locals is None:
311 locals = {}
312 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500313 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500314 locals['_return_type'] = return_type
315 return_annotation = '->_return_type'
316 args = ','.join(args)
317 body = '\n'.join(f' {b}' for b in body)
318
Eric V. Smithf199bc62018-03-18 20:40:34 -0400319 # Compute the text of the entire function.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500320 txt = f'def {name}({args}){return_annotation}:\n{body}'
321
322 exec(txt, globals, locals)
323 return locals[name]
324
325
326def _field_assign(frozen, name, value, self_name):
327 # If we're a frozen class, then assign to our fields in __init__
328 # via object.__setattr__. Otherwise, just use a simple
329 # assignment.
330 # self_name is what "self" is called in this function: don't
331 # hard-code "self", since that might be a field name.
332 if frozen:
333 return f'object.__setattr__({self_name},{name!r},{value})'
334 return f'{self_name}.{name}={value}'
335
336
337def _field_init(f, frozen, globals, self_name):
338 # Return the text of the line in the body of __init__ that will
339 # initialize this field.
340
341 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500342 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500343 if f.init:
344 # This field has a default factory. If a parameter is
345 # given, use it. If not, call the factory.
346 globals[default_name] = f.default_factory
347 value = (f'{default_name}() '
348 f'if {f.name} is _HAS_DEFAULT_FACTORY '
349 f'else {f.name}')
350 else:
351 # This is a field that's not in the __init__ params, but
352 # has a default factory function. It needs to be
353 # initialized here by calling the factory function,
354 # because there's no other way to initialize it.
355
356 # For a field initialized with a default=defaultvalue, the
357 # class dict just has the default value
358 # (cls.fieldname=defaultvalue). But that won't work for a
359 # default factory, the factory must be called in __init__
360 # and we must assign that to self.fieldname. We can't
361 # fall back to the class dict's value, both because it's
362 # not set, and because it might be different per-class
363 # (which, after all, is why we have a factory function!).
364
365 globals[default_name] = f.default_factory
366 value = f'{default_name}()'
367 else:
368 # No default factory.
369 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500370 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500371 # There's no default, just do an assignment.
372 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500373 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500374 globals[default_name] = f.default
375 value = f.name
376 else:
377 # This field does not need initialization. Signify that to
378 # the caller by returning None.
379 return None
380
381 # Only test this now, so that we can create variables for the
382 # default. However, return None to signify that we're not going
383 # to actually do the assignment statement for InitVars.
384 if f._field_type == _FIELD_INITVAR:
385 return None
386
387 # Now, actually generate the field assignment.
388 return _field_assign(frozen, f.name, value, self_name)
389
390
391def _init_param(f):
392 # Return the __init__ parameter string for this field.
393 # For example, the equivalent of 'x:int=3' (except instead of 'int',
394 # reference a variable set to int, and instead of '3', reference a
395 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500396 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500397 # There's no default, and no default_factory, just
398 # output the variable name and type.
399 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500400 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500401 # There's a default, this will be the name that's used to look it up.
402 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500403 elif f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500404 # There's a factory function. Set a marker.
405 default = '=_HAS_DEFAULT_FACTORY'
406 return f'{f.name}:_type_{f.name}{default}'
407
408
409def _init_fn(fields, frozen, has_post_init, self_name):
410 # fields contains both real fields and InitVar pseudo-fields.
411
412 # Make sure we don't have fields without defaults following fields
413 # with defaults. This actually would be caught when exec-ing the
414 # function source code, but catching it here gives a better error
415 # message, and future-proofs us in case we build up the function
416 # using ast.
417 seen_default = False
418 for f in fields:
419 # Only consider fields in the __init__ call.
420 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500421 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500422 seen_default = True
423 elif seen_default:
424 raise TypeError(f'non-default argument {f.name!r} '
425 'follows default argument')
426
Eric V. Smith03220fd2017-12-29 13:59:58 -0500427 globals = {'MISSING': MISSING,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500428 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
429
430 body_lines = []
431 for f in fields:
432 # Do not initialize the pseudo-fields, only the real ones.
433 line = _field_init(f, frozen, globals, self_name)
434 if line is not None:
435 # line is None means that this field doesn't require
436 # initialization. Just skip it.
437 body_lines.append(line)
438
439 # Does this class have a post-init function?
440 if has_post_init:
441 params_str = ','.join(f.name for f in fields
442 if f._field_type is _FIELD_INITVAR)
443 body_lines += [f'{self_name}.{_POST_INIT_NAME}({params_str})']
444
445 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500446 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500447 body_lines = ['pass']
448
449 locals = {f'_type_{f.name}': f.type for f in fields}
450 return _create_fn('__init__',
451 [self_name] +[_init_param(f) for f in fields if f.init],
452 body_lines,
453 locals=locals,
454 globals=globals,
455 return_type=None)
456
457
458def _repr_fn(fields):
459 return _create_fn('__repr__',
460 ['self'],
461 ['return self.__class__.__qualname__ + f"(' +
462 ', '.join([f"{f.name}={{self.{f.name}!r}}"
463 for f in fields]) +
464 ')"'])
465
466
Eric V. Smithf199bc62018-03-18 20:40:34 -0400467def _frozen_get_del_attr(cls, fields):
468 # XXX: globals is modified on the first call to _create_fn, then the
469 # modified version is used in the second call. Is this okay?
470 globals = {'cls': cls,
471 'FrozenInstanceError': FrozenInstanceError}
472 if fields:
473 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
474 else:
475 # Special case for the zero-length tuple.
476 fields_str = '()'
477 return (_create_fn('__setattr__',
478 ('self', 'name', 'value'),
479 (f'if type(self) is cls or name in {fields_str}:',
480 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
481 f'super(cls, self).__setattr__(name, value)'),
482 globals=globals),
483 _create_fn('__delattr__',
484 ('self', 'name'),
485 (f'if type(self) is cls or name in {fields_str}:',
486 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
487 f'super(cls, self).__delattr__(name)'),
488 globals=globals),
489 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500490
491
492def _cmp_fn(name, op, self_tuple, other_tuple):
493 # Create a comparison function. If the fields in the object are
494 # named 'x' and 'y', then self_tuple is the string
495 # '(self.x,self.y)' and other_tuple is the string
496 # '(other.x,other.y)'.
497
498 return _create_fn(name,
499 ['self', 'other'],
500 [ 'if other.__class__ is self.__class__:',
501 f' return {self_tuple}{op}{other_tuple}',
502 'return NotImplemented'])
503
504
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500505def _hash_fn(fields):
506 self_tuple = _tuple_str('self', fields)
507 return _create_fn('__hash__',
508 ['self'],
509 [f'return hash({self_tuple})'])
510
511
512def _get_field(cls, a_name, a_type):
513 # Return a Field object, for this field name and type. ClassVars
514 # and InitVars are also returned, but marked as such (see
515 # f._field_type).
516
Eric V. Smith8e4560a2018-03-21 17:10:22 -0400517 # If the default value isn't derived from Field, then it's
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500518 # only a normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500519 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500520 if isinstance(default, Field):
521 f = default
522 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400523 if isinstance(default, types.MemberDescriptorType):
524 # This is a field in __slots__, so it has no default value.
525 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500526 f = field(default=default)
527
528 # Assume it's a normal field until proven otherwise.
529 f._field_type = _FIELD
530
531 # Only at this point do we know the name and the type. Set them.
532 f.name = a_name
533 f.type = a_type
534
535 # If typing has not been imported, then it's impossible for
536 # any annotation to be a ClassVar. So, only look for ClassVar
537 # if typing has been imported.
538 typing = sys.modules.get('typing')
539 if typing is not None:
540 # This test uses a typing internal class, but it's the best
541 # way to test if this is a ClassVar.
Ivan Levkivskyid911e402018-01-20 11:23:59 +0000542 if (type(a_type) is typing._GenericAlias and
543 a_type.__origin__ is typing.ClassVar):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500544 # This field is a ClassVar, so it's not a field.
545 f._field_type = _FIELD_CLASSVAR
546
547 if f._field_type is _FIELD:
548 # Check if this is an InitVar.
549 if a_type is InitVar:
550 # InitVars are not fields, either.
551 f._field_type = _FIELD_INITVAR
552
553 # Validations for fields. This is delayed until now, instead of
554 # in the Field() constructor, since only here do we know the field
555 # name, which allows better error reporting.
556
557 # Special restrictions for ClassVar and InitVar.
558 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500559 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500560 raise TypeError(f'field {f.name} cannot have a '
561 'default factory')
562 # Should I check for other field settings? default_factory
563 # seems the most serious to check for. Maybe add others. For
564 # example, how about init=False (or really,
565 # init=<not-the-default-init-value>)? It makes no sense for
566 # ClassVar and InitVar to specify init=<anything>.
567
568 # For real fields, disallow mutable defaults for known types.
569 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
570 raise ValueError(f'mutable default {type(f.default)} for field '
571 f'{f.name} is not allowed: use default_factory')
572
573 return f
574
575
Eric V. Smithea8fc522018-01-27 19:07:40 -0500576def _set_new_attribute(cls, name, value):
577 # Never overwrites an existing attribute. Returns True if the
578 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500579 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500580 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500581 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500582 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500583
584
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500585# Decide if/how we're going to create a hash function. Key is
586# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
587# take.
588# Actions:
589# '': Do nothing.
590# 'none': Set __hash__ to None.
591# 'add': Always add a generated __hash__function.
592# 'exception': Raise an exception.
593#
594# +-------------------------------------- unsafe_hash?
595# | +------------------------------- eq?
596# | | +------------------------ frozen?
597# | | | +---------------- has-explicit-hash?
598# | | | |
599# | | | | +------- action
600# | | | | |
601# v v v v v
602_hash_action = {(False, False, False, False): (''),
603 (False, False, False, True ): (''),
604 (False, False, True, False): (''),
605 (False, False, True, True ): (''),
606 (False, True, False, False): ('none'),
607 (False, True, False, True ): (''),
608 (False, True, True, False): ('add'),
609 (False, True, True, True ): (''),
610 (True, False, False, False): ('add'),
611 (True, False, False, True ): ('exception'),
612 (True, False, True, False): ('add'),
613 (True, False, True, True ): ('exception'),
614 (True, True, False, False): ('add'),
615 (True, True, False, True ): ('exception'),
616 (True, True, True, False): ('add'),
617 (True, True, True, True ): ('exception'),
618 }
619# See https://bugs.python.org/issue32929#msg312829 for an if-statement
620# version of this table.
621
622
Eric V. Smithf199bc62018-03-18 20:40:34 -0400623def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500624 # Now that dicts retain insertion order, there's no reason to use
625 # an ordered dict. I am leveraging that ordering here, because
626 # derived class fields overwrite base class fields, but the order
627 # is defined by the base class, which is found first.
628 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500629
Eric V. Smithf199bc62018-03-18 20:40:34 -0400630 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
631 unsafe_hash, frozen))
632
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500633 # Find our base classes in reverse MRO order, and exclude
634 # ourselves. In reversed order so that more derived classes
635 # override earlier field definitions in base classes.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400636 # As long as we're iterating over them, see if any are frozen.
637 any_frozen_base = False
638 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500639 for b in cls.__mro__[-1:0:-1]:
640 # Only process classes that have been processed by our
Eric V. Smithf199bc62018-03-18 20:40:34 -0400641 # decorator. That is, they have a _FIELDS attribute.
642 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500643 if base_fields:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400644 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500645 for f in base_fields.values():
646 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400647 if getattr(b, _PARAMS).frozen:
648 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500649
Eric V. Smith56970b82018-03-22 16:28:48 -0400650 # Annotations that are defined in this class (not in base
651 # classes). If __annotations__ isn't present, then this class
652 # adds no new annotations. We use this to compute fields that
653 # are added by this class.
654 # Fields are found from cls_annotations, which is guaranteed to be
655 # ordered. Default values are from class attributes, if a field
656 # has a default. If the default value is a Field(), then it
657 # contains additional info beyond (and possibly including) the
658 # actual default value. Pseudo-fields ClassVars and InitVars are
659 # included, despite the fact that they're not real fields.
660 # That's dealt with later.
661 cls_annotations = cls.__dict__.get('__annotations__', {})
662
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500663 # Now find fields in our class. While doing so, validate some
664 # things, and set the default values (as class attributes)
665 # where we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400666 cls_fields = [_get_field(cls, name, type)
667 for name, type in cls_annotations.items()]
668 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500669 fields[f.name] = f
670
671 # If the class attribute (which is the default value for
672 # this field) exists and is of type 'Field', replace it
673 # with the real default. This is so that normal class
674 # introspection sees a real default value, not a Field.
675 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500676 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500677 # If there's no default, delete the class attribute.
678 # This happens if we specify field(repr=False), for
679 # example (that is, we specified a field object, but
680 # no default value). Also if we're using a default
681 # factory. The class attribute should not be set at
682 # all in the post-processed class.
683 delattr(cls, f.name)
684 else:
685 setattr(cls, f.name, f.default)
686
Eric V. Smith56970b82018-03-22 16:28:48 -0400687 # Do we have any Field members that don't also have annotations?
688 for name, value in cls.__dict__.items():
689 if isinstance(value, Field) and not name in cls_annotations:
690 raise TypeError(f'{name!r} is a field but has no type annotation')
691
Eric V. Smithf199bc62018-03-18 20:40:34 -0400692 # Check rules that apply if we are derived from any dataclasses.
693 if has_dataclass_bases:
694 # Raise an exception if any of our bases are frozen, but we're not.
695 if any_frozen_base and not frozen:
696 raise TypeError('cannot inherit non-frozen dataclass from a '
697 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500698
Eric V. Smithf199bc62018-03-18 20:40:34 -0400699 # Raise an exception if we're frozen, but none of our bases are.
700 if not any_frozen_base and frozen:
701 raise TypeError('cannot inherit frozen dataclass from a '
702 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500703
Eric V. Smithf199bc62018-03-18 20:40:34 -0400704 # Remember all of the fields on our class (including bases). This also
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500705 # marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400706 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500707
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500708 # Was this class defined with an explicit __hash__? Note that if
709 # __eq__ is defined in this class, then python will automatically
710 # set __hash__ to None. This is a heuristic, as it's possible
711 # that such a __hash__ == None was not auto-generated, but it
712 # close enough.
713 class_hash = cls.__dict__.get('__hash__', MISSING)
714 has_explicit_hash = not (class_hash is MISSING or
715 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500716
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500717 # If we're generating ordering methods, we must be generating
718 # the eq methods.
719 if order and not eq:
720 raise ValueError('eq must be true if order is true')
721
722 if init:
723 # Does this class have a post-init function?
724 has_post_init = hasattr(cls, _POST_INIT_NAME)
725
726 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500727 flds = [f for f in fields.values()
728 if f._field_type in (_FIELD, _FIELD_INITVAR)]
729 _set_new_attribute(cls, '__init__',
730 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500731 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500732 has_post_init,
733 # The name to use for the "self" param
734 # in __init__. Use "self" if possible.
735 '__dataclass_self__' if 'self' in fields
736 else 'self',
737 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500738
739 # Get the fields as a list, and include only real fields. This is
740 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500741 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500742
743 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500744 flds = [f for f in field_list if f.repr]
745 _set_new_attribute(cls, '__repr__', _repr_fn(flds))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500746
747 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500748 # Create _eq__ method. There's no need for a __ne__ method,
749 # since python will call __eq__ and negate it.
750 flds = [f for f in field_list if f.compare]
751 self_tuple = _tuple_str('self', flds)
752 other_tuple = _tuple_str('other', flds)
753 _set_new_attribute(cls, '__eq__',
754 _cmp_fn('__eq__', '==',
755 self_tuple, other_tuple))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500756
757 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500758 # Create and set the ordering methods.
759 flds = [f for f in field_list if f.compare]
760 self_tuple = _tuple_str('self', flds)
761 other_tuple = _tuple_str('other', flds)
762 for name, op in [('__lt__', '<'),
763 ('__le__', '<='),
764 ('__gt__', '>'),
765 ('__ge__', '>='),
766 ]:
767 if _set_new_attribute(cls, name,
768 _cmp_fn(name, op, self_tuple, other_tuple)):
769 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500770 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500771 'functools.total_ordering')
772
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500773 if frozen:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400774 # XXX: Which fields are frozen? InitVar? ClassVar? hashed-only?
775 for fn in _frozen_get_del_attr(cls, field_list):
776 if _set_new_attribute(cls, fn.__name__, fn):
777 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500778 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500779
780 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500781 hash_action = _hash_action[bool(unsafe_hash),
782 bool(eq),
783 bool(frozen),
784 has_explicit_hash]
785
Eric V. Smithea8fc522018-01-27 19:07:40 -0500786 # No need to call _set_new_attribute here, since we already know if
787 # we're overwriting a __hash__ or not.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500788 if hash_action == '':
Eric V. Smithea8fc522018-01-27 19:07:40 -0500789 # Do nothing.
790 pass
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500791 elif hash_action == 'none':
Eric V. Smithea8fc522018-01-27 19:07:40 -0500792 cls.__hash__ = None
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500793 elif hash_action == 'add':
794 flds = [f for f in field_list if (f.compare if f.hash is None else f.hash)]
795 cls.__hash__ = _hash_fn(flds)
796 elif hash_action == 'exception':
797 # Raise an exception.
798 raise TypeError(f'Cannot overwrite attribute __hash__ '
799 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500800 else:
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500801 assert False, f"can't get here: {hash_action}"
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500802
803 if not getattr(cls, '__doc__'):
804 # Create a class doc-string.
805 cls.__doc__ = (cls.__name__ +
806 str(inspect.signature(cls)).replace(' -> None', ''))
807
808 return cls
809
810
811# _cls should never be specified by keyword, so start it with an
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800812# underscore. The presence of _cls is used to detect if this
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500813# decorator is being called with parameters or not.
814def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -0500815 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500816 """Returns the same class as was passed in, with dunder methods
817 added based on the fields defined in the class.
818
819 Examines PEP 526 __annotations__ to determine fields.
820
821 If init is true, an __init__() method is added to the class. If
822 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500823 comparison dunder methods are added. If unsafe_hash is true, a
824 __hash__() method function is added. If frozen is true, fields may
825 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500826 """
827
828 def wrap(cls):
Eric V. Smithf199bc62018-03-18 20:40:34 -0400829 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500830
831 # See if we're being called as @dataclass or @dataclass().
832 if _cls is None:
833 # We're called with parens.
834 return wrap
835
836 # We're called as @dataclass without parens.
837 return wrap(_cls)
838
839
840def fields(class_or_instance):
841 """Return a tuple describing the fields of this dataclass.
842
843 Accepts a dataclass or an instance of one. Tuple elements are of
844 type Field.
845 """
846
847 # Might it be worth caching this, per class?
848 try:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400849 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500850 except AttributeError:
851 raise TypeError('must be called with a dataclass type or instance')
852
Eric V. Smithd1388922018-01-07 14:30:17 -0500853 # Exclude pseudo-fields. Note that fields is sorted by insertion
854 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500855 return tuple(f for f in fields.values() if f._field_type is _FIELD)
856
857
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500858def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500859 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithf199bc62018-03-18 20:40:34 -0400860 return not isinstance(obj, type) and hasattr(obj, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500861
862
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500863def is_dataclass(obj):
864 """Returns True if obj is a dataclass or an instance of a
865 dataclass."""
Eric V. Smithf199bc62018-03-18 20:40:34 -0400866 return hasattr(obj, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500867
868
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500869def asdict(obj, *, dict_factory=dict):
870 """Return the fields of a dataclass instance as a new dictionary mapping
871 field names to field values.
872
873 Example usage:
874
875 @dataclass
876 class C:
877 x: int
878 y: int
879
880 c = C(1, 2)
881 assert asdict(c) == {'x': 1, 'y': 2}
882
883 If given, 'dict_factory' will be used instead of built-in dict.
884 The function applies recursively to field values that are
885 dataclass instances. This will also look into built-in containers:
886 tuples, lists, and dicts.
887 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500888 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500889 raise TypeError("asdict() should be called on dataclass instances")
890 return _asdict_inner(obj, dict_factory)
891
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500892
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500893def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500894 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500895 result = []
896 for f in fields(obj):
897 value = _asdict_inner(getattr(obj, f.name), dict_factory)
898 result.append((f.name, value))
899 return dict_factory(result)
900 elif isinstance(obj, (list, tuple)):
901 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
902 elif isinstance(obj, dict):
903 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
904 for k, v in obj.items())
905 else:
906 return deepcopy(obj)
907
908
909def astuple(obj, *, tuple_factory=tuple):
910 """Return the fields of a dataclass instance as a new tuple of field values.
911
912 Example usage::
913
914 @dataclass
915 class C:
916 x: int
917 y: int
918
919 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800920 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500921
922 If given, 'tuple_factory' will be used instead of built-in tuple.
923 The function applies recursively to field values that are
924 dataclass instances. This will also look into built-in containers:
925 tuples, lists, and dicts.
926 """
927
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500928 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500929 raise TypeError("astuple() should be called on dataclass instances")
930 return _astuple_inner(obj, tuple_factory)
931
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500932
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500933def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500934 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500935 result = []
936 for f in fields(obj):
937 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
938 result.append(value)
939 return tuple_factory(result)
940 elif isinstance(obj, (list, tuple)):
941 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
942 elif isinstance(obj, dict):
943 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
944 for k, v in obj.items())
945 else:
946 return deepcopy(obj)
947
948
Eric V. Smithd80b4432018-01-06 17:09:58 -0500949def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -0500950 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500951 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500952 """Return a new dynamically created dataclass.
953
Eric V. Smithed7d4292018-01-06 16:14:03 -0500954 The dataclass name will be 'cls_name'. 'fields' is an iterable
955 of either (name), (name, type) or (name, type, Field) objects. If type is
956 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -0500957 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500958
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800959 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500960
961 is equivalent to:
962
963 @dataclass
964 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800965 x: 'typing.Any'
966 y: int
967 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500968
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800969 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -0500970
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500971 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -0500972 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500973 """
974
975 if namespace is None:
976 namespace = {}
977 else:
978 # Copy namespace since we're going to mutate it.
979 namespace = namespace.copy()
980
Eric V. Smithd1388922018-01-07 14:30:17 -0500981 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500982 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -0500983 if isinstance(item, str):
984 name = item
985 tp = 'typing.Any'
986 elif len(item) == 2:
987 name, tp, = item
988 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500989 name, tp, spec = item
990 namespace[name] = spec
Eric V. Smithed7d4292018-01-06 16:14:03 -0500991 anns[name] = tp
992
993 namespace['__annotations__'] = anns
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500994 cls = type(cls_name, bases, namespace)
Eric V. Smithd80b4432018-01-06 17:09:58 -0500995 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500996 unsafe_hash=unsafe_hash, frozen=frozen)
997
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500998
999def replace(obj, **changes):
1000 """Return a new object replacing specified fields with new values.
1001
1002 This is especially useful for frozen classes. Example usage:
1003
1004 @dataclass(frozen=True)
1005 class C:
1006 x: int
1007 y: int
1008
1009 c = C(1, 2)
1010 c1 = replace(c, x=3)
1011 assert c1.x == 3 and c1.y == 2
1012 """
1013
1014 # We're going to mutate 'changes', but that's okay because it's a new
1015 # dict, even if called with 'replace(obj, **my_changes)'.
1016
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001017 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001018 raise TypeError("replace() should be called on dataclass instances")
1019
1020 # It's an error to have init=False fields in 'changes'.
1021 # If a field is not in 'changes', read its value from the provided obj.
1022
Eric V. Smithf199bc62018-03-18 20:40:34 -04001023 for f in getattr(obj, _FIELDS).values():
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001024 if not f.init:
1025 # Error if this field is specified in changes.
1026 if f.name in changes:
1027 raise ValueError(f'field {f.name} is declared with '
1028 'init=False, it cannot be specified with '
1029 'replace()')
1030 continue
1031
1032 if f.name not in changes:
1033 changes[f.name] = getattr(obj, f.name)
1034
1035 # Create the new object, which calls __init__() and __post_init__
1036 # (if defined), using all of the init fields we've added and/or
1037 # left in 'changes'.
1038 # If there are values supplied in changes that aren't fields, this
1039 # will correctly raise a TypeError.
1040 return obj.__class__(**changes)