blob: adfb9b7240b9f9a3d5923bacce881326784a4c77 [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
Ethan Smithd01628e2020-04-14 16:14:15 -070011from types import 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
155
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500156# Raised when an attempt is made to modify a frozen class.
157class FrozenInstanceError(AttributeError): pass
158
Eric V. Smithf8e75492018-05-16 05:14:53 -0400159# A sentinel object for default values to signal that a default
160# factory will be used. This is given a nice repr() which will appear
161# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500162class _HAS_DEFAULT_FACTORY_CLASS:
163 def __repr__(self):
164 return '<factory>'
165_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
166
Eric V. Smith03220fd2017-12-29 13:59:58 -0500167# A sentinel object to detect if a parameter is supplied or not. Use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400168# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500169class _MISSING_TYPE:
170 pass
171MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500172
173# Since most per-field metadata will be unused, create an empty
Eric V. Smithf8e75492018-05-16 05:14:53 -0400174# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500175_EMPTY_METADATA = types.MappingProxyType({})
176
177# Markers for the various kinds of fields and pseudo-fields.
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400178class _FIELD_BASE:
179 def __init__(self, name):
180 self.name = name
181 def __repr__(self):
182 return self.name
183_FIELD = _FIELD_BASE('_FIELD')
184_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
185_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500186
187# The name of an attribute on the class where we store the Field
Eric V. Smithf8e75492018-05-16 05:14:53 -0400188# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400189_FIELDS = '__dataclass_fields__'
190
191# The name of an attribute on the class that stores the parameters to
192# @dataclass.
193_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500194
195# The name of the function, that if it exists, is called at the end of
196# __init__.
197_POST_INIT_NAME = '__post_init__'
198
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400199# String regex that string annotations for ClassVar or InitVar must match.
200# Allows "identifier.identifier[" or "identifier[".
201# https://bugs.python.org/issue33453 for details.
202_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500203
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300204class InitVar:
Augusto Hack01ee12b2019-06-02 23:14:48 -0300205 __slots__ = ('type', )
206
207 def __init__(self, type):
208 self.type = type
209
210 def __repr__(self):
Samuel Colvin793cb852019-10-13 12:45:36 +0100211 if isinstance(self.type, type):
212 type_name = self.type.__name__
213 else:
214 # typing objects, e.g. List[int]
215 type_name = repr(self.type)
216 return f'dataclasses.InitVar[{type_name}]'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500217
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300218 def __class_getitem__(cls, type):
219 return InitVar(type)
220
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500221
222# Instances of Field are only ever created from within this module,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400223# and only from the field() function, although Field instances are
224# exposed externally as (conceptually) read-only objects.
225#
226# name and type are filled in after the fact, not in __init__.
227# They're not known at the time this class is instantiated, but it's
228# convenient if they're available later.
229#
Eric V. Smithf199bc62018-03-18 20:40:34 -0400230# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf8e75492018-05-16 05:14:53 -0400231# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500232class Field:
233 __slots__ = ('name',
234 'type',
235 'default',
236 'default_factory',
237 'repr',
238 'hash',
239 'init',
240 'compare',
241 'metadata',
242 '_field_type', # Private: not to be used by user code.
243 )
244
245 def __init__(self, default, default_factory, init, repr, hash, compare,
246 metadata):
247 self.name = None
248 self.type = None
249 self.default = default
250 self.default_factory = default_factory
251 self.init = init
252 self.repr = repr
253 self.hash = hash
254 self.compare = compare
255 self.metadata = (_EMPTY_METADATA
Christopher Huntb01786c2019-02-12 06:50:49 -0500256 if metadata is None else
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500257 types.MappingProxyType(metadata))
258 self._field_type = None
259
260 def __repr__(self):
261 return ('Field('
262 f'name={self.name!r},'
Eric V. Smith2473eea2018-05-14 11:37:28 -0400263 f'type={self.type!r},'
264 f'default={self.default!r},'
265 f'default_factory={self.default_factory!r},'
266 f'init={self.init!r},'
267 f'repr={self.repr!r},'
268 f'hash={self.hash!r},'
269 f'compare={self.compare!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400270 f'metadata={self.metadata!r},'
271 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500272 ')')
273
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400274 # This is used to support the PEP 487 __set_name__ protocol in the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400275 # case where we're using a field that contains a descriptor as a
Artjome55ca3f2018-07-06 02:09:13 +0300276 # default value. For details on __set_name__, see
Eric V. Smithf8e75492018-05-16 05:14:53 -0400277 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
278 #
279 # Note that in _process_class, this Field object is overwritten
280 # with the default value, so the end result is a descriptor that
281 # had __set_name__ called on it at the right time.
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400282 def __set_name__(self, owner, name):
Eric V. Smith52199522018-03-29 11:07:48 -0400283 func = getattr(type(self.default), '__set_name__', None)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400284 if func:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400285 # There is a __set_name__ method on the descriptor, call
286 # it.
Eric V. Smith52199522018-03-29 11:07:48 -0400287 func(self.default, owner, name)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400288
Ethan Smithd01628e2020-04-14 16:14:15 -0700289 __class_getitem__ = classmethod(GenericAlias)
290
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500291
Eric V. Smithf199bc62018-03-18 20:40:34 -0400292class _DataclassParams:
293 __slots__ = ('init',
294 'repr',
295 'eq',
296 'order',
297 'unsafe_hash',
298 'frozen',
299 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400300
Eric V. Smithf199bc62018-03-18 20:40:34 -0400301 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
302 self.init = init
303 self.repr = repr
304 self.eq = eq
305 self.order = order
306 self.unsafe_hash = unsafe_hash
307 self.frozen = frozen
308
309 def __repr__(self):
310 return ('_DataclassParams('
Eric V. Smith30590422018-05-14 17:16:52 -0400311 f'init={self.init!r},'
312 f'repr={self.repr!r},'
313 f'eq={self.eq!r},'
314 f'order={self.order!r},'
315 f'unsafe_hash={self.unsafe_hash!r},'
316 f'frozen={self.frozen!r}'
Eric V. Smithf199bc62018-03-18 20:40:34 -0400317 ')')
318
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400319
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500320# This function is used instead of exposing Field creation directly,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400321# so that a type checker can be told (via overloads) that this is a
322# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500323def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500324 hash=None, compare=True, metadata=None):
325 """Return an object to identify dataclass fields.
326
Eric V. Smithf8e75492018-05-16 05:14:53 -0400327 default is the default value of the field. default_factory is a
328 0-argument function called to initialize a field's value. If init
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500329 is True, the field will be a parameter to the class's __init__()
Eric V. Smithf8e75492018-05-16 05:14:53 -0400330 function. If repr is True, the field will be included in the
331 object's repr(). If hash is True, the field will be included in
332 the object's hash(). If compare is True, the field will be used
333 in comparison functions. metadata, if specified, must be a
334 mapping which is stored but not otherwise examined by dataclass.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500335
336 It is an error to specify both default and default_factory.
337 """
338
Eric V. Smith03220fd2017-12-29 13:59:58 -0500339 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500340 raise ValueError('cannot specify both default and default_factory')
341 return Field(default, default_factory, init, repr, hash, compare,
342 metadata)
343
344
345def _tuple_str(obj_name, fields):
346 # Return a string representing each field of obj_name as a tuple
Eric V. Smithf8e75492018-05-16 05:14:53 -0400347 # member. So, if fields is ['x', 'y'] and obj_name is "self",
348 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500349
350 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500351 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500352 return '()'
353 # Note the trailing comma, needed if this turns out to be a 1-tuple.
354 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
355
356
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530357# This function's logic is copied from "recursive_repr" function in
358# reprlib module to avoid dependency.
359def _recursive_repr(user_function):
360 # Decorator to make a repr function return "..." for a recursive
361 # call.
362 repr_running = set()
363
364 @functools.wraps(user_function)
365 def wrapper(self):
366 key = id(self), _thread.get_ident()
367 if key in repr_running:
368 return '...'
369 repr_running.add(key)
370 try:
371 result = user_function(self)
372 finally:
373 repr_running.discard(key)
374 return result
375 return wrapper
376
377
Eric V. Smithea8fc522018-01-27 19:07:40 -0500378def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500379 return_type=MISSING):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400380 # Note that we mutate locals when exec() is called. Caller
381 # beware! The only callers are internal to this module, so no
382 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500383 if locals is None:
384 locals = {}
Yury Selivanovd219cc42019-12-09 09:54:20 -0500385 if 'BUILTINS' not in locals:
386 locals['BUILTINS'] = builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500387 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500388 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500389 locals['_return_type'] = return_type
390 return_annotation = '->_return_type'
391 args = ','.join(args)
Yury Selivanovd219cc42019-12-09 09:54:20 -0500392 body = '\n'.join(f' {b}' for b in body)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500393
Eric V. Smithf199bc62018-03-18 20:40:34 -0400394 # Compute the text of the entire function.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500395 txt = f' def {name}({args}){return_annotation}:\n{body}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500396
Yury Selivanovd219cc42019-12-09 09:54:20 -0500397 local_vars = ', '.join(locals.keys())
398 txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
399
400 ns = {}
401 exec(txt, globals, ns)
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300402 func = ns['__create_fn__'](**locals)
403 for arg, annotation in func.__annotations__.copy().items():
404 func.__annotations__[arg] = locals[annotation]
405 return func
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500406
407def _field_assign(frozen, name, value, self_name):
408 # If we're a frozen class, then assign to our fields in __init__
Eric V. Smithf8e75492018-05-16 05:14:53 -0400409 # via object.__setattr__. Otherwise, just use a simple
410 # assignment.
411 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500412 # self_name is what "self" is called in this function: don't
Eric V. Smithf8e75492018-05-16 05:14:53 -0400413 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500414 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500415 return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500416 return f'{self_name}.{name}={value}'
417
418
419def _field_init(f, frozen, globals, self_name):
420 # Return the text of the line in the body of __init__ that will
Eric V. Smithf8e75492018-05-16 05:14:53 -0400421 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500422
423 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500424 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500425 if f.init:
426 # This field has a default factory. If a parameter is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400427 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500428 globals[default_name] = f.default_factory
429 value = (f'{default_name}() '
430 f'if {f.name} is _HAS_DEFAULT_FACTORY '
431 f'else {f.name}')
432 else:
433 # This is a field that's not in the __init__ params, but
Eric V. Smithf8e75492018-05-16 05:14:53 -0400434 # has a default factory function. It needs to be
435 # initialized here by calling the factory function,
436 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500437
438 # For a field initialized with a default=defaultvalue, the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400439 # class dict just has the default value
440 # (cls.fieldname=defaultvalue). But that won't work for a
441 # default factory, the factory must be called in __init__
442 # and we must assign that to self.fieldname. We can't
443 # fall back to the class dict's value, both because it's
444 # not set, and because it might be different per-class
445 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500446
447 globals[default_name] = f.default_factory
448 value = f'{default_name}()'
449 else:
450 # No default factory.
451 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500452 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500453 # There's no default, just do an assignment.
454 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500455 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500456 globals[default_name] = f.default
457 value = f.name
458 else:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400459 # This field does not need initialization. Signify that
460 # to the caller by returning None.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500461 return None
462
463 # Only test this now, so that we can create variables for the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400464 # default. However, return None to signify that we're not going
465 # to actually do the assignment statement for InitVars.
Eric V. Smithe7adf2b2018-06-07 14:43:59 -0400466 if f._field_type is _FIELD_INITVAR:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500467 return None
468
469 # Now, actually generate the field assignment.
470 return _field_assign(frozen, f.name, value, self_name)
471
472
473def _init_param(f):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400474 # Return the __init__ parameter string for this field. For
475 # example, the equivalent of 'x:int=3' (except instead of 'int',
476 # reference a variable set to int, and instead of '3', reference a
477 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500478 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400479 # There's no default, and no default_factory, just output the
480 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500481 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500482 elif f.default is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400483 # There's a default, this will be the name that's used to look
484 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500485 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500486 elif f.default_factory is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400487 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500488 default = '=_HAS_DEFAULT_FACTORY'
489 return f'{f.name}:_type_{f.name}{default}'
490
491
Yury Selivanovd219cc42019-12-09 09:54:20 -0500492def _init_fn(fields, frozen, has_post_init, self_name, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500493 # fields contains both real fields and InitVar pseudo-fields.
494
495 # Make sure we don't have fields without defaults following fields
Eric V. Smithf8e75492018-05-16 05:14:53 -0400496 # with defaults. This actually would be caught when exec-ing the
497 # function source code, but catching it here gives a better error
498 # message, and future-proofs us in case we build up the function
499 # using ast.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500500 seen_default = False
501 for f in fields:
502 # Only consider fields in the __init__ call.
503 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500504 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500505 seen_default = True
506 elif seen_default:
507 raise TypeError(f'non-default argument {f.name!r} '
508 'follows default argument')
509
Yury Selivanovd219cc42019-12-09 09:54:20 -0500510 locals = {f'_type_{f.name}': f.type for f in fields}
511 locals.update({
512 'MISSING': MISSING,
513 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
514 })
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500515
516 body_lines = []
517 for f in fields:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500518 line = _field_init(f, frozen, locals, self_name)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400519 # line is None means that this field doesn't require
Eric V. Smithf8e75492018-05-16 05:14:53 -0400520 # initialization (it's a pseudo-field). Just skip it.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400521 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500522 body_lines.append(line)
523
524 # Does this class have a post-init function?
525 if has_post_init:
526 params_str = ','.join(f.name for f in fields
527 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400528 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500529
530 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500531 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500532 body_lines = ['pass']
533
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500534 return _create_fn('__init__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400535 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500536 body_lines,
537 locals=locals,
538 globals=globals,
539 return_type=None)
540
541
Yury Selivanovd219cc42019-12-09 09:54:20 -0500542def _repr_fn(fields, globals):
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530543 fn = _create_fn('__repr__',
544 ('self',),
545 ['return self.__class__.__qualname__ + f"(' +
546 ', '.join([f"{f.name}={{self.{f.name}!r}}"
547 for f in fields]) +
Yury Selivanovd219cc42019-12-09 09:54:20 -0500548 ')"'],
549 globals=globals)
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530550 return _recursive_repr(fn)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500551
552
Yury Selivanovd219cc42019-12-09 09:54:20 -0500553def _frozen_get_del_attr(cls, fields, globals):
554 locals = {'cls': cls,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400555 'FrozenInstanceError': FrozenInstanceError}
556 if fields:
557 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
558 else:
559 # Special case for the zero-length tuple.
560 fields_str = '()'
561 return (_create_fn('__setattr__',
562 ('self', 'name', 'value'),
563 (f'if type(self) is cls or name in {fields_str}:',
564 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
565 f'super(cls, self).__setattr__(name, value)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500566 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400567 globals=globals),
568 _create_fn('__delattr__',
569 ('self', 'name'),
570 (f'if type(self) is cls or name in {fields_str}:',
571 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
572 f'super(cls, self).__delattr__(name)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500573 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400574 globals=globals),
575 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500576
577
Yury Selivanovd219cc42019-12-09 09:54:20 -0500578def _cmp_fn(name, op, self_tuple, other_tuple, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500579 # Create a comparison function. If the fields in the object are
Eric V. Smithf8e75492018-05-16 05:14:53 -0400580 # named 'x' and 'y', then self_tuple is the string
581 # '(self.x,self.y)' and other_tuple is the string
582 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500583
584 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400585 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500586 [ 'if other.__class__ is self.__class__:',
587 f' return {self_tuple}{op}{other_tuple}',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500588 'return NotImplemented'],
589 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500590
591
Yury Selivanovd219cc42019-12-09 09:54:20 -0500592def _hash_fn(fields, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500593 self_tuple = _tuple_str('self', fields)
594 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400595 ('self',),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500596 [f'return hash({self_tuple})'],
597 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500598
599
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400600def _is_classvar(a_type, typing):
Eric V. Smith92858352018-05-16 07:24:00 -0400601 # This test uses a typing internal class, but it's the best way to
602 # test if this is a ClassVar.
603 return (a_type is typing.ClassVar
604 or (type(a_type) is typing._GenericAlias
605 and a_type.__origin__ is typing.ClassVar))
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400606
607
608def _is_initvar(a_type, dataclasses):
609 # The module we're checking against is the module we're
610 # currently in (dataclasses.py).
Augusto Hack01ee12b2019-06-02 23:14:48 -0300611 return (a_type is dataclasses.InitVar
612 or type(a_type) is dataclasses.InitVar)
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400613
614
615def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
616 # Given a type annotation string, does it refer to a_type in
617 # a_module? For example, when checking that annotation denotes a
618 # ClassVar, then a_module is typing, and a_type is
619 # typing.ClassVar.
620
621 # It's possible to look up a_module given a_type, but it involves
622 # looking in sys.modules (again!), and seems like a waste since
623 # the caller already knows a_module.
624
625 # - annotation is a string type annotation
626 # - cls is the class that this annotation was found in
627 # - a_module is the module we want to match
628 # - a_type is the type in that module we want to match
629 # - is_type_predicate is a function called with (obj, a_module)
630 # that determines if obj is of the desired type.
631
632 # Since this test does not do a local namespace lookup (and
633 # instead only a module (global) lookup), there are some things it
634 # gets wrong.
635
Eric V. Smithf8e75492018-05-16 05:14:53 -0400636 # With string annotations, cv0 will be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400637 # CV = ClassVar
638 # @dataclass
639 # class C0:
640 # cv0: CV
641
Eric V. Smithf8e75492018-05-16 05:14:53 -0400642 # But in this example cv1 will not be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400643 # @dataclass
644 # class C1:
645 # CV = ClassVar
646 # cv1: CV
647
Eric V. Smithf8e75492018-05-16 05:14:53 -0400648 # In C1, the code in this function (_is_type) will look up "CV" in
649 # the module and not find it, so it will not consider cv1 as a
650 # ClassVar. This is a fairly obscure corner case, and the best
651 # way to fix it would be to eval() the string "CV" with the
652 # correct global and local namespaces. However that would involve
653 # a eval() penalty for every single field of every dataclass
654 # that's defined. It was judged not worth it.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400655
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300656 # Strip away the extra quotes as a result of double-stringifying when the
657 # 'annotations' feature became default.
658 if annotation.startswith(("'", '"')) and annotation.endswith(("'", '"')):
659 annotation = annotation[1:-1]
660
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400661 match = _MODULE_IDENTIFIER_RE.match(annotation)
662 if match:
663 ns = None
664 module_name = match.group(1)
665 if not module_name:
666 # No module name, assume the class's module did
667 # "from dataclasses import InitVar".
668 ns = sys.modules.get(cls.__module__).__dict__
669 else:
670 # Look up module_name in the class's module.
671 module = sys.modules.get(cls.__module__)
672 if module and module.__dict__.get(module_name) is a_module:
673 ns = sys.modules.get(a_type.__module__).__dict__
674 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
675 return True
676 return False
677
678
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500679def _get_field(cls, a_name, a_type):
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400680 # Return a Field object for this field name and type. ClassVars
Eric V. Smithf8e75492018-05-16 05:14:53 -0400681 # and InitVars are also returned, but marked as such (see
682 # f._field_type).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500683
Eric V. Smithf8e75492018-05-16 05:14:53 -0400684 # If the default value isn't derived from Field, then it's only a
685 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500686 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500687 if isinstance(default, Field):
688 f = default
689 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400690 if isinstance(default, types.MemberDescriptorType):
691 # This is a field in __slots__, so it has no default value.
692 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500693 f = field(default=default)
694
Eric V. Smithf8e75492018-05-16 05:14:53 -0400695 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500696 f.name = a_name
697 f.type = a_type
698
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400699 # Assume it's a normal field until proven otherwise. We're next
Eric V. Smithf8e75492018-05-16 05:14:53 -0400700 # going to decide if it's a ClassVar or InitVar, everything else
701 # is just a normal field.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400702 f._field_type = _FIELD
703
704 # In addition to checking for actual types here, also check for
Eric V. Smithf8e75492018-05-16 05:14:53 -0400705 # string annotations. get_type_hints() won't always work for us
706 # (see https://github.com/python/typing/issues/508 for example),
707 # plus it's expensive and would require an eval for every stirng
708 # annotation. So, make a best effort to see if this is a ClassVar
709 # or InitVar using regex's and checking that the thing referenced
710 # is actually of the correct type.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400711
712 # For the complete discussion, see https://bugs.python.org/issue33453
713
714 # If typing has not been imported, then it's impossible for any
Eric V. Smithf8e75492018-05-16 05:14:53 -0400715 # annotation to be a ClassVar. So, only look for ClassVar if
716 # typing has been imported by any module (not necessarily cls's
717 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500718 typing = sys.modules.get('typing')
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400719 if typing:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400720 if (_is_classvar(a_type, typing)
721 or (isinstance(f.type, str)
722 and _is_type(f.type, cls, typing, typing.ClassVar,
723 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500724 f._field_type = _FIELD_CLASSVAR
725
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400726 # If the type is InitVar, or if it's a matching string annotation,
727 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500728 if f._field_type is _FIELD:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400729 # The module we're checking against is the module we're
730 # currently in (dataclasses.py).
731 dataclasses = sys.modules[__name__]
732 if (_is_initvar(a_type, dataclasses)
733 or (isinstance(f.type, str)
734 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
735 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500736 f._field_type = _FIELD_INITVAR
737
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400738 # Validations for individual fields. This is delayed until now,
739 # instead of in the Field() constructor, since only here do we
740 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500741
742 # Special restrictions for ClassVar and InitVar.
743 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500744 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500745 raise TypeError(f'field {f.name} cannot have a '
746 'default factory')
747 # Should I check for other field settings? default_factory
Eric V. Smithf8e75492018-05-16 05:14:53 -0400748 # seems the most serious to check for. Maybe add others. For
749 # example, how about init=False (or really,
750 # init=<not-the-default-init-value>)? It makes no sense for
751 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500752
753 # For real fields, disallow mutable defaults for known types.
754 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
755 raise ValueError(f'mutable default {type(f.default)} for field '
756 f'{f.name} is not allowed: use default_factory')
757
758 return f
759
760
Eric V. Smithea8fc522018-01-27 19:07:40 -0500761def _set_new_attribute(cls, name, value):
762 # Never overwrites an existing attribute. Returns True if the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400763 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500764 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500765 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500766 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500767 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500768
769
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500770# Decide if/how we're going to create a hash function. Key is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400771# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
772# take. The common case is to do nothing, so instead of providing a
773# function that is a no-op, use None to signify that.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400774
Yury Selivanovd219cc42019-12-09 09:54:20 -0500775def _hash_set_none(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400776 return None
777
Yury Selivanovd219cc42019-12-09 09:54:20 -0500778def _hash_add(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400779 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
Yury Selivanovd219cc42019-12-09 09:54:20 -0500780 return _hash_fn(flds, globals)
Eric V. Smith01d618c2018-03-24 22:10:14 -0400781
Yury Selivanovd219cc42019-12-09 09:54:20 -0500782def _hash_exception(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400783 # Raise an exception.
784 raise TypeError(f'Cannot overwrite attribute __hash__ '
785 f'in class {cls.__name__}')
786
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500787#
788# +-------------------------------------- unsafe_hash?
789# | +------------------------------- eq?
790# | | +------------------------ frozen?
791# | | | +---------------- has-explicit-hash?
792# | | | |
793# | | | | +------- action
794# | | | | |
795# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400796_hash_action = {(False, False, False, False): None,
797 (False, False, False, True ): None,
798 (False, False, True, False): None,
799 (False, False, True, True ): None,
800 (False, True, False, False): _hash_set_none,
801 (False, True, False, True ): None,
802 (False, True, True, False): _hash_add,
803 (False, True, True, True ): None,
804 (True, False, False, False): _hash_add,
805 (True, False, False, True ): _hash_exception,
806 (True, False, True, False): _hash_add,
807 (True, False, True, True ): _hash_exception,
808 (True, True, False, False): _hash_add,
809 (True, True, False, True ): _hash_exception,
810 (True, True, True, False): _hash_add,
811 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500812 }
813# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Eric V. Smithf8e75492018-05-16 05:14:53 -0400814# version of this table.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500815
816
Eric V. Smithf199bc62018-03-18 20:40:34 -0400817def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500818 # Now that dicts retain insertion order, there's no reason to use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400819 # an ordered dict. I am leveraging that ordering here, because
820 # derived class fields overwrite base class fields, but the order
821 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500822 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500823
Yury Selivanovd219cc42019-12-09 09:54:20 -0500824 if cls.__module__ in sys.modules:
825 globals = sys.modules[cls.__module__].__dict__
826 else:
827 # Theoretically this can happen if someone writes
828 # a custom string to cls.__module__. In which case
829 # such dataclass won't be fully introspectable
830 # (w.r.t. typing.get_type_hints) but will still function
831 # correctly.
832 globals = {}
833
Eric V. Smithf199bc62018-03-18 20:40:34 -0400834 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
835 unsafe_hash, frozen))
836
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500837 # Find our base classes in reverse MRO order, and exclude
Eric V. Smithf8e75492018-05-16 05:14:53 -0400838 # ourselves. In reversed order so that more derived classes
839 # override earlier field definitions in base classes. As long as
840 # we're iterating over them, see if any are frozen.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400841 any_frozen_base = False
842 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500843 for b in cls.__mro__[-1:0:-1]:
844 # Only process classes that have been processed by our
Eric V. Smithf8e75492018-05-16 05:14:53 -0400845 # decorator. That is, they have a _FIELDS attribute.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400846 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500847 if base_fields:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400848 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500849 for f in base_fields.values():
850 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400851 if getattr(b, _PARAMS).frozen:
852 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500853
Eric V. Smith56970b82018-03-22 16:28:48 -0400854 # Annotations that are defined in this class (not in base
Eric V. Smithf8e75492018-05-16 05:14:53 -0400855 # classes). If __annotations__ isn't present, then this class
856 # adds no new annotations. We use this to compute fields that are
857 # added by this class.
858 #
Eric V. Smith56970b82018-03-22 16:28:48 -0400859 # Fields are found from cls_annotations, which is guaranteed to be
Eric V. Smithf8e75492018-05-16 05:14:53 -0400860 # ordered. Default values are from class attributes, if a field
861 # has a default. If the default value is a Field(), then it
862 # contains additional info beyond (and possibly including) the
863 # actual default value. Pseudo-fields ClassVars and InitVars are
864 # included, despite the fact that they're not real fields. That's
865 # dealt with later.
Eric V. Smith56970b82018-03-22 16:28:48 -0400866 cls_annotations = cls.__dict__.get('__annotations__', {})
867
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500868 # Now find fields in our class. While doing so, validate some
Eric V. Smithf8e75492018-05-16 05:14:53 -0400869 # things, and set the default values (as class attributes) where
870 # we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400871 cls_fields = [_get_field(cls, name, type)
872 for name, type in cls_annotations.items()]
873 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500874 fields[f.name] = f
875
Eric V. Smithf8e75492018-05-16 05:14:53 -0400876 # If the class attribute (which is the default value for this
877 # field) exists and is of type 'Field', replace it with the
878 # real default. This is so that normal class introspection
879 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500880 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500881 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500882 # If there's no default, delete the class attribute.
Eric V. Smithf8e75492018-05-16 05:14:53 -0400883 # This happens if we specify field(repr=False), for
884 # example (that is, we specified a field object, but
885 # no default value). Also if we're using a default
886 # factory. The class attribute should not be set at
887 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500888 delattr(cls, f.name)
889 else:
890 setattr(cls, f.name, f.default)
891
Eric V. Smith56970b82018-03-22 16:28:48 -0400892 # Do we have any Field members that don't also have annotations?
893 for name, value in cls.__dict__.items():
894 if isinstance(value, Field) and not name in cls_annotations:
895 raise TypeError(f'{name!r} is a field but has no type annotation')
896
Eric V. Smithf199bc62018-03-18 20:40:34 -0400897 # Check rules that apply if we are derived from any dataclasses.
898 if has_dataclass_bases:
899 # Raise an exception if any of our bases are frozen, but we're not.
900 if any_frozen_base and not frozen:
901 raise TypeError('cannot inherit non-frozen dataclass from a '
902 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500903
Eric V. Smithf199bc62018-03-18 20:40:34 -0400904 # Raise an exception if we're frozen, but none of our bases are.
905 if not any_frozen_base and frozen:
906 raise TypeError('cannot inherit frozen dataclass from a '
907 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500908
Eric V. Smithf8e75492018-05-16 05:14:53 -0400909 # Remember all of the fields on our class (including bases). This
910 # also marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400911 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500912
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500913 # Was this class defined with an explicit __hash__? Note that if
Eric V. Smithf8e75492018-05-16 05:14:53 -0400914 # __eq__ is defined in this class, then python will automatically
915 # set __hash__ to None. This is a heuristic, as it's possible
916 # that such a __hash__ == None was not auto-generated, but it
917 # close enough.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500918 class_hash = cls.__dict__.get('__hash__', MISSING)
919 has_explicit_hash = not (class_hash is MISSING or
920 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500921
Eric V. Smithf8e75492018-05-16 05:14:53 -0400922 # If we're generating ordering methods, we must be generating the
923 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500924 if order and not eq:
925 raise ValueError('eq must be true if order is true')
926
927 if init:
928 # Does this class have a post-init function?
929 has_post_init = hasattr(cls, _POST_INIT_NAME)
930
931 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500932 flds = [f for f in fields.values()
933 if f._field_type in (_FIELD, _FIELD_INITVAR)]
934 _set_new_attribute(cls, '__init__',
935 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500936 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500937 has_post_init,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400938 # The name to use for the "self"
939 # param in __init__. Use "self"
940 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500941 '__dataclass_self__' if 'self' in fields
942 else 'self',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500943 globals,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500944 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500945
946 # Get the fields as a list, and include only real fields. This is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400947 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500948 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500949
950 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500951 flds = [f for f in field_list if f.repr]
Yury Selivanovd219cc42019-12-09 09:54:20 -0500952 _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500953
954 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500955 # Create _eq__ method. There's no need for a __ne__ method,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400956 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500957 flds = [f for f in field_list if f.compare]
958 self_tuple = _tuple_str('self', flds)
959 other_tuple = _tuple_str('other', flds)
960 _set_new_attribute(cls, '__eq__',
961 _cmp_fn('__eq__', '==',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500962 self_tuple, other_tuple,
963 globals=globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500964
965 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500966 # Create and set the ordering methods.
967 flds = [f for f in field_list if f.compare]
968 self_tuple = _tuple_str('self', flds)
969 other_tuple = _tuple_str('other', flds)
970 for name, op in [('__lt__', '<'),
971 ('__le__', '<='),
972 ('__gt__', '>'),
973 ('__ge__', '>='),
974 ]:
975 if _set_new_attribute(cls, name,
Yury Selivanovd219cc42019-12-09 09:54:20 -0500976 _cmp_fn(name, op, self_tuple, other_tuple,
977 globals=globals)):
Eric V. Smithea8fc522018-01-27 19:07:40 -0500978 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500979 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500980 'functools.total_ordering')
981
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500982 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500983 for fn in _frozen_get_del_attr(cls, field_list, globals):
Eric V. Smithf199bc62018-03-18 20:40:34 -0400984 if _set_new_attribute(cls, fn.__name__, fn):
985 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500986 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500987
988 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500989 hash_action = _hash_action[bool(unsafe_hash),
990 bool(eq),
991 bool(frozen),
992 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -0400993 if hash_action:
994 # No need to call _set_new_attribute here, since by the time
Eric V. Smithf8e75492018-05-16 05:14:53 -0400995 # we're here the overwriting is unconditional.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500996 cls.__hash__ = hash_action(cls, field_list, globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500997
998 if not getattr(cls, '__doc__'):
999 # Create a class doc-string.
1000 cls.__doc__ = (cls.__name__ +
Batuhan Taskaya044a1042020-10-06 23:03:02 +03001001 str(inspect.signature(cls)).replace(' -> NoneType', ''))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001002
Ben Avrahamibef7d292020-10-06 20:40:50 +03001003 abc.update_abstractmethods(cls)
1004
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001005 return cls
1006
1007
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001008def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001009 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001010 """Returns the same class as was passed in, with dunder methods
1011 added based on the fields defined in the class.
1012
1013 Examines PEP 526 __annotations__ to determine fields.
1014
1015 If init is true, an __init__() method is added to the class. If
1016 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001017 comparison dunder methods are added. If unsafe_hash is true, a
1018 __hash__() method function is added. If frozen is true, fields may
1019 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001020 """
1021
1022 def wrap(cls):
Eric V. Smithf199bc62018-03-18 20:40:34 -04001023 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001024
1025 # See if we're being called as @dataclass or @dataclass().
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001026 if cls is None:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001027 # We're called with parens.
1028 return wrap
1029
1030 # We're called as @dataclass without parens.
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001031 return wrap(cls)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001032
1033
1034def fields(class_or_instance):
1035 """Return a tuple describing the fields of this dataclass.
1036
1037 Accepts a dataclass or an instance of one. Tuple elements are of
1038 type Field.
1039 """
1040
1041 # Might it be worth caching this, per class?
1042 try:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001043 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001044 except AttributeError:
1045 raise TypeError('must be called with a dataclass type or instance')
1046
Eric V. Smithd1388922018-01-07 14:30:17 -05001047 # Exclude pseudo-fields. Note that fields is sorted by insertion
Eric V. Smithf8e75492018-05-16 05:14:53 -04001048 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001049 return tuple(f for f in fields.values() if f._field_type is _FIELD)
1050
1051
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001052def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001053 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001054 return hasattr(type(obj), _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001055
1056
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001057def is_dataclass(obj):
1058 """Returns True if obj is a dataclass or an instance of a
1059 dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001060 cls = obj if isinstance(obj, type) else type(obj)
1061 return hasattr(cls, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001062
1063
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001064def asdict(obj, *, dict_factory=dict):
1065 """Return the fields of a dataclass instance as a new dictionary mapping
1066 field names to field values.
1067
1068 Example usage:
1069
1070 @dataclass
1071 class C:
1072 x: int
1073 y: int
1074
1075 c = C(1, 2)
1076 assert asdict(c) == {'x': 1, 'y': 2}
1077
1078 If given, 'dict_factory' will be used instead of built-in dict.
1079 The function applies recursively to field values that are
1080 dataclass instances. This will also look into built-in containers:
1081 tuples, lists, and dicts.
1082 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001083 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001084 raise TypeError("asdict() should be called on dataclass instances")
1085 return _asdict_inner(obj, dict_factory)
1086
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001087
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001088def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001089 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001090 result = []
1091 for f in fields(obj):
1092 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1093 result.append((f.name, value))
1094 return dict_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001095 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1096 # obj is a namedtuple. Recurse into it, but the returned
1097 # object is another namedtuple of the same type. This is
1098 # similar to how other list- or tuple-derived classes are
1099 # treated (see below), but we just need to create them
1100 # differently because a namedtuple's __init__ needs to be
1101 # called differently (see bpo-34363).
1102
1103 # I'm not using namedtuple's _asdict()
1104 # method, because:
1105 # - it does not recurse in to the namedtuple fields and
1106 # convert them to dicts (using dict_factory).
Jürgen Gmach80526f62020-06-24 12:46:52 +02001107 # - I don't actually want to return a dict here. The main
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001108 # use case here is json.dumps, and it handles converting
1109 # namedtuples to lists. Admittedly we're losing some
1110 # information here when we produce a json list instead of a
1111 # dict. Note that if we returned dicts here instead of
1112 # namedtuples, we could no longer call asdict() on a data
1113 # structure where a namedtuple was used as a dict key.
1114
1115 return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001116 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001117 # Assume we can create an object of this type by passing in a
1118 # generator (which is not true for namedtuples, handled
1119 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001120 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1121 elif isinstance(obj, dict):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001122 return type(obj)((_asdict_inner(k, dict_factory),
1123 _asdict_inner(v, dict_factory))
1124 for k, v in obj.items())
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001125 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001126 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001127
1128
1129def astuple(obj, *, tuple_factory=tuple):
1130 """Return the fields of a dataclass instance as a new tuple of field values.
1131
1132 Example usage::
1133
1134 @dataclass
1135 class C:
1136 x: int
1137 y: int
1138
1139 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001140 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001141
1142 If given, 'tuple_factory' will be used instead of built-in tuple.
1143 The function applies recursively to field values that are
1144 dataclass instances. This will also look into built-in containers:
1145 tuples, lists, and dicts.
1146 """
1147
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001148 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001149 raise TypeError("astuple() should be called on dataclass instances")
1150 return _astuple_inner(obj, tuple_factory)
1151
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001152
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001153def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001154 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001155 result = []
1156 for f in fields(obj):
1157 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1158 result.append(value)
1159 return tuple_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001160 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1161 # obj is a namedtuple. Recurse into it, but the returned
1162 # object is another namedtuple of the same type. This is
1163 # similar to how other list- or tuple-derived classes are
1164 # treated (see below), but we just need to create them
1165 # differently because a namedtuple's __init__ needs to be
1166 # called differently (see bpo-34363).
1167 return type(obj)(*[_astuple_inner(v, tuple_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001168 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001169 # Assume we can create an object of this type by passing in a
1170 # generator (which is not true for namedtuples, handled
1171 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001172 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1173 elif isinstance(obj, dict):
1174 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1175 for k, v in obj.items())
1176 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001177 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001178
1179
Eric V. Smithd80b4432018-01-06 17:09:58 -05001180def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001181 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001182 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001183 """Return a new dynamically created dataclass.
1184
Eric V. Smithed7d4292018-01-06 16:14:03 -05001185 The dataclass name will be 'cls_name'. 'fields' is an iterable
1186 of either (name), (name, type) or (name, type, Field) objects. If type is
1187 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001188 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001189
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001190 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001191
1192 is equivalent to:
1193
1194 @dataclass
1195 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001196 x: 'typing.Any'
1197 y: int
1198 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001199
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001200 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001201
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001202 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001203 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001204 """
1205
1206 if namespace is None:
1207 namespace = {}
1208 else:
1209 # Copy namespace since we're going to mutate it.
1210 namespace = namespace.copy()
1211
Eric V. Smith4e812962018-05-16 11:31:29 -04001212 # While we're looking through the field names, validate that they
1213 # are identifiers, are not keywords, and not duplicates.
1214 seen = set()
Eric V. Smithd1388922018-01-07 14:30:17 -05001215 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001216 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001217 if isinstance(item, str):
1218 name = item
1219 tp = 'typing.Any'
1220 elif len(item) == 2:
1221 name, tp, = item
1222 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001223 name, tp, spec = item
1224 namespace[name] = spec
Eric V. Smith4e812962018-05-16 11:31:29 -04001225 else:
1226 raise TypeError(f'Invalid field: {item!r}')
1227
1228 if not isinstance(name, str) or not name.isidentifier():
Min ho Kim96e12d52019-07-22 06:12:33 +10001229 raise TypeError(f'Field names must be valid identifiers: {name!r}')
Eric V. Smith4e812962018-05-16 11:31:29 -04001230 if keyword.iskeyword(name):
1231 raise TypeError(f'Field names must not be keywords: {name!r}')
1232 if name in seen:
1233 raise TypeError(f'Field name duplicated: {name!r}')
1234
1235 seen.add(name)
Eric V. Smithed7d4292018-01-06 16:14:03 -05001236 anns[name] = tp
1237
1238 namespace['__annotations__'] = anns
Ivan Levkivskyi5a7092d2018-03-31 13:41:17 +01001239 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1240 # of generic dataclassses.
1241 cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace))
Eric V. Smithd80b4432018-01-06 17:09:58 -05001242 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001243 unsafe_hash=unsafe_hash, frozen=frozen)
1244
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001245
Serhiy Storchaka2d88e632019-06-26 19:07:44 +03001246def replace(obj, /, **changes):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001247 """Return a new object replacing specified fields with new values.
1248
1249 This is especially useful for frozen classes. Example usage:
1250
1251 @dataclass(frozen=True)
1252 class C:
1253 x: int
1254 y: int
1255
1256 c = C(1, 2)
1257 c1 = replace(c, x=3)
1258 assert c1.x == 3 and c1.y == 2
1259 """
1260
Eric V. Smithf8e75492018-05-16 05:14:53 -04001261 # We're going to mutate 'changes', but that's okay because it's a
1262 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001263
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001264 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001265 raise TypeError("replace() should be called on dataclass instances")
1266
1267 # It's an error to have init=False fields in 'changes'.
1268 # If a field is not in 'changes', read its value from the provided obj.
1269
Eric V. Smithf199bc62018-03-18 20:40:34 -04001270 for f in getattr(obj, _FIELDS).values():
Eric V. Smithe7adf2b2018-06-07 14:43:59 -04001271 # Only consider normal fields or InitVars.
1272 if f._field_type is _FIELD_CLASSVAR:
1273 continue
1274
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001275 if not f.init:
1276 # Error if this field is specified in changes.
1277 if f.name in changes:
1278 raise ValueError(f'field {f.name} is declared with '
1279 'init=False, it cannot be specified with '
1280 'replace()')
1281 continue
1282
1283 if f.name not in changes:
Dong-hee Na3d70f7a2018-06-23 23:46:32 +09001284 if f._field_type is _FIELD_INITVAR:
1285 raise ValueError(f"InitVar {f.name!r} "
1286 'must be specified with replace()')
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001287 changes[f.name] = getattr(obj, f.name)
1288
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001289 # Create the new object, which calls __init__() and
Eric V. Smithf8e75492018-05-16 05:14:53 -04001290 # __post_init__() (if defined), using all of the init fields we've
1291 # added and/or left in 'changes'. If there are values supplied in
1292 # changes that aren't fields, this will correctly raise a
1293 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001294 return obj.__class__(**changes)