blob: 105a95b95540ebf4e388a44640e99edff821ce70 [file] [log] [blame]
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001import re
Eric V. Smithf0db54a2017-12-04 16:58:55 -05002import sys
Eric V. Smithf96ddad2018-03-24 17:20:26 -04003import copy
Eric V. Smithf0db54a2017-12-04 16:58:55 -05004import types
Eric V. Smithf0db54a2017-12-04 16:58:55 -05005import inspect
Eric V. Smith4e812962018-05-16 11:31:29 -04006import keyword
Vadim Pushtaev4d12e4d2018-08-12 14:46:05 +03007import builtins
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +05308import functools
Ben Avrahamibef7d292020-10-06 20:40:50 +03009import abc
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +053010import _thread
Batuhan Taskayac7437e22020-10-21 16:49:22 +030011from types import FunctionType, GenericAlias
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +053012
Eric V. Smithf0db54a2017-12-04 16:58:55 -050013
14__all__ = ['dataclass',
15 'field',
Eric V. Smith8e4560a2018-03-21 17:10:22 -040016 'Field',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050017 'FrozenInstanceError',
18 'InitVar',
Eric V. Smithc0280532021-04-25 20:42:39 -040019 'KW_ONLY',
Eric V. Smith03220fd2017-12-29 13:59:58 -050020 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050021
22 # Helper functions.
23 'fields',
24 'asdict',
25 'astuple',
26 'make_dataclass',
27 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050028 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050029 ]
30
Eric V. Smithea8fc522018-01-27 19:07:40 -050031# Conditions for adding methods. The boxes indicate what action the
Eric V. Smithf8e75492018-05-16 05:14:53 -040032# dataclass decorator takes. For all of these tables, when I talk
33# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
34# referring to the arguments to the @dataclass decorator. When
35# checking if a dunder method already exists, I mean check for an
36# entry in the class's __dict__. I never check to see if an attribute
37# is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050038
39# Key:
40# +=========+=========================================+
41# + Value | Meaning |
42# +=========+=========================================+
43# | <blank> | No action: no method is added. |
44# +---------+-----------------------------------------+
45# | add | Generated method is added. |
46# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050047# | raise | TypeError is raised. |
48# +---------+-----------------------------------------+
49# | None | Attribute is set to None. |
50# +=========+=========================================+
51
52# __init__
53#
54# +--- init= parameter
55# |
56# v | | |
57# | no | yes | <--- class has __init__ in __dict__?
58# +=======+=======+=======+
59# | False | | |
60# +-------+-------+-------+
61# | True | add | | <- the default
62# +=======+=======+=======+
63
64# __repr__
65#
66# +--- repr= parameter
67# |
68# v | | |
69# | no | yes | <--- class has __repr__ in __dict__?
70# +=======+=======+=======+
71# | False | | |
72# +-------+-------+-------+
73# | True | add | | <- the default
74# +=======+=======+=======+
75
76
77# __setattr__
78# __delattr__
79#
80# +--- frozen= parameter
81# |
82# v | | |
83# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
84# +=======+=======+=======+
85# | False | | | <- the default
86# +-------+-------+-------+
87# | True | add | raise |
88# +=======+=======+=======+
89# Raise because not adding these methods would break the "frozen-ness"
Eric V. Smithf8e75492018-05-16 05:14:53 -040090# of the class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050091
92# __eq__
93#
94# +--- eq= parameter
95# |
96# v | | |
97# | no | yes | <--- class has __eq__ in __dict__?
98# +=======+=======+=======+
99# | False | | |
100# +-------+-------+-------+
101# | True | add | | <- the default
102# +=======+=======+=======+
103
104# __lt__
105# __le__
106# __gt__
107# __ge__
108#
109# +--- order= parameter
110# |
111# v | | |
112# | no | yes | <--- class has any comparison method in __dict__?
113# +=======+=======+=======+
114# | False | | | <- the default
115# +-------+-------+-------+
116# | True | add | raise |
117# +=======+=======+=======+
118# Raise because to allow this case would interfere with using
Eric V. Smithf8e75492018-05-16 05:14:53 -0400119# functools.total_ordering.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500120
121# __hash__
122
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500123# +------------------- unsafe_hash= parameter
124# | +----------- eq= parameter
125# | | +--- frozen= parameter
126# | | |
127# v v v | | |
128# | no | yes | <--- class has explicitly defined __hash__
129# +=======+=======+=======+========+========+
130# | False | False | False | | | No __eq__, use the base class __hash__
131# +-------+-------+-------+--------+--------+
132# | False | False | True | | | No __eq__, use the base class __hash__
133# +-------+-------+-------+--------+--------+
134# | False | True | False | None | | <-- the default, not hashable
135# +-------+-------+-------+--------+--------+
136# | False | True | True | add | | Frozen, so hashable, allows override
137# +-------+-------+-------+--------+--------+
138# | True | False | False | add | raise | Has no __eq__, but hashable
139# +-------+-------+-------+--------+--------+
140# | True | False | True | add | raise | Has no __eq__, but hashable
141# +-------+-------+-------+--------+--------+
142# | True | True | False | add | raise | Not frozen, but hashable
143# +-------+-------+-------+--------+--------+
144# | True | True | True | add | raise | Frozen, so hashable
145# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500146# For boxes that are blank, __hash__ is untouched and therefore
Eric V. Smithf8e75492018-05-16 05:14:53 -0400147# inherited from the base class. If the base is object, then
148# id-based hashing is used.
149#
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400150# Note that a class may already have __hash__=None if it specified an
Eric V. Smithf8e75492018-05-16 05:14:53 -0400151# __eq__ method in the class body (not one that was created by
152# @dataclass).
153#
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500154# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500155
Brandt Bucher145bf262021-02-26 14:51:55 -0800156# __match_args__
157#
Eric V. Smith750f4842021-04-10 21:28:42 -0400158# +--- match_args= parameter
159# |
160# v | | |
161# | no | yes | <--- class has __match_args__ in __dict__?
162# +=======+=======+=======+
163# | False | | |
164# +-------+-------+-------+
165# | True | add | | <- the default
166# +=======+=======+=======+
Eric V. Smithc0280532021-04-25 20:42:39 -0400167# __match_args__ is always added unless the class already defines it. It is a
168# tuple of __init__ parameter names; non-init fields must be matched by keyword.
Brandt Bucher145bf262021-02-26 14:51:55 -0800169
Eric V. Smithea8fc522018-01-27 19:07:40 -0500170
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500171# Raised when an attempt is made to modify a frozen class.
172class FrozenInstanceError(AttributeError): pass
173
Eric V. Smithf8e75492018-05-16 05:14:53 -0400174# A sentinel object for default values to signal that a default
175# factory will be used. This is given a nice repr() which will appear
176# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500177class _HAS_DEFAULT_FACTORY_CLASS:
178 def __repr__(self):
179 return '<factory>'
180_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
181
Eric V. Smith03220fd2017-12-29 13:59:58 -0500182# A sentinel object to detect if a parameter is supplied or not. Use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400183# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500184class _MISSING_TYPE:
185 pass
186MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500187
Eric V. Smithc0280532021-04-25 20:42:39 -0400188# A sentinel object to indicate that following fields are keyword-only by
189# default. Use a class to give it a better repr.
190class _KW_ONLY_TYPE:
191 pass
192KW_ONLY = _KW_ONLY_TYPE()
193
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500194# Since most per-field metadata will be unused, create an empty
Eric V. Smithf8e75492018-05-16 05:14:53 -0400195# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500196_EMPTY_METADATA = types.MappingProxyType({})
197
198# Markers for the various kinds of fields and pseudo-fields.
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400199class _FIELD_BASE:
200 def __init__(self, name):
201 self.name = name
202 def __repr__(self):
203 return self.name
204_FIELD = _FIELD_BASE('_FIELD')
205_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
206_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500207
208# The name of an attribute on the class where we store the Field
Eric V. Smithf8e75492018-05-16 05:14:53 -0400209# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400210_FIELDS = '__dataclass_fields__'
211
212# The name of an attribute on the class that stores the parameters to
213# @dataclass.
214_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500215
216# The name of the function, that if it exists, is called at the end of
217# __init__.
218_POST_INIT_NAME = '__post_init__'
219
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400220# String regex that string annotations for ClassVar or InitVar must match.
221# Allows "identifier.identifier[" or "identifier[".
222# https://bugs.python.org/issue33453 for details.
223_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500224
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300225class InitVar:
Augusto Hack01ee12b2019-06-02 23:14:48 -0300226 __slots__ = ('type', )
227
228 def __init__(self, type):
229 self.type = type
230
231 def __repr__(self):
Miss Islington (bot)f1dd5ed2021-12-05 13:02:47 -0800232 if isinstance(self.type, type) and not isinstance(self.type, GenericAlias):
Samuel Colvin793cb852019-10-13 12:45:36 +0100233 type_name = self.type.__name__
234 else:
235 # typing objects, e.g. List[int]
236 type_name = repr(self.type)
237 return f'dataclasses.InitVar[{type_name}]'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500238
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300239 def __class_getitem__(cls, type):
240 return InitVar(type)
241
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500242# Instances of Field are only ever created from within this module,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400243# and only from the field() function, although Field instances are
244# exposed externally as (conceptually) read-only objects.
245#
246# name and type are filled in after the fact, not in __init__.
247# They're not known at the time this class is instantiated, but it's
248# convenient if they're available later.
249#
Eric V. Smithf199bc62018-03-18 20:40:34 -0400250# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf8e75492018-05-16 05:14:53 -0400251# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500252class Field:
253 __slots__ = ('name',
254 'type',
255 'default',
256 'default_factory',
257 'repr',
258 'hash',
259 'init',
260 'compare',
261 'metadata',
Eric V. Smithc0280532021-04-25 20:42:39 -0400262 'kw_only',
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500263 '_field_type', # Private: not to be used by user code.
264 )
265
266 def __init__(self, default, default_factory, init, repr, hash, compare,
Eric V. Smithc0280532021-04-25 20:42:39 -0400267 metadata, kw_only):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500268 self.name = None
269 self.type = None
270 self.default = default
271 self.default_factory = default_factory
272 self.init = init
273 self.repr = repr
274 self.hash = hash
275 self.compare = compare
276 self.metadata = (_EMPTY_METADATA
Christopher Huntb01786c2019-02-12 06:50:49 -0500277 if metadata is None else
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500278 types.MappingProxyType(metadata))
Eric V. Smithc0280532021-04-25 20:42:39 -0400279 self.kw_only = kw_only
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500280 self._field_type = None
281
282 def __repr__(self):
283 return ('Field('
284 f'name={self.name!r},'
Eric V. Smith2473eea2018-05-14 11:37:28 -0400285 f'type={self.type!r},'
286 f'default={self.default!r},'
287 f'default_factory={self.default_factory!r},'
288 f'init={self.init!r},'
289 f'repr={self.repr!r},'
290 f'hash={self.hash!r},'
291 f'compare={self.compare!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400292 f'metadata={self.metadata!r},'
Eric V. Smithc0280532021-04-25 20:42:39 -0400293 f'kw_only={self.kw_only!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400294 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500295 ')')
296
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400297 # This is used to support the PEP 487 __set_name__ protocol in the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400298 # case where we're using a field that contains a descriptor as a
Artjome55ca3f2018-07-06 02:09:13 +0300299 # default value. For details on __set_name__, see
Eric V. Smithf8e75492018-05-16 05:14:53 -0400300 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
301 #
302 # Note that in _process_class, this Field object is overwritten
303 # with the default value, so the end result is a descriptor that
304 # had __set_name__ called on it at the right time.
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400305 def __set_name__(self, owner, name):
Eric V. Smith52199522018-03-29 11:07:48 -0400306 func = getattr(type(self.default), '__set_name__', None)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400307 if func:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400308 # There is a __set_name__ method on the descriptor, call
309 # it.
Eric V. Smith52199522018-03-29 11:07:48 -0400310 func(self.default, owner, name)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400311
Ethan Smithd01628e2020-04-14 16:14:15 -0700312 __class_getitem__ = classmethod(GenericAlias)
313
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500314
Eric V. Smithf199bc62018-03-18 20:40:34 -0400315class _DataclassParams:
316 __slots__ = ('init',
317 'repr',
318 'eq',
319 'order',
320 'unsafe_hash',
321 'frozen',
322 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400323
Eric V. Smithf199bc62018-03-18 20:40:34 -0400324 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
325 self.init = init
326 self.repr = repr
327 self.eq = eq
328 self.order = order
329 self.unsafe_hash = unsafe_hash
330 self.frozen = frozen
331
332 def __repr__(self):
333 return ('_DataclassParams('
Eric V. Smith30590422018-05-14 17:16:52 -0400334 f'init={self.init!r},'
335 f'repr={self.repr!r},'
336 f'eq={self.eq!r},'
337 f'order={self.order!r},'
338 f'unsafe_hash={self.unsafe_hash!r},'
339 f'frozen={self.frozen!r}'
Eric V. Smithf199bc62018-03-18 20:40:34 -0400340 ')')
341
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400342
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500343# This function is used instead of exposing Field creation directly,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400344# so that a type checker can be told (via overloads) that this is a
345# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500346def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithc0280532021-04-25 20:42:39 -0400347 hash=None, compare=True, metadata=None, kw_only=MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500348 """Return an object to identify dataclass fields.
349
Eric V. Smithf8e75492018-05-16 05:14:53 -0400350 default is the default value of the field. default_factory is a
351 0-argument function called to initialize a field's value. If init
Eric V. Smithc0280532021-04-25 20:42:39 -0400352 is true, the field will be a parameter to the class's __init__()
353 function. If repr is true, the field will be included in the
354 object's repr(). If hash is true, the field will be included in the
355 object's hash(). If compare is true, the field will be used in
356 comparison functions. metadata, if specified, must be a mapping
357 which is stored but not otherwise examined by dataclass. If kw_only
358 is true, the field will become a keyword-only parameter to
359 __init__().
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500360
361 It is an error to specify both default and default_factory.
362 """
363
Eric V. Smith03220fd2017-12-29 13:59:58 -0500364 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500365 raise ValueError('cannot specify both default and default_factory')
366 return Field(default, default_factory, init, repr, hash, compare,
Eric V. Smithc0280532021-04-25 20:42:39 -0400367 metadata, kw_only)
368
369
370def _fields_in_init_order(fields):
371 # Returns the fields as __init__ will output them. It returns 2 tuples:
372 # the first for normal args, and the second for keyword args.
373
374 return (tuple(f for f in fields if f.init and not f.kw_only),
375 tuple(f for f in fields if f.init and f.kw_only)
376 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500377
378
379def _tuple_str(obj_name, fields):
380 # Return a string representing each field of obj_name as a tuple
Eric V. Smithf8e75492018-05-16 05:14:53 -0400381 # member. So, if fields is ['x', 'y'] and obj_name is "self",
382 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500383
384 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500385 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500386 return '()'
387 # Note the trailing comma, needed if this turns out to be a 1-tuple.
388 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
389
390
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530391# This function's logic is copied from "recursive_repr" function in
392# reprlib module to avoid dependency.
393def _recursive_repr(user_function):
394 # Decorator to make a repr function return "..." for a recursive
395 # call.
396 repr_running = set()
397
398 @functools.wraps(user_function)
399 def wrapper(self):
400 key = id(self), _thread.get_ident()
401 if key in repr_running:
402 return '...'
403 repr_running.add(key)
404 try:
405 result = user_function(self)
406 finally:
407 repr_running.discard(key)
408 return result
409 return wrapper
410
411
Eric V. Smithea8fc522018-01-27 19:07:40 -0500412def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500413 return_type=MISSING):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400414 # Note that we mutate locals when exec() is called. Caller
415 # beware! The only callers are internal to this module, so no
416 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500417 if locals is None:
418 locals = {}
Yury Selivanovd219cc42019-12-09 09:54:20 -0500419 if 'BUILTINS' not in locals:
420 locals['BUILTINS'] = builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500421 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500422 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500423 locals['_return_type'] = return_type
424 return_annotation = '->_return_type'
425 args = ','.join(args)
Yury Selivanovd219cc42019-12-09 09:54:20 -0500426 body = '\n'.join(f' {b}' for b in body)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500427
Eric V. Smithf199bc62018-03-18 20:40:34 -0400428 # Compute the text of the entire function.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500429 txt = f' def {name}({args}){return_annotation}:\n{body}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500430
Yury Selivanovd219cc42019-12-09 09:54:20 -0500431 local_vars = ', '.join(locals.keys())
432 txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
Yury Selivanovd219cc42019-12-09 09:54:20 -0500433 ns = {}
434 exec(txt, globals, ns)
Pablo Galindob0544ba2021-04-21 12:41:19 +0100435 return ns['__create_fn__'](**locals)
436
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500437
438def _field_assign(frozen, name, value, self_name):
439 # If we're a frozen class, then assign to our fields in __init__
Eric V. Smithf8e75492018-05-16 05:14:53 -0400440 # via object.__setattr__. Otherwise, just use a simple
441 # assignment.
442 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500443 # self_name is what "self" is called in this function: don't
Eric V. Smithf8e75492018-05-16 05:14:53 -0400444 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500445 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500446 return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500447 return f'{self_name}.{name}={value}'
448
449
Miss Islington (bot)10343bd2021-11-22 05:47:41 -0800450def _field_init(f, frozen, globals, self_name, slots):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500451 # Return the text of the line in the body of __init__ that will
Eric V. Smithf8e75492018-05-16 05:14:53 -0400452 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500453
454 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500455 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500456 if f.init:
457 # This field has a default factory. If a parameter is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400458 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500459 globals[default_name] = f.default_factory
460 value = (f'{default_name}() '
461 f'if {f.name} is _HAS_DEFAULT_FACTORY '
462 f'else {f.name}')
463 else:
464 # This is a field that's not in the __init__ params, but
Eric V. Smithf8e75492018-05-16 05:14:53 -0400465 # has a default factory function. It needs to be
466 # initialized here by calling the factory function,
467 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500468
469 # For a field initialized with a default=defaultvalue, the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400470 # class dict just has the default value
471 # (cls.fieldname=defaultvalue). But that won't work for a
472 # default factory, the factory must be called in __init__
473 # and we must assign that to self.fieldname. We can't
474 # fall back to the class dict's value, both because it's
475 # not set, and because it might be different per-class
476 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500477
478 globals[default_name] = f.default_factory
479 value = f'{default_name}()'
480 else:
481 # No default factory.
482 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500483 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500484 # There's no default, just do an assignment.
485 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500486 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500487 globals[default_name] = f.default
488 value = f.name
489 else:
Miss Islington (bot)10343bd2021-11-22 05:47:41 -0800490 # If the class has slots, then initialize this field.
491 if slots and f.default is not MISSING:
492 globals[default_name] = f.default
493 value = default_name
494 else:
495 # This field does not need initialization: reading from it will
496 # just use the class attribute that contains the default.
497 # Signify that to the caller by returning None.
498 return None
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500499
500 # Only test this now, so that we can create variables for the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400501 # default. However, return None to signify that we're not going
502 # to actually do the assignment statement for InitVars.
Eric V. Smithe7adf2b2018-06-07 14:43:59 -0400503 if f._field_type is _FIELD_INITVAR:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500504 return None
505
506 # Now, actually generate the field assignment.
507 return _field_assign(frozen, f.name, value, self_name)
508
509
510def _init_param(f):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400511 # Return the __init__ parameter string for this field. For
512 # example, the equivalent of 'x:int=3' (except instead of 'int',
513 # reference a variable set to int, and instead of '3', reference a
514 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500515 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400516 # There's no default, and no default_factory, just output the
517 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500518 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500519 elif f.default is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400520 # There's a default, this will be the name that's used to look
521 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500522 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500523 elif f.default_factory is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400524 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500525 default = '=_HAS_DEFAULT_FACTORY'
526 return f'{f.name}:_type_{f.name}{default}'
527
528
Eric V. Smithc0280532021-04-25 20:42:39 -0400529def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,
Miss Islington (bot)10343bd2021-11-22 05:47:41 -0800530 self_name, globals, slots):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500531 # fields contains both real fields and InitVar pseudo-fields.
532
533 # Make sure we don't have fields without defaults following fields
Eric V. Smithf8e75492018-05-16 05:14:53 -0400534 # with defaults. This actually would be caught when exec-ing the
535 # function source code, but catching it here gives a better error
536 # message, and future-proofs us in case we build up the function
537 # using ast.
Eric V. Smithc0280532021-04-25 20:42:39 -0400538
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500539 seen_default = False
Eric V. Smithc0280532021-04-25 20:42:39 -0400540 for f in std_fields:
541 # Only consider the non-kw-only fields in the __init__ call.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500542 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500543 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500544 seen_default = True
545 elif seen_default:
546 raise TypeError(f'non-default argument {f.name!r} '
547 'follows default argument')
548
Yury Selivanovd219cc42019-12-09 09:54:20 -0500549 locals = {f'_type_{f.name}': f.type for f in fields}
550 locals.update({
551 'MISSING': MISSING,
552 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
553 })
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500554
555 body_lines = []
556 for f in fields:
Miss Islington (bot)10343bd2021-11-22 05:47:41 -0800557 line = _field_init(f, frozen, locals, self_name, slots)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400558 # line is None means that this field doesn't require
Eric V. Smithf8e75492018-05-16 05:14:53 -0400559 # initialization (it's a pseudo-field). Just skip it.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400560 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500561 body_lines.append(line)
562
563 # Does this class have a post-init function?
564 if has_post_init:
565 params_str = ','.join(f.name for f in fields
566 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400567 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500568
569 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500570 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500571 body_lines = ['pass']
572
Eric V. Smithc0280532021-04-25 20:42:39 -0400573 _init_params = [_init_param(f) for f in std_fields]
574 if kw_only_fields:
575 # Add the keyword-only args. Because the * can only be added if
576 # there's at least one keyword-only arg, there needs to be a test here
577 # (instead of just concatenting the lists together).
578 _init_params += ['*']
579 _init_params += [_init_param(f) for f in kw_only_fields]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500580 return _create_fn('__init__',
Eric V. Smithc0280532021-04-25 20:42:39 -0400581 [self_name] + _init_params,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500582 body_lines,
583 locals=locals,
584 globals=globals,
585 return_type=None)
586
587
Yury Selivanovd219cc42019-12-09 09:54:20 -0500588def _repr_fn(fields, globals):
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530589 fn = _create_fn('__repr__',
590 ('self',),
591 ['return self.__class__.__qualname__ + f"(' +
592 ', '.join([f"{f.name}={{self.{f.name}!r}}"
593 for f in fields]) +
Yury Selivanovd219cc42019-12-09 09:54:20 -0500594 ')"'],
595 globals=globals)
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530596 return _recursive_repr(fn)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500597
598
Yury Selivanovd219cc42019-12-09 09:54:20 -0500599def _frozen_get_del_attr(cls, fields, globals):
600 locals = {'cls': cls,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400601 'FrozenInstanceError': FrozenInstanceError}
602 if fields:
603 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
604 else:
605 # Special case for the zero-length tuple.
606 fields_str = '()'
607 return (_create_fn('__setattr__',
608 ('self', 'name', 'value'),
609 (f'if type(self) is cls or name in {fields_str}:',
610 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
611 f'super(cls, self).__setattr__(name, value)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500612 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400613 globals=globals),
614 _create_fn('__delattr__',
615 ('self', 'name'),
616 (f'if type(self) is cls or name in {fields_str}:',
617 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
618 f'super(cls, self).__delattr__(name)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500619 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400620 globals=globals),
621 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500622
623
Yury Selivanovd219cc42019-12-09 09:54:20 -0500624def _cmp_fn(name, op, self_tuple, other_tuple, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500625 # Create a comparison function. If the fields in the object are
Eric V. Smithf8e75492018-05-16 05:14:53 -0400626 # named 'x' and 'y', then self_tuple is the string
627 # '(self.x,self.y)' and other_tuple is the string
628 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500629
630 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400631 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500632 [ 'if other.__class__ is self.__class__:',
633 f' return {self_tuple}{op}{other_tuple}',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500634 'return NotImplemented'],
635 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500636
637
Yury Selivanovd219cc42019-12-09 09:54:20 -0500638def _hash_fn(fields, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500639 self_tuple = _tuple_str('self', fields)
640 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400641 ('self',),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500642 [f'return hash({self_tuple})'],
643 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500644
645
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400646def _is_classvar(a_type, typing):
Eric V. Smith92858352018-05-16 07:24:00 -0400647 # This test uses a typing internal class, but it's the best way to
648 # test if this is a ClassVar.
649 return (a_type is typing.ClassVar
650 or (type(a_type) is typing._GenericAlias
651 and a_type.__origin__ is typing.ClassVar))
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400652
653
654def _is_initvar(a_type, dataclasses):
655 # The module we're checking against is the module we're
656 # currently in (dataclasses.py).
Augusto Hack01ee12b2019-06-02 23:14:48 -0300657 return (a_type is dataclasses.InitVar
658 or type(a_type) is dataclasses.InitVar)
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400659
Eric V. Smithc0280532021-04-25 20:42:39 -0400660def _is_kw_only(a_type, dataclasses):
661 return a_type is dataclasses.KW_ONLY
662
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400663
664def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
665 # Given a type annotation string, does it refer to a_type in
666 # a_module? For example, when checking that annotation denotes a
667 # ClassVar, then a_module is typing, and a_type is
668 # typing.ClassVar.
669
670 # It's possible to look up a_module given a_type, but it involves
671 # looking in sys.modules (again!), and seems like a waste since
672 # the caller already knows a_module.
673
674 # - annotation is a string type annotation
675 # - cls is the class that this annotation was found in
676 # - a_module is the module we want to match
677 # - a_type is the type in that module we want to match
678 # - is_type_predicate is a function called with (obj, a_module)
679 # that determines if obj is of the desired type.
680
681 # Since this test does not do a local namespace lookup (and
682 # instead only a module (global) lookup), there are some things it
683 # gets wrong.
684
Eric V. Smithf8e75492018-05-16 05:14:53 -0400685 # With string annotations, cv0 will be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400686 # CV = ClassVar
687 # @dataclass
688 # class C0:
689 # cv0: CV
690
Eric V. Smithf8e75492018-05-16 05:14:53 -0400691 # But in this example cv1 will not be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400692 # @dataclass
693 # class C1:
694 # CV = ClassVar
695 # cv1: CV
696
Eric V. Smithf8e75492018-05-16 05:14:53 -0400697 # In C1, the code in this function (_is_type) will look up "CV" in
698 # the module and not find it, so it will not consider cv1 as a
699 # ClassVar. This is a fairly obscure corner case, and the best
700 # way to fix it would be to eval() the string "CV" with the
701 # correct global and local namespaces. However that would involve
702 # a eval() penalty for every single field of every dataclass
703 # that's defined. It was judged not worth it.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400704
705 match = _MODULE_IDENTIFIER_RE.match(annotation)
706 if match:
707 ns = None
708 module_name = match.group(1)
709 if not module_name:
710 # No module name, assume the class's module did
711 # "from dataclasses import InitVar".
712 ns = sys.modules.get(cls.__module__).__dict__
713 else:
714 # Look up module_name in the class's module.
715 module = sys.modules.get(cls.__module__)
716 if module and module.__dict__.get(module_name) is a_module:
717 ns = sys.modules.get(a_type.__module__).__dict__
718 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
719 return True
720 return False
721
722
Eric V. Smithc0280532021-04-25 20:42:39 -0400723def _get_field(cls, a_name, a_type, default_kw_only):
724 # Return a Field object for this field name and type. ClassVars and
725 # InitVars are also returned, but marked as such (see f._field_type).
726 # default_kw_only is the value of kw_only to use if there isn't a field()
727 # that defines it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500728
Eric V. Smithf8e75492018-05-16 05:14:53 -0400729 # If the default value isn't derived from Field, then it's only a
730 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500731 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500732 if isinstance(default, Field):
733 f = default
734 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400735 if isinstance(default, types.MemberDescriptorType):
736 # This is a field in __slots__, so it has no default value.
737 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500738 f = field(default=default)
739
Eric V. Smithf8e75492018-05-16 05:14:53 -0400740 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500741 f.name = a_name
742 f.type = a_type
743
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400744 # Assume it's a normal field until proven otherwise. We're next
Eric V. Smithf8e75492018-05-16 05:14:53 -0400745 # going to decide if it's a ClassVar or InitVar, everything else
746 # is just a normal field.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400747 f._field_type = _FIELD
748
749 # In addition to checking for actual types here, also check for
Eric V. Smithf8e75492018-05-16 05:14:53 -0400750 # string annotations. get_type_hints() won't always work for us
751 # (see https://github.com/python/typing/issues/508 for example),
Eric V. Smith76beadb2021-04-17 09:53:24 -0400752 # plus it's expensive and would require an eval for every string
Eric V. Smithf8e75492018-05-16 05:14:53 -0400753 # annotation. So, make a best effort to see if this is a ClassVar
754 # or InitVar using regex's and checking that the thing referenced
755 # is actually of the correct type.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400756
757 # For the complete discussion, see https://bugs.python.org/issue33453
758
759 # If typing has not been imported, then it's impossible for any
Eric V. Smithf8e75492018-05-16 05:14:53 -0400760 # annotation to be a ClassVar. So, only look for ClassVar if
761 # typing has been imported by any module (not necessarily cls's
762 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500763 typing = sys.modules.get('typing')
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400764 if typing:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400765 if (_is_classvar(a_type, typing)
766 or (isinstance(f.type, str)
767 and _is_type(f.type, cls, typing, typing.ClassVar,
768 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500769 f._field_type = _FIELD_CLASSVAR
770
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400771 # If the type is InitVar, or if it's a matching string annotation,
772 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500773 if f._field_type is _FIELD:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400774 # The module we're checking against is the module we're
775 # currently in (dataclasses.py).
776 dataclasses = sys.modules[__name__]
777 if (_is_initvar(a_type, dataclasses)
778 or (isinstance(f.type, str)
779 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
780 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500781 f._field_type = _FIELD_INITVAR
782
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400783 # Validations for individual fields. This is delayed until now,
784 # instead of in the Field() constructor, since only here do we
785 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500786
787 # Special restrictions for ClassVar and InitVar.
788 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500789 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500790 raise TypeError(f'field {f.name} cannot have a '
791 'default factory')
792 # Should I check for other field settings? default_factory
Eric V. Smithf8e75492018-05-16 05:14:53 -0400793 # seems the most serious to check for. Maybe add others. For
794 # example, how about init=False (or really,
795 # init=<not-the-default-init-value>)? It makes no sense for
796 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500797
Eric V. Smithc0280532021-04-25 20:42:39 -0400798 # kw_only validation and assignment.
799 if f._field_type in (_FIELD, _FIELD_INITVAR):
800 # For real and InitVar fields, if kw_only wasn't specified use the
801 # default value.
802 if f.kw_only is MISSING:
803 f.kw_only = default_kw_only
804 else:
805 # Make sure kw_only isn't set for ClassVars
806 assert f._field_type is _FIELD_CLASSVAR
807 if f.kw_only is not MISSING:
808 raise TypeError(f'field {f.name} is a ClassVar but specifies '
809 'kw_only')
810
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500811 # For real fields, disallow mutable defaults for known types.
812 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
813 raise ValueError(f'mutable default {type(f.default)} for field '
814 f'{f.name} is not allowed: use default_factory')
815
816 return f
817
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300818def _set_qualname(cls, value):
819 # Ensure that the functions returned from _create_fn uses the proper
820 # __qualname__ (the class they belong to).
821 if isinstance(value, FunctionType):
822 value.__qualname__ = f"{cls.__qualname__}.{value.__name__}"
823 return value
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500824
Eric V. Smithea8fc522018-01-27 19:07:40 -0500825def _set_new_attribute(cls, name, value):
826 # Never overwrites an existing attribute. Returns True if the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400827 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500828 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500829 return True
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300830 _set_qualname(cls, value)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500831 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500832 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500833
834
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500835# Decide if/how we're going to create a hash function. Key is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400836# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
837# take. The common case is to do nothing, so instead of providing a
838# function that is a no-op, use None to signify that.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400839
Yury Selivanovd219cc42019-12-09 09:54:20 -0500840def _hash_set_none(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400841 return None
842
Yury Selivanovd219cc42019-12-09 09:54:20 -0500843def _hash_add(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400844 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300845 return _set_qualname(cls, _hash_fn(flds, globals))
Eric V. Smith01d618c2018-03-24 22:10:14 -0400846
Yury Selivanovd219cc42019-12-09 09:54:20 -0500847def _hash_exception(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400848 # Raise an exception.
849 raise TypeError(f'Cannot overwrite attribute __hash__ '
850 f'in class {cls.__name__}')
851
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500852#
853# +-------------------------------------- unsafe_hash?
854# | +------------------------------- eq?
855# | | +------------------------ frozen?
856# | | | +---------------- has-explicit-hash?
857# | | | |
858# | | | | +------- action
859# | | | | |
860# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400861_hash_action = {(False, False, False, False): None,
862 (False, False, False, True ): None,
863 (False, False, True, False): None,
864 (False, False, True, True ): None,
865 (False, True, False, False): _hash_set_none,
866 (False, True, False, True ): None,
867 (False, True, True, False): _hash_add,
868 (False, True, True, True ): None,
869 (True, False, False, False): _hash_add,
870 (True, False, False, True ): _hash_exception,
871 (True, False, True, False): _hash_add,
872 (True, False, True, True ): _hash_exception,
873 (True, True, False, False): _hash_add,
874 (True, True, False, True ): _hash_exception,
875 (True, True, True, False): _hash_add,
876 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500877 }
878# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Eric V. Smithf8e75492018-05-16 05:14:53 -0400879# version of this table.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500880
881
Eric V. Smith750f4842021-04-10 21:28:42 -0400882def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
Yurii Karabasc2419912021-05-01 05:14:30 +0300883 match_args, kw_only, slots):
Eric V. Smithd1388922018-01-07 14:30:17 -0500884 # Now that dicts retain insertion order, there's no reason to use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400885 # an ordered dict. I am leveraging that ordering here, because
886 # derived class fields overwrite base class fields, but the order
887 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500888 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500889
Yury Selivanovd219cc42019-12-09 09:54:20 -0500890 if cls.__module__ in sys.modules:
891 globals = sys.modules[cls.__module__].__dict__
892 else:
893 # Theoretically this can happen if someone writes
894 # a custom string to cls.__module__. In which case
895 # such dataclass won't be fully introspectable
896 # (w.r.t. typing.get_type_hints) but will still function
897 # correctly.
898 globals = {}
899
Eric V. Smithf199bc62018-03-18 20:40:34 -0400900 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
901 unsafe_hash, frozen))
902
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500903 # Find our base classes in reverse MRO order, and exclude
Eric V. Smithf8e75492018-05-16 05:14:53 -0400904 # ourselves. In reversed order so that more derived classes
905 # override earlier field definitions in base classes. As long as
906 # we're iterating over them, see if any are frozen.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400907 any_frozen_base = False
908 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500909 for b in cls.__mro__[-1:0:-1]:
910 # Only process classes that have been processed by our
Eric V. Smithf8e75492018-05-16 05:14:53 -0400911 # decorator. That is, they have a _FIELDS attribute.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400912 base_fields = getattr(b, _FIELDS, None)
Iurii Kemaev376ffc62021-04-06 06:14:01 +0100913 if base_fields is not None:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400914 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500915 for f in base_fields.values():
916 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400917 if getattr(b, _PARAMS).frozen:
918 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500919
Eric V. Smith56970b82018-03-22 16:28:48 -0400920 # Annotations that are defined in this class (not in base
Eric V. Smithf8e75492018-05-16 05:14:53 -0400921 # classes). If __annotations__ isn't present, then this class
922 # adds no new annotations. We use this to compute fields that are
923 # added by this class.
924 #
Eric V. Smith56970b82018-03-22 16:28:48 -0400925 # Fields are found from cls_annotations, which is guaranteed to be
Eric V. Smithf8e75492018-05-16 05:14:53 -0400926 # ordered. Default values are from class attributes, if a field
927 # has a default. If the default value is a Field(), then it
928 # contains additional info beyond (and possibly including) the
929 # actual default value. Pseudo-fields ClassVars and InitVars are
930 # included, despite the fact that they're not real fields. That's
931 # dealt with later.
Eric V. Smith56970b82018-03-22 16:28:48 -0400932 cls_annotations = cls.__dict__.get('__annotations__', {})
933
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500934 # Now find fields in our class. While doing so, validate some
Eric V. Smithf8e75492018-05-16 05:14:53 -0400935 # things, and set the default values (as class attributes) where
936 # we can.
Eric V. Smithc0280532021-04-25 20:42:39 -0400937 cls_fields = []
938 # Get a reference to this module for the _is_kw_only() test.
Eric V. Smith99ad7422021-05-03 03:24:53 -0400939 KW_ONLY_seen = False
Eric V. Smithc0280532021-04-25 20:42:39 -0400940 dataclasses = sys.modules[__name__]
941 for name, type in cls_annotations.items():
942 # See if this is a marker to change the value of kw_only.
943 if (_is_kw_only(type, dataclasses)
944 or (isinstance(type, str)
945 and _is_type(type, cls, dataclasses, dataclasses.KW_ONLY,
946 _is_kw_only))):
947 # Switch the default to kw_only=True, and ignore this
948 # annotation: it's not a real field.
Eric V. Smith99ad7422021-05-03 03:24:53 -0400949 if KW_ONLY_seen:
950 raise TypeError(f'{name!r} is KW_ONLY, but KW_ONLY '
951 'has already been specified')
952 KW_ONLY_seen = True
Eric V. Smithc0280532021-04-25 20:42:39 -0400953 kw_only = True
954 else:
955 # Otherwise it's a field of some type.
956 cls_fields.append(_get_field(cls, name, type, kw_only))
957
Eric V. Smith56970b82018-03-22 16:28:48 -0400958 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500959 fields[f.name] = f
960
Eric V. Smithf8e75492018-05-16 05:14:53 -0400961 # If the class attribute (which is the default value for this
962 # field) exists and is of type 'Field', replace it with the
963 # real default. This is so that normal class introspection
964 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500965 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500966 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500967 # If there's no default, delete the class attribute.
Eric V. Smithf8e75492018-05-16 05:14:53 -0400968 # This happens if we specify field(repr=False), for
969 # example (that is, we specified a field object, but
970 # no default value). Also if we're using a default
971 # factory. The class attribute should not be set at
972 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500973 delattr(cls, f.name)
974 else:
975 setattr(cls, f.name, f.default)
976
Eric V. Smith56970b82018-03-22 16:28:48 -0400977 # Do we have any Field members that don't also have annotations?
978 for name, value in cls.__dict__.items():
979 if isinstance(value, Field) and not name in cls_annotations:
980 raise TypeError(f'{name!r} is a field but has no type annotation')
981
Eric V. Smithf199bc62018-03-18 20:40:34 -0400982 # Check rules that apply if we are derived from any dataclasses.
983 if has_dataclass_bases:
984 # Raise an exception if any of our bases are frozen, but we're not.
985 if any_frozen_base and not frozen:
986 raise TypeError('cannot inherit non-frozen dataclass from a '
987 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500988
Eric V. Smithf199bc62018-03-18 20:40:34 -0400989 # Raise an exception if we're frozen, but none of our bases are.
990 if not any_frozen_base and frozen:
991 raise TypeError('cannot inherit frozen dataclass from a '
992 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500993
Eric V. Smithf8e75492018-05-16 05:14:53 -0400994 # Remember all of the fields on our class (including bases). This
995 # also marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400996 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500997
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500998 # Was this class defined with an explicit __hash__? Note that if
Eric V. Smithf8e75492018-05-16 05:14:53 -0400999 # __eq__ is defined in this class, then python will automatically
1000 # set __hash__ to None. This is a heuristic, as it's possible
1001 # that such a __hash__ == None was not auto-generated, but it
1002 # close enough.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001003 class_hash = cls.__dict__.get('__hash__', MISSING)
1004 has_explicit_hash = not (class_hash is MISSING or
1005 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -05001006
Eric V. Smithf8e75492018-05-16 05:14:53 -04001007 # If we're generating ordering methods, we must be generating the
1008 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001009 if order and not eq:
1010 raise ValueError('eq must be true if order is true')
1011
Eric V. Smithc0280532021-04-25 20:42:39 -04001012 # Include InitVars and regular fields (so, not ClassVars). This is
1013 # initialized here, outside of the "if init:" test, because std_init_fields
1014 # is used with match_args, below.
1015 all_init_fields = [f for f in fields.values()
1016 if f._field_type in (_FIELD, _FIELD_INITVAR)]
1017 (std_init_fields,
1018 kw_only_init_fields) = _fields_in_init_order(all_init_fields)
1019
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001020 if init:
1021 # Does this class have a post-init function?
1022 has_post_init = hasattr(cls, _POST_INIT_NAME)
1023
Eric V. Smithea8fc522018-01-27 19:07:40 -05001024 _set_new_attribute(cls, '__init__',
Eric V. Smithc0280532021-04-25 20:42:39 -04001025 _init_fn(all_init_fields,
1026 std_init_fields,
1027 kw_only_init_fields,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -05001028 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -05001029 has_post_init,
Eric V. Smithf8e75492018-05-16 05:14:53 -04001030 # The name to use for the "self"
1031 # param in __init__. Use "self"
1032 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -05001033 '__dataclass_self__' if 'self' in fields
1034 else 'self',
Yury Selivanovd219cc42019-12-09 09:54:20 -05001035 globals,
Miss Islington (bot)10343bd2021-11-22 05:47:41 -08001036 slots,
Eric V. Smithea8fc522018-01-27 19:07:40 -05001037 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001038
1039 # Get the fields as a list, and include only real fields. This is
Eric V. Smithf8e75492018-05-16 05:14:53 -04001040 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -05001041 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001042
1043 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -05001044 flds = [f for f in field_list if f.repr]
Yury Selivanovd219cc42019-12-09 09:54:20 -05001045 _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001046
1047 if eq:
Miss Islington (bot)1757ddd2021-05-28 18:07:27 -07001048 # Create __eq__ method. There's no need for a __ne__ method,
Eric V. Smithf8e75492018-05-16 05:14:53 -04001049 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -05001050 flds = [f for f in field_list if f.compare]
1051 self_tuple = _tuple_str('self', flds)
1052 other_tuple = _tuple_str('other', flds)
1053 _set_new_attribute(cls, '__eq__',
1054 _cmp_fn('__eq__', '==',
Yury Selivanovd219cc42019-12-09 09:54:20 -05001055 self_tuple, other_tuple,
1056 globals=globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001057
1058 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -05001059 # Create and set the ordering methods.
1060 flds = [f for f in field_list if f.compare]
1061 self_tuple = _tuple_str('self', flds)
1062 other_tuple = _tuple_str('other', flds)
1063 for name, op in [('__lt__', '<'),
1064 ('__le__', '<='),
1065 ('__gt__', '>'),
1066 ('__ge__', '>='),
1067 ]:
1068 if _set_new_attribute(cls, name,
Yury Selivanovd219cc42019-12-09 09:54:20 -05001069 _cmp_fn(name, op, self_tuple, other_tuple,
1070 globals=globals)):
Eric V. Smithea8fc522018-01-27 19:07:40 -05001071 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001072 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -05001073 'functools.total_ordering')
1074
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -05001075 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -05001076 for fn in _frozen_get_del_attr(cls, field_list, globals):
Eric V. Smithf199bc62018-03-18 20:40:34 -04001077 if _set_new_attribute(cls, fn.__name__, fn):
1078 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001079 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -05001080
1081 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001082 hash_action = _hash_action[bool(unsafe_hash),
1083 bool(eq),
1084 bool(frozen),
1085 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -04001086 if hash_action:
1087 # No need to call _set_new_attribute here, since by the time
Eric V. Smithf8e75492018-05-16 05:14:53 -04001088 # we're here the overwriting is unconditional.
Yury Selivanovd219cc42019-12-09 09:54:20 -05001089 cls.__hash__ = hash_action(cls, field_list, globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001090
1091 if not getattr(cls, '__doc__'):
1092 # Create a class doc-string.
1093 cls.__doc__ = (cls.__name__ +
Pablo Galindob0544ba2021-04-21 12:41:19 +01001094 str(inspect.signature(cls)).replace(' -> None', ''))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001095
Eric V. Smith750f4842021-04-10 21:28:42 -04001096 if match_args:
Eric V. Smithc0280532021-04-25 20:42:39 -04001097 # I could probably compute this once
Eric V. Smith750f4842021-04-10 21:28:42 -04001098 _set_new_attribute(cls, '__match_args__',
Eric V. Smithc0280532021-04-25 20:42:39 -04001099 tuple(f.name for f in std_init_fields))
Brandt Bucher145bf262021-02-26 14:51:55 -08001100
Yurii Karabasc2419912021-05-01 05:14:30 +03001101 if slots:
Eric V. Smith823fbf42021-05-01 13:27:30 -04001102 cls = _add_slots(cls, frozen)
Yurii Karabasc2419912021-05-01 05:14:30 +03001103
Ben Avrahamibef7d292020-10-06 20:40:50 +03001104 abc.update_abstractmethods(cls)
1105
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001106 return cls
1107
1108
Eric V. Smith823fbf42021-05-01 13:27:30 -04001109# _dataclass_getstate and _dataclass_setstate are needed for pickling frozen
1110# classes with slots. These could be slighly more performant if we generated
1111# the code instead of iterating over fields. But that can be a project for
1112# another day, if performance becomes an issue.
1113def _dataclass_getstate(self):
1114 return [getattr(self, f.name) for f in fields(self)]
1115
1116
1117def _dataclass_setstate(self, state):
1118 for field, value in zip(fields(self), state):
1119 # use setattr because dataclass may be frozen
1120 object.__setattr__(self, field.name, value)
1121
1122
1123def _add_slots(cls, is_frozen):
Yurii Karabasc2419912021-05-01 05:14:30 +03001124 # Need to create a new class, since we can't set __slots__
1125 # after a class has been created.
1126
1127 # Make sure __slots__ isn't already set.
1128 if '__slots__' in cls.__dict__:
1129 raise TypeError(f'{cls.__name__} already specifies __slots__')
1130
1131 # Create a new dict for our new class.
1132 cls_dict = dict(cls.__dict__)
1133 field_names = tuple(f.name for f in fields(cls))
1134 cls_dict['__slots__'] = field_names
1135 for field_name in field_names:
1136 # Remove our attributes, if present. They'll still be
1137 # available in _MARKER.
1138 cls_dict.pop(field_name, None)
1139
1140 # Remove __dict__ itself.
1141 cls_dict.pop('__dict__', None)
1142
1143 # And finally create the class.
1144 qualname = getattr(cls, '__qualname__', None)
1145 cls = type(cls)(cls.__name__, cls.__bases__, cls_dict)
1146 if qualname is not None:
1147 cls.__qualname__ = qualname
1148
Eric V. Smith823fbf42021-05-01 13:27:30 -04001149 if is_frozen:
1150 # Need this for pickling frozen classes with slots.
1151 cls.__getstate__ = _dataclass_getstate
1152 cls.__setstate__ = _dataclass_setstate
1153
Yurii Karabasc2419912021-05-01 05:14:30 +03001154 return cls
1155
1156
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001157def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
Eric V. Smithc0280532021-04-25 20:42:39 -04001158 unsafe_hash=False, frozen=False, match_args=True,
Yurii Karabasc2419912021-05-01 05:14:30 +03001159 kw_only=False, slots=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001160 """Returns the same class as was passed in, with dunder methods
1161 added based on the fields defined in the class.
1162
1163 Examines PEP 526 __annotations__ to determine fields.
1164
1165 If init is true, an __init__() method is added to the class. If
1166 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001167 comparison dunder methods are added. If unsafe_hash is true, a
1168 __hash__() method function is added. If frozen is true, fields may
Eric V. Smith750f4842021-04-10 21:28:42 -04001169 not be assigned to after instance creation. If match_args is true,
Eric V. Smithc0280532021-04-25 20:42:39 -04001170 the __match_args__ tuple is added. If kw_only is true, then by
Yurii Karabasc2419912021-05-01 05:14:30 +03001171 default all fields are keyword-only. If slots is true, an
1172 __slots__ attribute is added.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001173 """
1174
1175 def wrap(cls):
Eric V. Smith750f4842021-04-10 21:28:42 -04001176 return _process_class(cls, init, repr, eq, order, unsafe_hash,
Yurii Karabasc2419912021-05-01 05:14:30 +03001177 frozen, match_args, kw_only, slots)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001178
1179 # See if we're being called as @dataclass or @dataclass().
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001180 if cls is None:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001181 # We're called with parens.
1182 return wrap
1183
1184 # We're called as @dataclass without parens.
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001185 return wrap(cls)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001186
1187
1188def fields(class_or_instance):
1189 """Return a tuple describing the fields of this dataclass.
1190
1191 Accepts a dataclass or an instance of one. Tuple elements are of
1192 type Field.
1193 """
1194
1195 # Might it be worth caching this, per class?
1196 try:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001197 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001198 except AttributeError:
1199 raise TypeError('must be called with a dataclass type or instance')
1200
Eric V. Smithd1388922018-01-07 14:30:17 -05001201 # Exclude pseudo-fields. Note that fields is sorted by insertion
Eric V. Smithf8e75492018-05-16 05:14:53 -04001202 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001203 return tuple(f for f in fields.values() if f._field_type is _FIELD)
1204
1205
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001206def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001207 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001208 return hasattr(type(obj), _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001209
1210
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001211def is_dataclass(obj):
1212 """Returns True if obj is a dataclass or an instance of a
1213 dataclass."""
Miss Islington (bot)abceb662021-12-05 13:04:29 -08001214 cls = obj if isinstance(obj, type) and not isinstance(obj, GenericAlias) else type(obj)
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001215 return hasattr(cls, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001216
1217
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001218def asdict(obj, *, dict_factory=dict):
1219 """Return the fields of a dataclass instance as a new dictionary mapping
1220 field names to field values.
1221
1222 Example usage:
1223
1224 @dataclass
1225 class C:
1226 x: int
1227 y: int
1228
1229 c = C(1, 2)
1230 assert asdict(c) == {'x': 1, 'y': 2}
1231
1232 If given, 'dict_factory' will be used instead of built-in dict.
1233 The function applies recursively to field values that are
1234 dataclass instances. This will also look into built-in containers:
1235 tuples, lists, and dicts.
1236 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001237 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001238 raise TypeError("asdict() should be called on dataclass instances")
1239 return _asdict_inner(obj, dict_factory)
1240
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001241
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001242def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001243 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001244 result = []
1245 for f in fields(obj):
1246 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1247 result.append((f.name, value))
1248 return dict_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001249 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1250 # obj is a namedtuple. Recurse into it, but the returned
1251 # object is another namedtuple of the same type. This is
1252 # similar to how other list- or tuple-derived classes are
1253 # treated (see below), but we just need to create them
1254 # differently because a namedtuple's __init__ needs to be
1255 # called differently (see bpo-34363).
1256
1257 # I'm not using namedtuple's _asdict()
1258 # method, because:
1259 # - it does not recurse in to the namedtuple fields and
1260 # convert them to dicts (using dict_factory).
Jürgen Gmach80526f62020-06-24 12:46:52 +02001261 # - I don't actually want to return a dict here. The main
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001262 # use case here is json.dumps, and it handles converting
1263 # namedtuples to lists. Admittedly we're losing some
1264 # information here when we produce a json list instead of a
1265 # dict. Note that if we returned dicts here instead of
1266 # namedtuples, we could no longer call asdict() on a data
1267 # structure where a namedtuple was used as a dict key.
1268
1269 return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001270 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001271 # Assume we can create an object of this type by passing in a
1272 # generator (which is not true for namedtuples, handled
1273 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001274 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1275 elif isinstance(obj, dict):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001276 return type(obj)((_asdict_inner(k, dict_factory),
1277 _asdict_inner(v, dict_factory))
1278 for k, v in obj.items())
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001279 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001280 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001281
1282
1283def astuple(obj, *, tuple_factory=tuple):
1284 """Return the fields of a dataclass instance as a new tuple of field values.
1285
1286 Example usage::
1287
1288 @dataclass
1289 class C:
1290 x: int
1291 y: int
1292
1293 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001294 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001295
1296 If given, 'tuple_factory' will be used instead of built-in tuple.
1297 The function applies recursively to field values that are
1298 dataclass instances. This will also look into built-in containers:
1299 tuples, lists, and dicts.
1300 """
1301
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001302 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001303 raise TypeError("astuple() should be called on dataclass instances")
1304 return _astuple_inner(obj, tuple_factory)
1305
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001306
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001307def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001308 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001309 result = []
1310 for f in fields(obj):
1311 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1312 result.append(value)
1313 return tuple_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001314 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1315 # obj is a namedtuple. Recurse into it, but the returned
1316 # object is another namedtuple of the same type. This is
1317 # similar to how other list- or tuple-derived classes are
1318 # treated (see below), but we just need to create them
1319 # differently because a namedtuple's __init__ needs to be
1320 # called differently (see bpo-34363).
1321 return type(obj)(*[_astuple_inner(v, tuple_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001322 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001323 # Assume we can create an object of this type by passing in a
1324 # generator (which is not true for namedtuples, handled
1325 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001326 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1327 elif isinstance(obj, dict):
1328 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1329 for k, v in obj.items())
1330 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001331 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001332
1333
Eric V. Smithd80b4432018-01-06 17:09:58 -05001334def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001335 repr=True, eq=True, order=False, unsafe_hash=False,
Miss Islington (bot)cf8c8782021-11-20 15:46:56 -08001336 frozen=False, match_args=True, kw_only=False, slots=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001337 """Return a new dynamically created dataclass.
1338
Eric V. Smithed7d4292018-01-06 16:14:03 -05001339 The dataclass name will be 'cls_name'. 'fields' is an iterable
1340 of either (name), (name, type) or (name, type, Field) objects. If type is
1341 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001342 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001343
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001344 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001345
1346 is equivalent to:
1347
1348 @dataclass
1349 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001350 x: 'typing.Any'
1351 y: int
1352 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001353
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001354 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001355
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001356 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001357 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001358 """
1359
1360 if namespace is None:
1361 namespace = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001362
Eric V. Smith4e812962018-05-16 11:31:29 -04001363 # While we're looking through the field names, validate that they
1364 # are identifiers, are not keywords, and not duplicates.
1365 seen = set()
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001366 annotations = {}
1367 defaults = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001368 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001369 if isinstance(item, str):
1370 name = item
1371 tp = 'typing.Any'
1372 elif len(item) == 2:
1373 name, tp, = item
1374 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001375 name, tp, spec = item
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001376 defaults[name] = spec
Eric V. Smith4e812962018-05-16 11:31:29 -04001377 else:
1378 raise TypeError(f'Invalid field: {item!r}')
1379
1380 if not isinstance(name, str) or not name.isidentifier():
Min ho Kim96e12d52019-07-22 06:12:33 +10001381 raise TypeError(f'Field names must be valid identifiers: {name!r}')
Eric V. Smith4e812962018-05-16 11:31:29 -04001382 if keyword.iskeyword(name):
1383 raise TypeError(f'Field names must not be keywords: {name!r}')
1384 if name in seen:
1385 raise TypeError(f'Field name duplicated: {name!r}')
1386
1387 seen.add(name)
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001388 annotations[name] = tp
Eric V. Smithed7d4292018-01-06 16:14:03 -05001389
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001390 # Update 'ns' with the user-supplied namespace plus our calculated values.
1391 def exec_body_callback(ns):
1392 ns.update(namespace)
1393 ns.update(defaults)
1394 ns['__annotations__'] = annotations
1395
Ivan Levkivskyi5a7092d2018-03-31 13:41:17 +01001396 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
Miss Islington (bot)e086bfe2021-10-09 12:50:45 -07001397 # of generic dataclasses.
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001398 cls = types.new_class(cls_name, bases, {}, exec_body_callback)
1399
1400 # Apply the normal decorator.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001401 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smith750f4842021-04-10 21:28:42 -04001402 unsafe_hash=unsafe_hash, frozen=frozen,
Miss Islington (bot)cf8c8782021-11-20 15:46:56 -08001403 match_args=match_args, kw_only=kw_only, slots=slots)
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001404
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001405
Serhiy Storchaka2d88e632019-06-26 19:07:44 +03001406def replace(obj, /, **changes):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001407 """Return a new object replacing specified fields with new values.
1408
1409 This is especially useful for frozen classes. Example usage:
1410
1411 @dataclass(frozen=True)
1412 class C:
1413 x: int
1414 y: int
1415
1416 c = C(1, 2)
1417 c1 = replace(c, x=3)
1418 assert c1.x == 3 and c1.y == 2
1419 """
1420
Eric V. Smithf8e75492018-05-16 05:14:53 -04001421 # We're going to mutate 'changes', but that's okay because it's a
1422 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001423
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001424 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001425 raise TypeError("replace() should be called on dataclass instances")
1426
1427 # It's an error to have init=False fields in 'changes'.
1428 # If a field is not in 'changes', read its value from the provided obj.
1429
Eric V. Smithf199bc62018-03-18 20:40:34 -04001430 for f in getattr(obj, _FIELDS).values():
Eric V. Smithe7adf2b2018-06-07 14:43:59 -04001431 # Only consider normal fields or InitVars.
1432 if f._field_type is _FIELD_CLASSVAR:
1433 continue
1434
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001435 if not f.init:
1436 # Error if this field is specified in changes.
1437 if f.name in changes:
1438 raise ValueError(f'field {f.name} is declared with '
1439 'init=False, it cannot be specified with '
1440 'replace()')
1441 continue
1442
1443 if f.name not in changes:
Zackery Spytz75220672021-04-05 13:41:01 -06001444 if f._field_type is _FIELD_INITVAR and f.default is MISSING:
Dong-hee Na3d70f7a2018-06-23 23:46:32 +09001445 raise ValueError(f"InitVar {f.name!r} "
1446 'must be specified with replace()')
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001447 changes[f.name] = getattr(obj, f.name)
1448
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001449 # Create the new object, which calls __init__() and
Eric V. Smithf8e75492018-05-16 05:14:53 -04001450 # __post_init__() (if defined), using all of the init fields we've
1451 # added and/or left in 'changes'. If there are values supplied in
1452 # changes that aren't fields, this will correctly raise a
1453 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001454 return obj.__class__(**changes)