blob: 1b95bb961d9ecb91d91f01f94791a2ae980a119c [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. Smith03220fd2017-12-29 13:59:58 -050019 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050020
21 # Helper functions.
22 'fields',
23 'asdict',
24 'astuple',
25 'make_dataclass',
26 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050027 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050028 ]
29
Eric V. Smithea8fc522018-01-27 19:07:40 -050030# Conditions for adding methods. The boxes indicate what action the
Eric V. Smithf8e75492018-05-16 05:14:53 -040031# dataclass decorator takes. For all of these tables, when I talk
32# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
33# referring to the arguments to the @dataclass decorator. When
34# checking if a dunder method already exists, I mean check for an
35# entry in the class's __dict__. I never check to see if an attribute
36# is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050037
38# Key:
39# +=========+=========================================+
40# + Value | Meaning |
41# +=========+=========================================+
42# | <blank> | No action: no method is added. |
43# +---------+-----------------------------------------+
44# | add | Generated method is added. |
45# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050046# | raise | TypeError is raised. |
47# +---------+-----------------------------------------+
48# | None | Attribute is set to None. |
49# +=========+=========================================+
50
51# __init__
52#
53# +--- init= parameter
54# |
55# v | | |
56# | no | yes | <--- class has __init__ in __dict__?
57# +=======+=======+=======+
58# | False | | |
59# +-------+-------+-------+
60# | True | add | | <- the default
61# +=======+=======+=======+
62
63# __repr__
64#
65# +--- repr= parameter
66# |
67# v | | |
68# | no | yes | <--- class has __repr__ in __dict__?
69# +=======+=======+=======+
70# | False | | |
71# +-------+-------+-------+
72# | True | add | | <- the default
73# +=======+=======+=======+
74
75
76# __setattr__
77# __delattr__
78#
79# +--- frozen= parameter
80# |
81# v | | |
82# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
83# +=======+=======+=======+
84# | False | | | <- the default
85# +-------+-------+-------+
86# | True | add | raise |
87# +=======+=======+=======+
88# Raise because not adding these methods would break the "frozen-ness"
Eric V. Smithf8e75492018-05-16 05:14:53 -040089# of the class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050090
91# __eq__
92#
93# +--- eq= parameter
94# |
95# v | | |
96# | no | yes | <--- class has __eq__ in __dict__?
97# +=======+=======+=======+
98# | False | | |
99# +-------+-------+-------+
100# | True | add | | <- the default
101# +=======+=======+=======+
102
103# __lt__
104# __le__
105# __gt__
106# __ge__
107#
108# +--- order= parameter
109# |
110# v | | |
111# | no | yes | <--- class has any comparison method in __dict__?
112# +=======+=======+=======+
113# | False | | | <- the default
114# +-------+-------+-------+
115# | True | add | raise |
116# +=======+=======+=======+
117# Raise because to allow this case would interfere with using
Eric V. Smithf8e75492018-05-16 05:14:53 -0400118# functools.total_ordering.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500119
120# __hash__
121
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500122# +------------------- unsafe_hash= parameter
123# | +----------- eq= parameter
124# | | +--- frozen= parameter
125# | | |
126# v v v | | |
127# | no | yes | <--- class has explicitly defined __hash__
128# +=======+=======+=======+========+========+
129# | False | False | False | | | No __eq__, use the base class __hash__
130# +-------+-------+-------+--------+--------+
131# | False | False | True | | | No __eq__, use the base class __hash__
132# +-------+-------+-------+--------+--------+
133# | False | True | False | None | | <-- the default, not hashable
134# +-------+-------+-------+--------+--------+
135# | False | True | True | add | | Frozen, so hashable, allows override
136# +-------+-------+-------+--------+--------+
137# | True | False | False | add | raise | Has no __eq__, but hashable
138# +-------+-------+-------+--------+--------+
139# | True | False | True | add | raise | Has no __eq__, but hashable
140# +-------+-------+-------+--------+--------+
141# | True | True | False | add | raise | Not frozen, but hashable
142# +-------+-------+-------+--------+--------+
143# | True | True | True | add | raise | Frozen, so hashable
144# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500145# For boxes that are blank, __hash__ is untouched and therefore
Eric V. Smithf8e75492018-05-16 05:14:53 -0400146# inherited from the base class. If the base is object, then
147# id-based hashing is used.
148#
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400149# Note that a class may already have __hash__=None if it specified an
Eric V. Smithf8e75492018-05-16 05:14:53 -0400150# __eq__ method in the class body (not one that was created by
151# @dataclass).
152#
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500153# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500154
Brandt Bucher145bf262021-02-26 14:51:55 -0800155# __match_args__
156#
Eric V. Smith750f4842021-04-10 21:28:42 -0400157# +--- match_args= parameter
158# |
159# v | | |
160# | no | yes | <--- class has __match_args__ in __dict__?
161# +=======+=======+=======+
162# | False | | |
163# +-------+-------+-------+
164# | True | add | | <- the default
165# +=======+=======+=======+
166# __match_args__ is a tuple of __init__ parameter names; non-init fields must
167# be matched by keyword.
Brandt Bucher145bf262021-02-26 14:51:55 -0800168
Eric V. Smithea8fc522018-01-27 19:07:40 -0500169
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500170# Raised when an attempt is made to modify a frozen class.
171class FrozenInstanceError(AttributeError): pass
172
Eric V. Smithf8e75492018-05-16 05:14:53 -0400173# A sentinel object for default values to signal that a default
174# factory will be used. This is given a nice repr() which will appear
175# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500176class _HAS_DEFAULT_FACTORY_CLASS:
177 def __repr__(self):
178 return '<factory>'
179_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
180
Eric V. Smith03220fd2017-12-29 13:59:58 -0500181# A sentinel object to detect if a parameter is supplied or not. Use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400182# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500183class _MISSING_TYPE:
184 pass
185MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500186
187# Since most per-field metadata will be unused, create an empty
Eric V. Smithf8e75492018-05-16 05:14:53 -0400188# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500189_EMPTY_METADATA = types.MappingProxyType({})
190
191# Markers for the various kinds of fields and pseudo-fields.
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400192class _FIELD_BASE:
193 def __init__(self, name):
194 self.name = name
195 def __repr__(self):
196 return self.name
197_FIELD = _FIELD_BASE('_FIELD')
198_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
199_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500200
201# The name of an attribute on the class where we store the Field
Eric V. Smithf8e75492018-05-16 05:14:53 -0400202# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400203_FIELDS = '__dataclass_fields__'
204
205# The name of an attribute on the class that stores the parameters to
206# @dataclass.
207_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500208
209# The name of the function, that if it exists, is called at the end of
210# __init__.
211_POST_INIT_NAME = '__post_init__'
212
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400213# String regex that string annotations for ClassVar or InitVar must match.
214# Allows "identifier.identifier[" or "identifier[".
215# https://bugs.python.org/issue33453 for details.
216_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500217
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300218class InitVar:
Augusto Hack01ee12b2019-06-02 23:14:48 -0300219 __slots__ = ('type', )
220
221 def __init__(self, type):
222 self.type = type
223
224 def __repr__(self):
Samuel Colvin793cb852019-10-13 12:45:36 +0100225 if isinstance(self.type, type):
226 type_name = self.type.__name__
227 else:
228 # typing objects, e.g. List[int]
229 type_name = repr(self.type)
230 return f'dataclasses.InitVar[{type_name}]'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500231
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300232 def __class_getitem__(cls, type):
233 return InitVar(type)
234
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500235
236# Instances of Field are only ever created from within this module,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400237# and only from the field() function, although Field instances are
238# exposed externally as (conceptually) read-only objects.
239#
240# name and type are filled in after the fact, not in __init__.
241# They're not known at the time this class is instantiated, but it's
242# convenient if they're available later.
243#
Eric V. Smithf199bc62018-03-18 20:40:34 -0400244# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf8e75492018-05-16 05:14:53 -0400245# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500246class Field:
247 __slots__ = ('name',
248 'type',
249 'default',
250 'default_factory',
251 'repr',
252 'hash',
253 'init',
254 'compare',
255 'metadata',
256 '_field_type', # Private: not to be used by user code.
257 )
258
259 def __init__(self, default, default_factory, init, repr, hash, compare,
260 metadata):
261 self.name = None
262 self.type = None
263 self.default = default
264 self.default_factory = default_factory
265 self.init = init
266 self.repr = repr
267 self.hash = hash
268 self.compare = compare
269 self.metadata = (_EMPTY_METADATA
Christopher Huntb01786c2019-02-12 06:50:49 -0500270 if metadata is None else
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500271 types.MappingProxyType(metadata))
272 self._field_type = None
273
274 def __repr__(self):
275 return ('Field('
276 f'name={self.name!r},'
Eric V. Smith2473eea2018-05-14 11:37:28 -0400277 f'type={self.type!r},'
278 f'default={self.default!r},'
279 f'default_factory={self.default_factory!r},'
280 f'init={self.init!r},'
281 f'repr={self.repr!r},'
282 f'hash={self.hash!r},'
283 f'compare={self.compare!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400284 f'metadata={self.metadata!r},'
285 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500286 ')')
287
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400288 # This is used to support the PEP 487 __set_name__ protocol in the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400289 # case where we're using a field that contains a descriptor as a
Artjome55ca3f2018-07-06 02:09:13 +0300290 # default value. For details on __set_name__, see
Eric V. Smithf8e75492018-05-16 05:14:53 -0400291 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
292 #
293 # Note that in _process_class, this Field object is overwritten
294 # with the default value, so the end result is a descriptor that
295 # had __set_name__ called on it at the right time.
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400296 def __set_name__(self, owner, name):
Eric V. Smith52199522018-03-29 11:07:48 -0400297 func = getattr(type(self.default), '__set_name__', None)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400298 if func:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400299 # There is a __set_name__ method on the descriptor, call
300 # it.
Eric V. Smith52199522018-03-29 11:07:48 -0400301 func(self.default, owner, name)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400302
Ethan Smithd01628e2020-04-14 16:14:15 -0700303 __class_getitem__ = classmethod(GenericAlias)
304
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500305
Eric V. Smithf199bc62018-03-18 20:40:34 -0400306class _DataclassParams:
307 __slots__ = ('init',
308 'repr',
309 'eq',
310 'order',
311 'unsafe_hash',
312 'frozen',
313 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400314
Eric V. Smithf199bc62018-03-18 20:40:34 -0400315 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
316 self.init = init
317 self.repr = repr
318 self.eq = eq
319 self.order = order
320 self.unsafe_hash = unsafe_hash
321 self.frozen = frozen
322
323 def __repr__(self):
324 return ('_DataclassParams('
Eric V. Smith30590422018-05-14 17:16:52 -0400325 f'init={self.init!r},'
326 f'repr={self.repr!r},'
327 f'eq={self.eq!r},'
328 f'order={self.order!r},'
329 f'unsafe_hash={self.unsafe_hash!r},'
330 f'frozen={self.frozen!r}'
Eric V. Smithf199bc62018-03-18 20:40:34 -0400331 ')')
332
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400333
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500334# This function is used instead of exposing Field creation directly,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400335# so that a type checker can be told (via overloads) that this is a
336# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500337def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500338 hash=None, compare=True, metadata=None):
339 """Return an object to identify dataclass fields.
340
Eric V. Smithf8e75492018-05-16 05:14:53 -0400341 default is the default value of the field. default_factory is a
342 0-argument function called to initialize a field's value. If init
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500343 is True, the field will be a parameter to the class's __init__()
Eric V. Smithf8e75492018-05-16 05:14:53 -0400344 function. If repr is True, the field will be included in the
345 object's repr(). If hash is True, the field will be included in
346 the object's hash(). If compare is True, the field will be used
347 in comparison functions. metadata, if specified, must be a
348 mapping which is stored but not otherwise examined by dataclass.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500349
350 It is an error to specify both default and default_factory.
351 """
352
Eric V. Smith03220fd2017-12-29 13:59:58 -0500353 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500354 raise ValueError('cannot specify both default and default_factory')
355 return Field(default, default_factory, init, repr, hash, compare,
356 metadata)
357
358
359def _tuple_str(obj_name, fields):
360 # Return a string representing each field of obj_name as a tuple
Eric V. Smithf8e75492018-05-16 05:14:53 -0400361 # member. So, if fields is ['x', 'y'] and obj_name is "self",
362 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500363
364 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500365 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500366 return '()'
367 # Note the trailing comma, needed if this turns out to be a 1-tuple.
368 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
369
370
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530371# This function's logic is copied from "recursive_repr" function in
372# reprlib module to avoid dependency.
373def _recursive_repr(user_function):
374 # Decorator to make a repr function return "..." for a recursive
375 # call.
376 repr_running = set()
377
378 @functools.wraps(user_function)
379 def wrapper(self):
380 key = id(self), _thread.get_ident()
381 if key in repr_running:
382 return '...'
383 repr_running.add(key)
384 try:
385 result = user_function(self)
386 finally:
387 repr_running.discard(key)
388 return result
389 return wrapper
390
391
Eric V. Smithea8fc522018-01-27 19:07:40 -0500392def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500393 return_type=MISSING):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400394 # Note that we mutate locals when exec() is called. Caller
395 # beware! The only callers are internal to this module, so no
396 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500397 if locals is None:
398 locals = {}
Yury Selivanovd219cc42019-12-09 09:54:20 -0500399 if 'BUILTINS' not in locals:
400 locals['BUILTINS'] = builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500401 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500402 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500403 locals['_return_type'] = return_type
404 return_annotation = '->_return_type'
405 args = ','.join(args)
Yury Selivanovd219cc42019-12-09 09:54:20 -0500406 body = '\n'.join(f' {b}' for b in body)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500407
Eric V. Smithf199bc62018-03-18 20:40:34 -0400408 # Compute the text of the entire function.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500409 txt = f' def {name}({args}){return_annotation}:\n{body}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500410
Yury Selivanovd219cc42019-12-09 09:54:20 -0500411 local_vars = ', '.join(locals.keys())
412 txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
413
414 ns = {}
415 exec(txt, globals, ns)
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300416 func = ns['__create_fn__'](**locals)
417 for arg, annotation in func.__annotations__.copy().items():
418 func.__annotations__[arg] = locals[annotation]
419 return func
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500420
421def _field_assign(frozen, name, value, self_name):
422 # If we're a frozen class, then assign to our fields in __init__
Eric V. Smithf8e75492018-05-16 05:14:53 -0400423 # via object.__setattr__. Otherwise, just use a simple
424 # assignment.
425 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500426 # self_name is what "self" is called in this function: don't
Eric V. Smithf8e75492018-05-16 05:14:53 -0400427 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500428 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500429 return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500430 return f'{self_name}.{name}={value}'
431
432
433def _field_init(f, frozen, globals, self_name):
434 # Return the text of the line in the body of __init__ that will
Eric V. Smithf8e75492018-05-16 05:14:53 -0400435 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500436
437 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500438 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500439 if f.init:
440 # This field has a default factory. If a parameter is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400441 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500442 globals[default_name] = f.default_factory
443 value = (f'{default_name}() '
444 f'if {f.name} is _HAS_DEFAULT_FACTORY '
445 f'else {f.name}')
446 else:
447 # This is a field that's not in the __init__ params, but
Eric V. Smithf8e75492018-05-16 05:14:53 -0400448 # has a default factory function. It needs to be
449 # initialized here by calling the factory function,
450 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500451
452 # For a field initialized with a default=defaultvalue, the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400453 # class dict just has the default value
454 # (cls.fieldname=defaultvalue). But that won't work for a
455 # default factory, the factory must be called in __init__
456 # and we must assign that to self.fieldname. We can't
457 # fall back to the class dict's value, both because it's
458 # not set, and because it might be different per-class
459 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500460
461 globals[default_name] = f.default_factory
462 value = f'{default_name}()'
463 else:
464 # No default factory.
465 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500466 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500467 # There's no default, just do an assignment.
468 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500469 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500470 globals[default_name] = f.default
471 value = f.name
472 else:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400473 # This field does not need initialization. Signify that
474 # to the caller by returning None.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500475 return None
476
477 # Only test this now, so that we can create variables for the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400478 # default. However, return None to signify that we're not going
479 # to actually do the assignment statement for InitVars.
Eric V. Smithe7adf2b2018-06-07 14:43:59 -0400480 if f._field_type is _FIELD_INITVAR:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500481 return None
482
483 # Now, actually generate the field assignment.
484 return _field_assign(frozen, f.name, value, self_name)
485
486
487def _init_param(f):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400488 # Return the __init__ parameter string for this field. For
489 # example, the equivalent of 'x:int=3' (except instead of 'int',
490 # reference a variable set to int, and instead of '3', reference a
491 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500492 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400493 # There's no default, and no default_factory, just output the
494 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500495 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500496 elif f.default is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400497 # There's a default, this will be the name that's used to look
498 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500499 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500500 elif f.default_factory is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400501 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500502 default = '=_HAS_DEFAULT_FACTORY'
503 return f'{f.name}:_type_{f.name}{default}'
504
505
Yury Selivanovd219cc42019-12-09 09:54:20 -0500506def _init_fn(fields, frozen, has_post_init, self_name, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500507 # fields contains both real fields and InitVar pseudo-fields.
508
509 # Make sure we don't have fields without defaults following fields
Eric V. Smithf8e75492018-05-16 05:14:53 -0400510 # with defaults. This actually would be caught when exec-ing the
511 # function source code, but catching it here gives a better error
512 # message, and future-proofs us in case we build up the function
513 # using ast.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500514 seen_default = False
515 for f in fields:
516 # Only consider fields in the __init__ call.
517 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500518 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500519 seen_default = True
520 elif seen_default:
521 raise TypeError(f'non-default argument {f.name!r} '
522 'follows default argument')
523
Yury Selivanovd219cc42019-12-09 09:54:20 -0500524 locals = {f'_type_{f.name}': f.type for f in fields}
525 locals.update({
526 'MISSING': MISSING,
527 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
528 })
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500529
530 body_lines = []
531 for f in fields:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500532 line = _field_init(f, frozen, locals, self_name)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400533 # line is None means that this field doesn't require
Eric V. Smithf8e75492018-05-16 05:14:53 -0400534 # initialization (it's a pseudo-field). Just skip it.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400535 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500536 body_lines.append(line)
537
538 # Does this class have a post-init function?
539 if has_post_init:
540 params_str = ','.join(f.name for f in fields
541 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400542 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500543
544 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500545 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500546 body_lines = ['pass']
547
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500548 return _create_fn('__init__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400549 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500550 body_lines,
551 locals=locals,
552 globals=globals,
553 return_type=None)
554
555
Yury Selivanovd219cc42019-12-09 09:54:20 -0500556def _repr_fn(fields, globals):
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530557 fn = _create_fn('__repr__',
558 ('self',),
559 ['return self.__class__.__qualname__ + f"(' +
560 ', '.join([f"{f.name}={{self.{f.name}!r}}"
561 for f in fields]) +
Yury Selivanovd219cc42019-12-09 09:54:20 -0500562 ')"'],
563 globals=globals)
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530564 return _recursive_repr(fn)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500565
566
Yury Selivanovd219cc42019-12-09 09:54:20 -0500567def _frozen_get_del_attr(cls, fields, globals):
568 locals = {'cls': cls,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400569 'FrozenInstanceError': FrozenInstanceError}
570 if fields:
571 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
572 else:
573 # Special case for the zero-length tuple.
574 fields_str = '()'
575 return (_create_fn('__setattr__',
576 ('self', 'name', 'value'),
577 (f'if type(self) is cls or name in {fields_str}:',
578 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
579 f'super(cls, self).__setattr__(name, value)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500580 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400581 globals=globals),
582 _create_fn('__delattr__',
583 ('self', 'name'),
584 (f'if type(self) is cls or name in {fields_str}:',
585 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
586 f'super(cls, self).__delattr__(name)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500587 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400588 globals=globals),
589 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500590
591
Yury Selivanovd219cc42019-12-09 09:54:20 -0500592def _cmp_fn(name, op, self_tuple, other_tuple, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500593 # Create a comparison function. If the fields in the object are
Eric V. Smithf8e75492018-05-16 05:14:53 -0400594 # named 'x' and 'y', then self_tuple is the string
595 # '(self.x,self.y)' and other_tuple is the string
596 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500597
598 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400599 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500600 [ 'if other.__class__ is self.__class__:',
601 f' return {self_tuple}{op}{other_tuple}',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500602 'return NotImplemented'],
603 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500604
605
Yury Selivanovd219cc42019-12-09 09:54:20 -0500606def _hash_fn(fields, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500607 self_tuple = _tuple_str('self', fields)
608 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400609 ('self',),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500610 [f'return hash({self_tuple})'],
611 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500612
613
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400614def _is_classvar(a_type, typing):
Eric V. Smith92858352018-05-16 07:24:00 -0400615 # This test uses a typing internal class, but it's the best way to
616 # test if this is a ClassVar.
617 return (a_type is typing.ClassVar
618 or (type(a_type) is typing._GenericAlias
619 and a_type.__origin__ is typing.ClassVar))
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400620
621
622def _is_initvar(a_type, dataclasses):
623 # The module we're checking against is the module we're
624 # currently in (dataclasses.py).
Augusto Hack01ee12b2019-06-02 23:14:48 -0300625 return (a_type is dataclasses.InitVar
626 or type(a_type) is dataclasses.InitVar)
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400627
628
629def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
630 # Given a type annotation string, does it refer to a_type in
631 # a_module? For example, when checking that annotation denotes a
632 # ClassVar, then a_module is typing, and a_type is
633 # typing.ClassVar.
634
635 # It's possible to look up a_module given a_type, but it involves
636 # looking in sys.modules (again!), and seems like a waste since
637 # the caller already knows a_module.
638
639 # - annotation is a string type annotation
640 # - cls is the class that this annotation was found in
641 # - a_module is the module we want to match
642 # - a_type is the type in that module we want to match
643 # - is_type_predicate is a function called with (obj, a_module)
644 # that determines if obj is of the desired type.
645
646 # Since this test does not do a local namespace lookup (and
647 # instead only a module (global) lookup), there are some things it
648 # gets wrong.
649
Eric V. Smithf8e75492018-05-16 05:14:53 -0400650 # With string annotations, cv0 will be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400651 # CV = ClassVar
652 # @dataclass
653 # class C0:
654 # cv0: CV
655
Eric V. Smithf8e75492018-05-16 05:14:53 -0400656 # But in this example cv1 will not be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400657 # @dataclass
658 # class C1:
659 # CV = ClassVar
660 # cv1: CV
661
Eric V. Smithf8e75492018-05-16 05:14:53 -0400662 # In C1, the code in this function (_is_type) will look up "CV" in
663 # the module and not find it, so it will not consider cv1 as a
664 # ClassVar. This is a fairly obscure corner case, and the best
665 # way to fix it would be to eval() the string "CV" with the
666 # correct global and local namespaces. However that would involve
667 # a eval() penalty for every single field of every dataclass
668 # that's defined. It was judged not worth it.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400669
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300670 # Strip away the extra quotes as a result of double-stringifying when the
671 # 'annotations' feature became default.
672 if annotation.startswith(("'", '"')) and annotation.endswith(("'", '"')):
673 annotation = annotation[1:-1]
674
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400675 match = _MODULE_IDENTIFIER_RE.match(annotation)
676 if match:
677 ns = None
678 module_name = match.group(1)
679 if not module_name:
680 # No module name, assume the class's module did
681 # "from dataclasses import InitVar".
682 ns = sys.modules.get(cls.__module__).__dict__
683 else:
684 # Look up module_name in the class's module.
685 module = sys.modules.get(cls.__module__)
686 if module and module.__dict__.get(module_name) is a_module:
687 ns = sys.modules.get(a_type.__module__).__dict__
688 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
689 return True
690 return False
691
692
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500693def _get_field(cls, a_name, a_type):
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400694 # Return a Field object for this field name and type. ClassVars
Eric V. Smithf8e75492018-05-16 05:14:53 -0400695 # and InitVars are also returned, but marked as such (see
696 # f._field_type).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500697
Eric V. Smithf8e75492018-05-16 05:14:53 -0400698 # If the default value isn't derived from Field, then it's only a
699 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500700 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500701 if isinstance(default, Field):
702 f = default
703 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400704 if isinstance(default, types.MemberDescriptorType):
705 # This is a field in __slots__, so it has no default value.
706 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500707 f = field(default=default)
708
Eric V. Smithf8e75492018-05-16 05:14:53 -0400709 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500710 f.name = a_name
711 f.type = a_type
712
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400713 # Assume it's a normal field until proven otherwise. We're next
Eric V. Smithf8e75492018-05-16 05:14:53 -0400714 # going to decide if it's a ClassVar or InitVar, everything else
715 # is just a normal field.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400716 f._field_type = _FIELD
717
718 # In addition to checking for actual types here, also check for
Eric V. Smithf8e75492018-05-16 05:14:53 -0400719 # string annotations. get_type_hints() won't always work for us
720 # (see https://github.com/python/typing/issues/508 for example),
Eric V. Smith76beadb2021-04-17 09:53:24 -0400721 # plus it's expensive and would require an eval for every string
Eric V. Smithf8e75492018-05-16 05:14:53 -0400722 # annotation. So, make a best effort to see if this is a ClassVar
723 # or InitVar using regex's and checking that the thing referenced
724 # is actually of the correct type.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400725
726 # For the complete discussion, see https://bugs.python.org/issue33453
727
728 # If typing has not been imported, then it's impossible for any
Eric V. Smithf8e75492018-05-16 05:14:53 -0400729 # annotation to be a ClassVar. So, only look for ClassVar if
730 # typing has been imported by any module (not necessarily cls's
731 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500732 typing = sys.modules.get('typing')
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400733 if typing:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400734 if (_is_classvar(a_type, typing)
735 or (isinstance(f.type, str)
736 and _is_type(f.type, cls, typing, typing.ClassVar,
737 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500738 f._field_type = _FIELD_CLASSVAR
739
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400740 # If the type is InitVar, or if it's a matching string annotation,
741 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500742 if f._field_type is _FIELD:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400743 # The module we're checking against is the module we're
744 # currently in (dataclasses.py).
745 dataclasses = sys.modules[__name__]
746 if (_is_initvar(a_type, dataclasses)
747 or (isinstance(f.type, str)
748 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
749 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500750 f._field_type = _FIELD_INITVAR
751
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400752 # Validations for individual fields. This is delayed until now,
753 # instead of in the Field() constructor, since only here do we
754 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500755
756 # Special restrictions for ClassVar and InitVar.
757 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500758 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500759 raise TypeError(f'field {f.name} cannot have a '
760 'default factory')
761 # Should I check for other field settings? default_factory
Eric V. Smithf8e75492018-05-16 05:14:53 -0400762 # seems the most serious to check for. Maybe add others. For
763 # example, how about init=False (or really,
764 # init=<not-the-default-init-value>)? It makes no sense for
765 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500766
767 # For real fields, disallow mutable defaults for known types.
768 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
769 raise ValueError(f'mutable default {type(f.default)} for field '
770 f'{f.name} is not allowed: use default_factory')
771
772 return f
773
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300774def _set_qualname(cls, value):
775 # Ensure that the functions returned from _create_fn uses the proper
776 # __qualname__ (the class they belong to).
777 if isinstance(value, FunctionType):
778 value.__qualname__ = f"{cls.__qualname__}.{value.__name__}"
779 return value
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500780
Eric V. Smithea8fc522018-01-27 19:07:40 -0500781def _set_new_attribute(cls, name, value):
782 # Never overwrites an existing attribute. Returns True if the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400783 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500784 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500785 return True
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300786 _set_qualname(cls, value)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500787 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500788 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500789
790
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500791# Decide if/how we're going to create a hash function. Key is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400792# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
793# take. The common case is to do nothing, so instead of providing a
794# function that is a no-op, use None to signify that.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400795
Yury Selivanovd219cc42019-12-09 09:54:20 -0500796def _hash_set_none(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400797 return None
798
Yury Selivanovd219cc42019-12-09 09:54:20 -0500799def _hash_add(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400800 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300801 return _set_qualname(cls, _hash_fn(flds, globals))
Eric V. Smith01d618c2018-03-24 22:10:14 -0400802
Yury Selivanovd219cc42019-12-09 09:54:20 -0500803def _hash_exception(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400804 # Raise an exception.
805 raise TypeError(f'Cannot overwrite attribute __hash__ '
806 f'in class {cls.__name__}')
807
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500808#
809# +-------------------------------------- unsafe_hash?
810# | +------------------------------- eq?
811# | | +------------------------ frozen?
812# | | | +---------------- has-explicit-hash?
813# | | | |
814# | | | | +------- action
815# | | | | |
816# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400817_hash_action = {(False, False, False, False): None,
818 (False, False, False, True ): None,
819 (False, False, True, False): None,
820 (False, False, True, True ): None,
821 (False, True, False, False): _hash_set_none,
822 (False, True, False, True ): None,
823 (False, True, True, False): _hash_add,
824 (False, True, True, True ): None,
825 (True, False, False, False): _hash_add,
826 (True, False, False, True ): _hash_exception,
827 (True, False, True, False): _hash_add,
828 (True, False, True, True ): _hash_exception,
829 (True, True, False, False): _hash_add,
830 (True, True, False, True ): _hash_exception,
831 (True, True, True, False): _hash_add,
832 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500833 }
834# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Eric V. Smithf8e75492018-05-16 05:14:53 -0400835# version of this table.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500836
837
Eric V. Smith750f4842021-04-10 21:28:42 -0400838def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
839 match_args):
Eric V. Smithd1388922018-01-07 14:30:17 -0500840 # Now that dicts retain insertion order, there's no reason to use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400841 # an ordered dict. I am leveraging that ordering here, because
842 # derived class fields overwrite base class fields, but the order
843 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500844 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500845
Yury Selivanovd219cc42019-12-09 09:54:20 -0500846 if cls.__module__ in sys.modules:
847 globals = sys.modules[cls.__module__].__dict__
848 else:
849 # Theoretically this can happen if someone writes
850 # a custom string to cls.__module__. In which case
851 # such dataclass won't be fully introspectable
852 # (w.r.t. typing.get_type_hints) but will still function
853 # correctly.
854 globals = {}
855
Eric V. Smithf199bc62018-03-18 20:40:34 -0400856 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
857 unsafe_hash, frozen))
858
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500859 # Find our base classes in reverse MRO order, and exclude
Eric V. Smithf8e75492018-05-16 05:14:53 -0400860 # ourselves. In reversed order so that more derived classes
861 # override earlier field definitions in base classes. As long as
862 # we're iterating over them, see if any are frozen.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400863 any_frozen_base = False
864 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500865 for b in cls.__mro__[-1:0:-1]:
866 # Only process classes that have been processed by our
Eric V. Smithf8e75492018-05-16 05:14:53 -0400867 # decorator. That is, they have a _FIELDS attribute.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400868 base_fields = getattr(b, _FIELDS, None)
Iurii Kemaev376ffc62021-04-06 06:14:01 +0100869 if base_fields is not None:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400870 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500871 for f in base_fields.values():
872 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400873 if getattr(b, _PARAMS).frozen:
874 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500875
Eric V. Smith56970b82018-03-22 16:28:48 -0400876 # Annotations that are defined in this class (not in base
Eric V. Smithf8e75492018-05-16 05:14:53 -0400877 # classes). If __annotations__ isn't present, then this class
878 # adds no new annotations. We use this to compute fields that are
879 # added by this class.
880 #
Eric V. Smith56970b82018-03-22 16:28:48 -0400881 # Fields are found from cls_annotations, which is guaranteed to be
Eric V. Smithf8e75492018-05-16 05:14:53 -0400882 # ordered. Default values are from class attributes, if a field
883 # has a default. If the default value is a Field(), then it
884 # contains additional info beyond (and possibly including) the
885 # actual default value. Pseudo-fields ClassVars and InitVars are
886 # included, despite the fact that they're not real fields. That's
887 # dealt with later.
Eric V. Smith56970b82018-03-22 16:28:48 -0400888 cls_annotations = cls.__dict__.get('__annotations__', {})
889
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500890 # Now find fields in our class. While doing so, validate some
Eric V. Smithf8e75492018-05-16 05:14:53 -0400891 # things, and set the default values (as class attributes) where
892 # we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400893 cls_fields = [_get_field(cls, name, type)
894 for name, type in cls_annotations.items()]
895 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500896 fields[f.name] = f
897
Eric V. Smithf8e75492018-05-16 05:14:53 -0400898 # If the class attribute (which is the default value for this
899 # field) exists and is of type 'Field', replace it with the
900 # real default. This is so that normal class introspection
901 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500902 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500903 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500904 # If there's no default, delete the class attribute.
Eric V. Smithf8e75492018-05-16 05:14:53 -0400905 # This happens if we specify field(repr=False), for
906 # example (that is, we specified a field object, but
907 # no default value). Also if we're using a default
908 # factory. The class attribute should not be set at
909 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500910 delattr(cls, f.name)
911 else:
912 setattr(cls, f.name, f.default)
913
Eric V. Smith56970b82018-03-22 16:28:48 -0400914 # Do we have any Field members that don't also have annotations?
915 for name, value in cls.__dict__.items():
916 if isinstance(value, Field) and not name in cls_annotations:
917 raise TypeError(f'{name!r} is a field but has no type annotation')
918
Eric V. Smithf199bc62018-03-18 20:40:34 -0400919 # Check rules that apply if we are derived from any dataclasses.
920 if has_dataclass_bases:
921 # Raise an exception if any of our bases are frozen, but we're not.
922 if any_frozen_base and not frozen:
923 raise TypeError('cannot inherit non-frozen dataclass from a '
924 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500925
Eric V. Smithf199bc62018-03-18 20:40:34 -0400926 # Raise an exception if we're frozen, but none of our bases are.
927 if not any_frozen_base and frozen:
928 raise TypeError('cannot inherit frozen dataclass from a '
929 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500930
Eric V. Smithf8e75492018-05-16 05:14:53 -0400931 # Remember all of the fields on our class (including bases). This
932 # also marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400933 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500934
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500935 # Was this class defined with an explicit __hash__? Note that if
Eric V. Smithf8e75492018-05-16 05:14:53 -0400936 # __eq__ is defined in this class, then python will automatically
937 # set __hash__ to None. This is a heuristic, as it's possible
938 # that such a __hash__ == None was not auto-generated, but it
939 # close enough.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500940 class_hash = cls.__dict__.get('__hash__', MISSING)
941 has_explicit_hash = not (class_hash is MISSING or
942 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500943
Eric V. Smithf8e75492018-05-16 05:14:53 -0400944 # If we're generating ordering methods, we must be generating the
945 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500946 if order and not eq:
947 raise ValueError('eq must be true if order is true')
948
949 if init:
950 # Does this class have a post-init function?
951 has_post_init = hasattr(cls, _POST_INIT_NAME)
952
953 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500954 flds = [f for f in fields.values()
955 if f._field_type in (_FIELD, _FIELD_INITVAR)]
956 _set_new_attribute(cls, '__init__',
957 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500958 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500959 has_post_init,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400960 # The name to use for the "self"
961 # param in __init__. Use "self"
962 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500963 '__dataclass_self__' if 'self' in fields
964 else 'self',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500965 globals,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500966 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500967
968 # Get the fields as a list, and include only real fields. This is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400969 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500970 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500971
972 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500973 flds = [f for f in field_list if f.repr]
Yury Selivanovd219cc42019-12-09 09:54:20 -0500974 _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500975
976 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500977 # Create _eq__ method. There's no need for a __ne__ method,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400978 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500979 flds = [f for f in field_list if f.compare]
980 self_tuple = _tuple_str('self', flds)
981 other_tuple = _tuple_str('other', flds)
982 _set_new_attribute(cls, '__eq__',
983 _cmp_fn('__eq__', '==',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500984 self_tuple, other_tuple,
985 globals=globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500986
987 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500988 # Create and set the ordering methods.
989 flds = [f for f in field_list if f.compare]
990 self_tuple = _tuple_str('self', flds)
991 other_tuple = _tuple_str('other', flds)
992 for name, op in [('__lt__', '<'),
993 ('__le__', '<='),
994 ('__gt__', '>'),
995 ('__ge__', '>='),
996 ]:
997 if _set_new_attribute(cls, name,
Yury Selivanovd219cc42019-12-09 09:54:20 -0500998 _cmp_fn(name, op, self_tuple, other_tuple,
999 globals=globals)):
Eric V. Smithea8fc522018-01-27 19:07:40 -05001000 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001001 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -05001002 'functools.total_ordering')
1003
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -05001004 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -05001005 for fn in _frozen_get_del_attr(cls, field_list, globals):
Eric V. Smithf199bc62018-03-18 20:40:34 -04001006 if _set_new_attribute(cls, fn.__name__, fn):
1007 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001008 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -05001009
1010 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001011 hash_action = _hash_action[bool(unsafe_hash),
1012 bool(eq),
1013 bool(frozen),
1014 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -04001015 if hash_action:
1016 # No need to call _set_new_attribute here, since by the time
Eric V. Smithf8e75492018-05-16 05:14:53 -04001017 # we're here the overwriting is unconditional.
Yury Selivanovd219cc42019-12-09 09:54:20 -05001018 cls.__hash__ = hash_action(cls, field_list, globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001019
1020 if not getattr(cls, '__doc__'):
1021 # Create a class doc-string.
1022 cls.__doc__ = (cls.__name__ +
Batuhan Taskaya044a1042020-10-06 23:03:02 +03001023 str(inspect.signature(cls)).replace(' -> NoneType', ''))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001024
Eric V. Smith750f4842021-04-10 21:28:42 -04001025 if match_args:
1026 _set_new_attribute(cls, '__match_args__',
1027 tuple(f.name for f in field_list if f.init))
Brandt Bucher145bf262021-02-26 14:51:55 -08001028
Ben Avrahamibef7d292020-10-06 20:40:50 +03001029 abc.update_abstractmethods(cls)
1030
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001031 return cls
1032
1033
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001034def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith750f4842021-04-10 21:28:42 -04001035 unsafe_hash=False, frozen=False, match_args=True):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001036 """Returns the same class as was passed in, with dunder methods
1037 added based on the fields defined in the class.
1038
1039 Examines PEP 526 __annotations__ to determine fields.
1040
1041 If init is true, an __init__() method is added to the class. If
1042 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001043 comparison dunder methods are added. If unsafe_hash is true, a
1044 __hash__() method function is added. If frozen is true, fields may
Eric V. Smith750f4842021-04-10 21:28:42 -04001045 not be assigned to after instance creation. If match_args is true,
1046 the __match_args__ tuple is added.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001047 """
1048
1049 def wrap(cls):
Eric V. Smith750f4842021-04-10 21:28:42 -04001050 return _process_class(cls, init, repr, eq, order, unsafe_hash,
1051 frozen, match_args)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001052
1053 # See if we're being called as @dataclass or @dataclass().
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001054 if cls is None:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001055 # We're called with parens.
1056 return wrap
1057
1058 # We're called as @dataclass without parens.
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001059 return wrap(cls)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001060
1061
1062def fields(class_or_instance):
1063 """Return a tuple describing the fields of this dataclass.
1064
1065 Accepts a dataclass or an instance of one. Tuple elements are of
1066 type Field.
1067 """
1068
1069 # Might it be worth caching this, per class?
1070 try:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001071 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001072 except AttributeError:
1073 raise TypeError('must be called with a dataclass type or instance')
1074
Eric V. Smithd1388922018-01-07 14:30:17 -05001075 # Exclude pseudo-fields. Note that fields is sorted by insertion
Eric V. Smithf8e75492018-05-16 05:14:53 -04001076 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001077 return tuple(f for f in fields.values() if f._field_type is _FIELD)
1078
1079
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001080def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001081 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001082 return hasattr(type(obj), _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001083
1084
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001085def is_dataclass(obj):
1086 """Returns True if obj is a dataclass or an instance of a
1087 dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001088 cls = obj if isinstance(obj, type) else type(obj)
1089 return hasattr(cls, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001090
1091
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001092def asdict(obj, *, dict_factory=dict):
1093 """Return the fields of a dataclass instance as a new dictionary mapping
1094 field names to field values.
1095
1096 Example usage:
1097
1098 @dataclass
1099 class C:
1100 x: int
1101 y: int
1102
1103 c = C(1, 2)
1104 assert asdict(c) == {'x': 1, 'y': 2}
1105
1106 If given, 'dict_factory' will be used instead of built-in dict.
1107 The function applies recursively to field values that are
1108 dataclass instances. This will also look into built-in containers:
1109 tuples, lists, and dicts.
1110 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001111 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001112 raise TypeError("asdict() should be called on dataclass instances")
1113 return _asdict_inner(obj, dict_factory)
1114
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001115
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001116def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001117 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001118 result = []
1119 for f in fields(obj):
1120 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1121 result.append((f.name, value))
1122 return dict_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001123 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1124 # obj is a namedtuple. Recurse into it, but the returned
1125 # object is another namedtuple of the same type. This is
1126 # similar to how other list- or tuple-derived classes are
1127 # treated (see below), but we just need to create them
1128 # differently because a namedtuple's __init__ needs to be
1129 # called differently (see bpo-34363).
1130
1131 # I'm not using namedtuple's _asdict()
1132 # method, because:
1133 # - it does not recurse in to the namedtuple fields and
1134 # convert them to dicts (using dict_factory).
Jürgen Gmach80526f62020-06-24 12:46:52 +02001135 # - I don't actually want to return a dict here. The main
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001136 # use case here is json.dumps, and it handles converting
1137 # namedtuples to lists. Admittedly we're losing some
1138 # information here when we produce a json list instead of a
1139 # dict. Note that if we returned dicts here instead of
1140 # namedtuples, we could no longer call asdict() on a data
1141 # structure where a namedtuple was used as a dict key.
1142
1143 return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001144 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001145 # Assume we can create an object of this type by passing in a
1146 # generator (which is not true for namedtuples, handled
1147 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001148 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1149 elif isinstance(obj, dict):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001150 return type(obj)((_asdict_inner(k, dict_factory),
1151 _asdict_inner(v, dict_factory))
1152 for k, v in obj.items())
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001153 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001154 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001155
1156
1157def astuple(obj, *, tuple_factory=tuple):
1158 """Return the fields of a dataclass instance as a new tuple of field values.
1159
1160 Example usage::
1161
1162 @dataclass
1163 class C:
1164 x: int
1165 y: int
1166
1167 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001168 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001169
1170 If given, 'tuple_factory' will be used instead of built-in tuple.
1171 The function applies recursively to field values that are
1172 dataclass instances. This will also look into built-in containers:
1173 tuples, lists, and dicts.
1174 """
1175
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001176 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001177 raise TypeError("astuple() should be called on dataclass instances")
1178 return _astuple_inner(obj, tuple_factory)
1179
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001180
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001181def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001182 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001183 result = []
1184 for f in fields(obj):
1185 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1186 result.append(value)
1187 return tuple_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001188 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1189 # obj is a namedtuple. Recurse into it, but the returned
1190 # object is another namedtuple of the same type. This is
1191 # similar to how other list- or tuple-derived classes are
1192 # treated (see below), but we just need to create them
1193 # differently because a namedtuple's __init__ needs to be
1194 # called differently (see bpo-34363).
1195 return type(obj)(*[_astuple_inner(v, tuple_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001196 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001197 # Assume we can create an object of this type by passing in a
1198 # generator (which is not true for namedtuples, handled
1199 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001200 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1201 elif isinstance(obj, dict):
1202 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1203 for k, v in obj.items())
1204 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001205 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001206
1207
Eric V. Smithd80b4432018-01-06 17:09:58 -05001208def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001209 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smith750f4842021-04-10 21:28:42 -04001210 frozen=False, match_args=True):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001211 """Return a new dynamically created dataclass.
1212
Eric V. Smithed7d4292018-01-06 16:14:03 -05001213 The dataclass name will be 'cls_name'. 'fields' is an iterable
1214 of either (name), (name, type) or (name, type, Field) objects. If type is
1215 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001216 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001217
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001218 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001219
1220 is equivalent to:
1221
1222 @dataclass
1223 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001224 x: 'typing.Any'
1225 y: int
1226 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001227
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001228 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001229
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001230 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001231 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001232 """
1233
1234 if namespace is None:
1235 namespace = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001236
Eric V. Smith4e812962018-05-16 11:31:29 -04001237 # While we're looking through the field names, validate that they
1238 # are identifiers, are not keywords, and not duplicates.
1239 seen = set()
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001240 annotations = {}
1241 defaults = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001242 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001243 if isinstance(item, str):
1244 name = item
1245 tp = 'typing.Any'
1246 elif len(item) == 2:
1247 name, tp, = item
1248 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001249 name, tp, spec = item
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001250 defaults[name] = spec
Eric V. Smith4e812962018-05-16 11:31:29 -04001251 else:
1252 raise TypeError(f'Invalid field: {item!r}')
1253
1254 if not isinstance(name, str) or not name.isidentifier():
Min ho Kim96e12d52019-07-22 06:12:33 +10001255 raise TypeError(f'Field names must be valid identifiers: {name!r}')
Eric V. Smith4e812962018-05-16 11:31:29 -04001256 if keyword.iskeyword(name):
1257 raise TypeError(f'Field names must not be keywords: {name!r}')
1258 if name in seen:
1259 raise TypeError(f'Field name duplicated: {name!r}')
1260
1261 seen.add(name)
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001262 annotations[name] = tp
Eric V. Smithed7d4292018-01-06 16:14:03 -05001263
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001264 # Update 'ns' with the user-supplied namespace plus our calculated values.
1265 def exec_body_callback(ns):
1266 ns.update(namespace)
1267 ns.update(defaults)
1268 ns['__annotations__'] = annotations
1269
Ivan Levkivskyi5a7092d2018-03-31 13:41:17 +01001270 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1271 # of generic dataclassses.
Eric V. Smithc1a66bd2021-04-12 21:02:02 -04001272 cls = types.new_class(cls_name, bases, {}, exec_body_callback)
1273
1274 # Apply the normal decorator.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001275 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smith750f4842021-04-10 21:28:42 -04001276 unsafe_hash=unsafe_hash, frozen=frozen,
1277 match_args=match_args)
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001278
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001279
Serhiy Storchaka2d88e632019-06-26 19:07:44 +03001280def replace(obj, /, **changes):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001281 """Return a new object replacing specified fields with new values.
1282
1283 This is especially useful for frozen classes. Example usage:
1284
1285 @dataclass(frozen=True)
1286 class C:
1287 x: int
1288 y: int
1289
1290 c = C(1, 2)
1291 c1 = replace(c, x=3)
1292 assert c1.x == 3 and c1.y == 2
1293 """
1294
Eric V. Smithf8e75492018-05-16 05:14:53 -04001295 # We're going to mutate 'changes', but that's okay because it's a
1296 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001297
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001298 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001299 raise TypeError("replace() should be called on dataclass instances")
1300
1301 # It's an error to have init=False fields in 'changes'.
1302 # If a field is not in 'changes', read its value from the provided obj.
1303
Eric V. Smithf199bc62018-03-18 20:40:34 -04001304 for f in getattr(obj, _FIELDS).values():
Eric V. Smithe7adf2b2018-06-07 14:43:59 -04001305 # Only consider normal fields or InitVars.
1306 if f._field_type is _FIELD_CLASSVAR:
1307 continue
1308
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001309 if not f.init:
1310 # Error if this field is specified in changes.
1311 if f.name in changes:
1312 raise ValueError(f'field {f.name} is declared with '
1313 'init=False, it cannot be specified with '
1314 'replace()')
1315 continue
1316
1317 if f.name not in changes:
Zackery Spytz75220672021-04-05 13:41:01 -06001318 if f._field_type is _FIELD_INITVAR and f.default is MISSING:
Dong-hee Na3d70f7a2018-06-23 23:46:32 +09001319 raise ValueError(f"InitVar {f.name!r} "
1320 'must be specified with replace()')
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001321 changes[f.name] = getattr(obj, f.name)
1322
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001323 # Create the new object, which calls __init__() and
Eric V. Smithf8e75492018-05-16 05:14:53 -04001324 # __post_init__() (if defined), using all of the init fields we've
1325 # added and/or left in 'changes'. If there are values supplied in
1326 # changes that aren't fields, this will correctly raise a
1327 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001328 return obj.__class__(**changes)