blob: d61643249148899bdc1fb1330a1566910192f46e [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
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -080023# 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
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800113# +------------------- 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).
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800142# 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.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700174_FIELDS = '__dataclass_fields__'
175
176# The name of an attribute on the class that stores the parameters to
177# @dataclass.
178_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500179
180# The name of the function, that if it exists, is called at the end of
181# __init__.
182_POST_INIT_NAME = '__post_init__'
183
184
185class _InitVarMeta(type):
186 def __getitem__(self, params):
187 return self
188
189class InitVar(metaclass=_InitVarMeta):
190 pass
191
192
193# Instances of Field are only ever created from within this module,
194# and only from the field() function, although Field instances are
195# exposed externally as (conceptually) read-only objects.
196# name and type are filled in after the fact, not in __init__. They're
197# not known at the time this class is instantiated, but it's
198# convenient if they're available later.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700199# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500200# and type fields will have been populated.
201class Field:
202 __slots__ = ('name',
203 'type',
204 'default',
205 'default_factory',
206 'repr',
207 'hash',
208 'init',
209 'compare',
210 'metadata',
211 '_field_type', # Private: not to be used by user code.
212 )
213
214 def __init__(self, default, default_factory, init, repr, hash, compare,
215 metadata):
216 self.name = None
217 self.type = None
218 self.default = default
219 self.default_factory = default_factory
220 self.init = init
221 self.repr = repr
222 self.hash = hash
223 self.compare = compare
224 self.metadata = (_EMPTY_METADATA
225 if metadata is None or len(metadata) == 0 else
226 types.MappingProxyType(metadata))
227 self._field_type = None
228
229 def __repr__(self):
230 return ('Field('
231 f'name={self.name!r},'
232 f'type={self.type},'
233 f'default={self.default},'
234 f'default_factory={self.default_factory},'
235 f'init={self.init},'
236 f'repr={self.repr},'
237 f'hash={self.hash},'
238 f'compare={self.compare},'
239 f'metadata={self.metadata}'
240 ')')
241
242
Miss Islington (bot)45648312018-03-18 18:03:36 -0700243class _DataclassParams:
244 __slots__ = ('init',
245 'repr',
246 'eq',
247 'order',
248 'unsafe_hash',
249 'frozen',
250 )
251 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
252 self.init = init
253 self.repr = repr
254 self.eq = eq
255 self.order = order
256 self.unsafe_hash = unsafe_hash
257 self.frozen = frozen
258
259 def __repr__(self):
260 return ('_DataclassParams('
261 f'init={self.init},'
262 f'repr={self.repr},'
263 f'eq={self.eq},'
264 f'order={self.order},'
265 f'unsafe_hash={self.unsafe_hash},'
266 f'frozen={self.frozen}'
267 ')')
268
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500269# This function is used instead of exposing Field creation directly,
270# so that a type checker can be told (via overloads) that this is a
271# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500272def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500273 hash=None, compare=True, metadata=None):
274 """Return an object to identify dataclass fields.
275
276 default is the default value of the field. default_factory is a
277 0-argument function called to initialize a field's value. If init
278 is True, the field will be a parameter to the class's __init__()
279 function. If repr is True, the field will be included in the
280 object's repr(). If hash is True, the field will be included in
281 the object's hash(). If compare is True, the field will be used in
282 comparison functions. metadata, if specified, must be a mapping
283 which is stored but not otherwise examined by dataclass.
284
285 It is an error to specify both default and default_factory.
286 """
287
Eric V. Smith03220fd2017-12-29 13:59:58 -0500288 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500289 raise ValueError('cannot specify both default and default_factory')
290 return Field(default, default_factory, init, repr, hash, compare,
291 metadata)
292
293
294def _tuple_str(obj_name, fields):
295 # Return a string representing each field of obj_name as a tuple
296 # member. So, if fields is ['x', 'y'] and obj_name is "self",
297 # return "(self.x,self.y)".
298
299 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500300 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500301 return '()'
302 # Note the trailing comma, needed if this turns out to be a 1-tuple.
303 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
304
305
Eric V. Smithea8fc522018-01-27 19:07:40 -0500306def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500307 return_type=MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500308 # Note that we mutate locals when exec() is called. Caller beware!
309 if locals is None:
310 locals = {}
311 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500312 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500313 locals['_return_type'] = return_type
314 return_annotation = '->_return_type'
315 args = ','.join(args)
316 body = '\n'.join(f' {b}' for b in body)
317
Miss Islington (bot)45648312018-03-18 18:03:36 -0700318 # Compute the text of the entire function.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500319 txt = f'def {name}({args}){return_annotation}:\n{body}'
320
321 exec(txt, globals, locals)
322 return locals[name]
323
324
325def _field_assign(frozen, name, value, self_name):
326 # If we're a frozen class, then assign to our fields in __init__
327 # via object.__setattr__. Otherwise, just use a simple
328 # assignment.
329 # self_name is what "self" is called in this function: don't
330 # hard-code "self", since that might be a field name.
331 if frozen:
332 return f'object.__setattr__({self_name},{name!r},{value})'
333 return f'{self_name}.{name}={value}'
334
335
336def _field_init(f, frozen, globals, self_name):
337 # Return the text of the line in the body of __init__ that will
338 # initialize this field.
339
340 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500341 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500342 if f.init:
343 # This field has a default factory. If a parameter is
344 # given, use it. If not, call the factory.
345 globals[default_name] = f.default_factory
346 value = (f'{default_name}() '
347 f'if {f.name} is _HAS_DEFAULT_FACTORY '
348 f'else {f.name}')
349 else:
350 # This is a field that's not in the __init__ params, but
351 # has a default factory function. It needs to be
352 # initialized here by calling the factory function,
353 # because there's no other way to initialize it.
354
355 # For a field initialized with a default=defaultvalue, the
356 # class dict just has the default value
357 # (cls.fieldname=defaultvalue). But that won't work for a
358 # default factory, the factory must be called in __init__
359 # and we must assign that to self.fieldname. We can't
360 # fall back to the class dict's value, both because it's
361 # not set, and because it might be different per-class
362 # (which, after all, is why we have a factory function!).
363
364 globals[default_name] = f.default_factory
365 value = f'{default_name}()'
366 else:
367 # No default factory.
368 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500369 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500370 # There's no default, just do an assignment.
371 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500372 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500373 globals[default_name] = f.default
374 value = f.name
375 else:
376 # This field does not need initialization. Signify that to
377 # the caller by returning None.
378 return None
379
380 # Only test this now, so that we can create variables for the
381 # default. However, return None to signify that we're not going
382 # to actually do the assignment statement for InitVars.
383 if f._field_type == _FIELD_INITVAR:
384 return None
385
386 # Now, actually generate the field assignment.
387 return _field_assign(frozen, f.name, value, self_name)
388
389
390def _init_param(f):
391 # Return the __init__ parameter string for this field.
392 # For example, the equivalent of 'x:int=3' (except instead of 'int',
393 # reference a variable set to int, and instead of '3', reference a
394 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500395 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500396 # There's no default, and no default_factory, just
397 # output the variable name and type.
398 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500399 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500400 # There's a default, this will be the name that's used to look it up.
401 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500402 elif f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500403 # There's a factory function. Set a marker.
404 default = '=_HAS_DEFAULT_FACTORY'
405 return f'{f.name}:_type_{f.name}{default}'
406
407
408def _init_fn(fields, frozen, has_post_init, self_name):
409 # fields contains both real fields and InitVar pseudo-fields.
410
411 # Make sure we don't have fields without defaults following fields
412 # with defaults. This actually would be caught when exec-ing the
413 # function source code, but catching it here gives a better error
414 # message, and future-proofs us in case we build up the function
415 # using ast.
416 seen_default = False
417 for f in fields:
418 # Only consider fields in the __init__ call.
419 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500420 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500421 seen_default = True
422 elif seen_default:
423 raise TypeError(f'non-default argument {f.name!r} '
424 'follows default argument')
425
Eric V. Smith03220fd2017-12-29 13:59:58 -0500426 globals = {'MISSING': MISSING,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500427 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
428
429 body_lines = []
430 for f in fields:
431 # Do not initialize the pseudo-fields, only the real ones.
432 line = _field_init(f, frozen, globals, self_name)
433 if line is not None:
434 # line is None means that this field doesn't require
435 # initialization. Just skip it.
436 body_lines.append(line)
437
438 # Does this class have a post-init function?
439 if has_post_init:
440 params_str = ','.join(f.name for f in fields
441 if f._field_type is _FIELD_INITVAR)
442 body_lines += [f'{self_name}.{_POST_INIT_NAME}({params_str})']
443
444 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500445 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500446 body_lines = ['pass']
447
448 locals = {f'_type_{f.name}': f.type for f in fields}
449 return _create_fn('__init__',
450 [self_name] +[_init_param(f) for f in fields if f.init],
451 body_lines,
452 locals=locals,
453 globals=globals,
454 return_type=None)
455
456
457def _repr_fn(fields):
458 return _create_fn('__repr__',
459 ['self'],
460 ['return self.__class__.__qualname__ + f"(' +
461 ', '.join([f"{f.name}={{self.{f.name}!r}}"
462 for f in fields]) +
463 ')"'])
464
465
Miss Islington (bot)45648312018-03-18 18:03:36 -0700466def _frozen_get_del_attr(cls, fields):
467 # XXX: globals is modified on the first call to _create_fn, then the
468 # modified version is used in the second call. Is this okay?
469 globals = {'cls': cls,
470 'FrozenInstanceError': FrozenInstanceError}
471 if fields:
472 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
473 else:
474 # Special case for the zero-length tuple.
475 fields_str = '()'
476 return (_create_fn('__setattr__',
477 ('self', 'name', 'value'),
478 (f'if type(self) is cls or name in {fields_str}:',
479 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
480 f'super(cls, self).__setattr__(name, value)'),
481 globals=globals),
482 _create_fn('__delattr__',
483 ('self', 'name'),
484 (f'if type(self) is cls or name in {fields_str}:',
485 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
486 f'super(cls, self).__delattr__(name)'),
487 globals=globals),
488 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500489
490
491def _cmp_fn(name, op, self_tuple, other_tuple):
492 # Create a comparison function. If the fields in the object are
493 # named 'x' and 'y', then self_tuple is the string
494 # '(self.x,self.y)' and other_tuple is the string
495 # '(other.x,other.y)'.
496
497 return _create_fn(name,
498 ['self', 'other'],
499 [ 'if other.__class__ is self.__class__:',
500 f' return {self_tuple}{op}{other_tuple}',
501 'return NotImplemented'])
502
503
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500504def _hash_fn(fields):
505 self_tuple = _tuple_str('self', fields)
506 return _create_fn('__hash__',
507 ['self'],
508 [f'return hash({self_tuple})'])
509
510
511def _get_field(cls, a_name, a_type):
512 # Return a Field object, for this field name and type. ClassVars
513 # and InitVars are also returned, but marked as such (see
514 # f._field_type).
515
516 # If the default value isn't derived from field, then it's
517 # only a normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500518 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500519 if isinstance(default, Field):
520 f = default
521 else:
Miss Islington (bot)3d41f482018-03-19 18:31:22 -0700522 if isinstance(default, types.MemberDescriptorType):
523 # This is a field in __slots__, so it has no default value.
524 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500525 f = field(default=default)
526
527 # Assume it's a normal field until proven otherwise.
528 f._field_type = _FIELD
529
530 # Only at this point do we know the name and the type. Set them.
531 f.name = a_name
532 f.type = a_type
533
534 # If typing has not been imported, then it's impossible for
535 # any annotation to be a ClassVar. So, only look for ClassVar
536 # if typing has been imported.
537 typing = sys.modules.get('typing')
538 if typing is not None:
539 # This test uses a typing internal class, but it's the best
540 # way to test if this is a ClassVar.
Ivan Levkivskyid911e402018-01-20 11:23:59 +0000541 if (type(a_type) is typing._GenericAlias and
542 a_type.__origin__ is typing.ClassVar):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500543 # This field is a ClassVar, so it's not a field.
544 f._field_type = _FIELD_CLASSVAR
545
546 if f._field_type is _FIELD:
547 # Check if this is an InitVar.
548 if a_type is InitVar:
549 # InitVars are not fields, either.
550 f._field_type = _FIELD_INITVAR
551
552 # Validations for fields. This is delayed until now, instead of
553 # in the Field() constructor, since only here do we know the field
554 # name, which allows better error reporting.
555
556 # Special restrictions for ClassVar and InitVar.
557 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500558 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500559 raise TypeError(f'field {f.name} cannot have a '
560 'default factory')
561 # Should I check for other field settings? default_factory
562 # seems the most serious to check for. Maybe add others. For
563 # example, how about init=False (or really,
564 # init=<not-the-default-init-value>)? It makes no sense for
565 # ClassVar and InitVar to specify init=<anything>.
566
567 # For real fields, disallow mutable defaults for known types.
568 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
569 raise ValueError(f'mutable default {type(f.default)} for field '
570 f'{f.name} is not allowed: use default_factory')
571
572 return f
573
574
575def _find_fields(cls):
576 # Return a list of Field objects, in order, for this class (and no
Miss Islington (bot)22136c92018-03-21 02:17:30 -0700577 # base classes). Fields are found from the class dict's
578 # __annotations__ (which is guaranteed to be ordered). Default
579 # values are from class attributes, if a field has a default. If
580 # the default value is a Field(), then it contains additional
581 # info beyond (and possibly including) the actual default value.
582 # Pseudo-fields ClassVars and InitVars are included, despite the
583 # fact that they're not real fields. That's dealt with later.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500584
Miss Islington (bot)22136c92018-03-21 02:17:30 -0700585 # If __annotations__ isn't present, then this class adds no new
586 # annotations.
587 annotations = cls.__dict__.get('__annotations__', {})
588 return [_get_field(cls, name, type) for name, type in annotations.items()]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500589
590
Eric V. Smithea8fc522018-01-27 19:07:40 -0500591def _set_new_attribute(cls, name, value):
592 # Never overwrites an existing attribute. Returns True if the
593 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500594 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500595 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500596 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500597 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500598
599
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800600# Decide if/how we're going to create a hash function. Key is
601# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
602# take.
603# Actions:
604# '': Do nothing.
605# 'none': Set __hash__ to None.
606# 'add': Always add a generated __hash__function.
607# 'exception': Raise an exception.
608#
609# +-------------------------------------- unsafe_hash?
610# | +------------------------------- eq?
611# | | +------------------------ frozen?
612# | | | +---------------- has-explicit-hash?
613# | | | |
614# | | | | +------- action
615# | | | | |
616# v v v v v
617_hash_action = {(False, False, False, False): (''),
618 (False, False, False, True ): (''),
619 (False, False, True, False): (''),
620 (False, False, True, True ): (''),
621 (False, True, False, False): ('none'),
622 (False, True, False, True ): (''),
623 (False, True, True, False): ('add'),
624 (False, True, True, True ): (''),
625 (True, False, False, False): ('add'),
626 (True, False, False, True ): ('exception'),
627 (True, False, True, False): ('add'),
628 (True, False, True, True ): ('exception'),
629 (True, True, False, False): ('add'),
630 (True, True, False, True ): ('exception'),
631 (True, True, True, False): ('add'),
632 (True, True, True, True ): ('exception'),
633 }
634# See https://bugs.python.org/issue32929#msg312829 for an if-statement
635# version of this table.
636
637
Miss Islington (bot)45648312018-03-18 18:03:36 -0700638def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500639 # Now that dicts retain insertion order, there's no reason to use
640 # an ordered dict. I am leveraging that ordering here, because
641 # derived class fields overwrite base class fields, but the order
642 # is defined by the base class, which is found first.
643 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500644
Miss Islington (bot)45648312018-03-18 18:03:36 -0700645 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
646 unsafe_hash, frozen))
647
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500648 # Find our base classes in reverse MRO order, and exclude
649 # ourselves. In reversed order so that more derived classes
650 # override earlier field definitions in base classes.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700651 # As long as we're iterating over them, see if any are frozen.
652 any_frozen_base = False
653 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500654 for b in cls.__mro__[-1:0:-1]:
655 # Only process classes that have been processed by our
Miss Islington (bot)45648312018-03-18 18:03:36 -0700656 # decorator. That is, they have a _FIELDS attribute.
657 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500658 if base_fields:
Miss Islington (bot)45648312018-03-18 18:03:36 -0700659 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500660 for f in base_fields.values():
661 fields[f.name] = f
Miss Islington (bot)45648312018-03-18 18:03:36 -0700662 if getattr(b, _PARAMS).frozen:
663 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500664
665 # Now find fields in our class. While doing so, validate some
666 # things, and set the default values (as class attributes)
667 # where we can.
668 for f in _find_fields(cls):
669 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
Miss Islington (bot)45648312018-03-18 18:03:36 -0700687 # Check rules that apply if we are derived from any dataclasses.
688 if has_dataclass_bases:
689 # Raise an exception if any of our bases are frozen, but we're not.
690 if any_frozen_base and not frozen:
691 raise TypeError('cannot inherit non-frozen dataclass from a '
692 'frozen one')
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800693
Miss Islington (bot)45648312018-03-18 18:03:36 -0700694 # Raise an exception if we're frozen, but none of our bases are.
695 if not any_frozen_base and frozen:
696 raise TypeError('cannot inherit frozen dataclass from a '
697 'non-frozen one')
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800698
Miss Islington (bot)45648312018-03-18 18:03:36 -0700699 # Remember all of the fields on our class (including bases). This also
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500700 # marks this class as being a dataclass.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700701 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500702
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800703 # Was this class defined with an explicit __hash__? Note that if
704 # __eq__ is defined in this class, then python will automatically
705 # set __hash__ to None. This is a heuristic, as it's possible
706 # that such a __hash__ == None was not auto-generated, but it
707 # close enough.
708 class_hash = cls.__dict__.get('__hash__', MISSING)
709 has_explicit_hash = not (class_hash is MISSING or
710 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500711
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500712 # If we're generating ordering methods, we must be generating
713 # the eq methods.
714 if order and not eq:
715 raise ValueError('eq must be true if order is true')
716
717 if init:
718 # Does this class have a post-init function?
719 has_post_init = hasattr(cls, _POST_INIT_NAME)
720
721 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500722 flds = [f for f in fields.values()
723 if f._field_type in (_FIELD, _FIELD_INITVAR)]
724 _set_new_attribute(cls, '__init__',
725 _init_fn(flds,
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800726 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500727 has_post_init,
728 # The name to use for the "self" param
729 # in __init__. Use "self" if possible.
730 '__dataclass_self__' if 'self' in fields
731 else 'self',
732 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500733
734 # Get the fields as a list, and include only real fields. This is
735 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500736 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500737
738 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500739 flds = [f for f in field_list if f.repr]
740 _set_new_attribute(cls, '__repr__', _repr_fn(flds))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500741
742 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500743 # Create _eq__ method. There's no need for a __ne__ method,
744 # since python will call __eq__ and negate it.
745 flds = [f for f in field_list if f.compare]
746 self_tuple = _tuple_str('self', flds)
747 other_tuple = _tuple_str('other', flds)
748 _set_new_attribute(cls, '__eq__',
749 _cmp_fn('__eq__', '==',
750 self_tuple, other_tuple))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500751
752 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500753 # Create and set the ordering methods.
754 flds = [f for f in field_list if f.compare]
755 self_tuple = _tuple_str('self', flds)
756 other_tuple = _tuple_str('other', flds)
757 for name, op in [('__lt__', '<'),
758 ('__le__', '<='),
759 ('__gt__', '>'),
760 ('__ge__', '>='),
761 ]:
762 if _set_new_attribute(cls, name,
763 _cmp_fn(name, op, self_tuple, other_tuple)):
764 raise TypeError(f'Cannot overwrite attribute {name} '
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800765 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500766 'functools.total_ordering')
767
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800768 if frozen:
Miss Islington (bot)45648312018-03-18 18:03:36 -0700769 # XXX: Which fields are frozen? InitVar? ClassVar? hashed-only?
770 for fn in _frozen_get_del_attr(cls, field_list):
771 if _set_new_attribute(cls, fn.__name__, fn):
772 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800773 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500774
775 # Decide if/how we're going to create a hash function.
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800776 hash_action = _hash_action[bool(unsafe_hash),
777 bool(eq),
778 bool(frozen),
779 has_explicit_hash]
780
Eric V. Smithea8fc522018-01-27 19:07:40 -0500781 # No need to call _set_new_attribute here, since we already know if
782 # we're overwriting a __hash__ or not.
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800783 if hash_action == '':
Eric V. Smithea8fc522018-01-27 19:07:40 -0500784 # Do nothing.
785 pass
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800786 elif hash_action == 'none':
Eric V. Smithea8fc522018-01-27 19:07:40 -0500787 cls.__hash__ = None
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800788 elif hash_action == 'add':
789 flds = [f for f in field_list if (f.compare if f.hash is None else f.hash)]
790 cls.__hash__ = _hash_fn(flds)
791 elif hash_action == 'exception':
792 # Raise an exception.
793 raise TypeError(f'Cannot overwrite attribute __hash__ '
794 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500795 else:
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800796 assert False, f"can't get here: {hash_action}"
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500797
798 if not getattr(cls, '__doc__'):
799 # Create a class doc-string.
800 cls.__doc__ = (cls.__name__ +
801 str(inspect.signature(cls)).replace(' -> None', ''))
802
803 return cls
804
805
806# _cls should never be specified by keyword, so start it with an
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800807# underscore. The presence of _cls is used to detect if this
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500808# decorator is being called with parameters or not.
809def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
Miss Islington (bot)398242a2018-03-01 05:30:13 -0800810 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500811 """Returns the same class as was passed in, with dunder methods
812 added based on the fields defined in the class.
813
814 Examines PEP 526 __annotations__ to determine fields.
815
816 If init is true, an __init__() method is added to the class. If
817 repr is true, a __repr__() method is added. If order is true, rich
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800818 comparison dunder methods are added. If unsafe_hash is true, a
819 __hash__() method function is added. If frozen is true, fields may
820 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500821 """
822
823 def wrap(cls):
Miss Islington (bot)45648312018-03-18 18:03:36 -0700824 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500825
826 # See if we're being called as @dataclass or @dataclass().
827 if _cls is None:
828 # We're called with parens.
829 return wrap
830
831 # We're called as @dataclass without parens.
832 return wrap(_cls)
833
834
835def fields(class_or_instance):
836 """Return a tuple describing the fields of this dataclass.
837
838 Accepts a dataclass or an instance of one. Tuple elements are of
839 type Field.
840 """
841
842 # Might it be worth caching this, per class?
843 try:
Miss Islington (bot)45648312018-03-18 18:03:36 -0700844 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500845 except AttributeError:
846 raise TypeError('must be called with a dataclass type or instance')
847
Eric V. Smithd1388922018-01-07 14:30:17 -0500848 # Exclude pseudo-fields. Note that fields is sorted by insertion
849 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500850 return tuple(f for f in fields.values() if f._field_type is _FIELD)
851
852
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500853def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500854 """Returns True if obj is an instance of a dataclass."""
Miss Islington (bot)45648312018-03-18 18:03:36 -0700855 return not isinstance(obj, type) and hasattr(obj, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500856
857
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500858def is_dataclass(obj):
859 """Returns True if obj is a dataclass or an instance of a
860 dataclass."""
Miss Islington (bot)45648312018-03-18 18:03:36 -0700861 return hasattr(obj, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500862
863
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500864def asdict(obj, *, dict_factory=dict):
865 """Return the fields of a dataclass instance as a new dictionary mapping
866 field names to field values.
867
868 Example usage:
869
870 @dataclass
871 class C:
872 x: int
873 y: int
874
875 c = C(1, 2)
876 assert asdict(c) == {'x': 1, 'y': 2}
877
878 If given, 'dict_factory' will be used instead of built-in dict.
879 The function applies recursively to field values that are
880 dataclass instances. This will also look into built-in containers:
881 tuples, lists, and dicts.
882 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500883 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500884 raise TypeError("asdict() should be called on dataclass instances")
885 return _asdict_inner(obj, dict_factory)
886
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800887
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500888def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500889 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500890 result = []
891 for f in fields(obj):
892 value = _asdict_inner(getattr(obj, f.name), dict_factory)
893 result.append((f.name, value))
894 return dict_factory(result)
895 elif isinstance(obj, (list, tuple)):
896 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
897 elif isinstance(obj, dict):
898 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
899 for k, v in obj.items())
900 else:
901 return deepcopy(obj)
902
903
904def astuple(obj, *, tuple_factory=tuple):
905 """Return the fields of a dataclass instance as a new tuple of field values.
906
907 Example usage::
908
909 @dataclass
910 class C:
911 x: int
912 y: int
913
914 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800915 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500916
917 If given, 'tuple_factory' will be used instead of built-in tuple.
918 The function applies recursively to field values that are
919 dataclass instances. This will also look into built-in containers:
920 tuples, lists, and dicts.
921 """
922
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500923 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500924 raise TypeError("astuple() should be called on dataclass instances")
925 return _astuple_inner(obj, tuple_factory)
926
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800927
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500928def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500929 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500930 result = []
931 for f in fields(obj):
932 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
933 result.append(value)
934 return tuple_factory(result)
935 elif isinstance(obj, (list, tuple)):
936 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
937 elif isinstance(obj, dict):
938 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
939 for k, v in obj.items())
940 else:
941 return deepcopy(obj)
942
943
Eric V. Smithd80b4432018-01-06 17:09:58 -0500944def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Miss Islington (bot)398242a2018-03-01 05:30:13 -0800945 repr=True, eq=True, order=False, unsafe_hash=False,
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800946 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500947 """Return a new dynamically created dataclass.
948
Eric V. Smithed7d4292018-01-06 16:14:03 -0500949 The dataclass name will be 'cls_name'. 'fields' is an iterable
950 of either (name), (name, type) or (name, type, Field) objects. If type is
951 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -0500952 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500953
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800954 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500955
956 is equivalent to:
957
958 @dataclass
959 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800960 x: 'typing.Any'
961 y: int
962 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500963
Raymond Hettingerd55209d2018-01-10 20:56:41 -0800964 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -0500965
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800966 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -0500967 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500968 """
969
970 if namespace is None:
971 namespace = {}
972 else:
973 # Copy namespace since we're going to mutate it.
974 namespace = namespace.copy()
975
Eric V. Smithd1388922018-01-07 14:30:17 -0500976 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500977 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -0500978 if isinstance(item, str):
979 name = item
980 tp = 'typing.Any'
981 elif len(item) == 2:
982 name, tp, = item
983 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500984 name, tp, spec = item
985 namespace[name] = spec
Eric V. Smithed7d4292018-01-06 16:14:03 -0500986 anns[name] = tp
987
988 namespace['__annotations__'] = anns
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500989 cls = type(cls_name, bases, namespace)
Eric V. Smithd80b4432018-01-06 17:09:58 -0500990 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800991 unsafe_hash=unsafe_hash, frozen=frozen)
992
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500993
994def replace(obj, **changes):
995 """Return a new object replacing specified fields with new values.
996
997 This is especially useful for frozen classes. Example usage:
998
999 @dataclass(frozen=True)
1000 class C:
1001 x: int
1002 y: int
1003
1004 c = C(1, 2)
1005 c1 = replace(c, x=3)
1006 assert c1.x == 3 and c1.y == 2
1007 """
1008
1009 # We're going to mutate 'changes', but that's okay because it's a new
1010 # dict, even if called with 'replace(obj, **my_changes)'.
1011
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001012 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001013 raise TypeError("replace() should be called on dataclass instances")
1014
1015 # It's an error to have init=False fields in 'changes'.
1016 # If a field is not in 'changes', read its value from the provided obj.
1017
Miss Islington (bot)45648312018-03-18 18:03:36 -07001018 for f in getattr(obj, _FIELDS).values():
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001019 if not f.init:
1020 # Error if this field is specified in changes.
1021 if f.name in changes:
1022 raise ValueError(f'field {f.name} is declared with '
1023 'init=False, it cannot be specified with '
1024 'replace()')
1025 continue
1026
1027 if f.name not in changes:
1028 changes[f.name] = getattr(obj, f.name)
1029
1030 # Create the new object, which calls __init__() and __post_init__
1031 # (if defined), using all of the init fields we've added and/or
1032 # left in 'changes'.
1033 # If there are values supplied in changes that aren't fields, this
1034 # will correctly raise a TypeError.
1035 return obj.__class__(**changes)