blob: 00851c648a13b5b15c28deb5ac5479f9c12c9996 [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
9import _thread
10
Eric V. Smithf0db54a2017-12-04 16:58:55 -050011
12__all__ = ['dataclass',
13 'field',
Eric V. Smith8e4560a2018-03-21 17:10:22 -040014 'Field',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050015 'FrozenInstanceError',
16 'InitVar',
Eric V. Smith03220fd2017-12-29 13:59:58 -050017 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050018
19 # Helper functions.
20 'fields',
21 'asdict',
22 'astuple',
23 'make_dataclass',
24 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050025 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050026 ]
27
Eric V. Smithea8fc522018-01-27 19:07:40 -050028# Conditions for adding methods. The boxes indicate what action the
Eric V. Smithf8e75492018-05-16 05:14:53 -040029# dataclass decorator takes. For all of these tables, when I talk
30# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
31# referring to the arguments to the @dataclass decorator. When
32# checking if a dunder method already exists, I mean check for an
33# entry in the class's __dict__. I never check to see if an attribute
34# is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050035
36# Key:
37# +=========+=========================================+
38# + Value | Meaning |
39# +=========+=========================================+
40# | <blank> | No action: no method is added. |
41# +---------+-----------------------------------------+
42# | add | Generated method is added. |
43# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050044# | raise | TypeError is raised. |
45# +---------+-----------------------------------------+
46# | None | Attribute is set to None. |
47# +=========+=========================================+
48
49# __init__
50#
51# +--- init= parameter
52# |
53# v | | |
54# | no | yes | <--- class has __init__ in __dict__?
55# +=======+=======+=======+
56# | False | | |
57# +-------+-------+-------+
58# | True | add | | <- the default
59# +=======+=======+=======+
60
61# __repr__
62#
63# +--- repr= parameter
64# |
65# v | | |
66# | no | yes | <--- class has __repr__ in __dict__?
67# +=======+=======+=======+
68# | False | | |
69# +-------+-------+-------+
70# | True | add | | <- the default
71# +=======+=======+=======+
72
73
74# __setattr__
75# __delattr__
76#
77# +--- frozen= parameter
78# |
79# v | | |
80# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
81# +=======+=======+=======+
82# | False | | | <- the default
83# +-------+-------+-------+
84# | True | add | raise |
85# +=======+=======+=======+
86# Raise because not adding these methods would break the "frozen-ness"
Eric V. Smithf8e75492018-05-16 05:14:53 -040087# of the class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050088
89# __eq__
90#
91# +--- eq= parameter
92# |
93# v | | |
94# | no | yes | <--- class has __eq__ in __dict__?
95# +=======+=======+=======+
96# | False | | |
97# +-------+-------+-------+
98# | True | add | | <- the default
99# +=======+=======+=======+
100
101# __lt__
102# __le__
103# __gt__
104# __ge__
105#
106# +--- order= parameter
107# |
108# v | | |
109# | no | yes | <--- class has any comparison method in __dict__?
110# +=======+=======+=======+
111# | False | | | <- the default
112# +-------+-------+-------+
113# | True | add | raise |
114# +=======+=======+=======+
115# Raise because to allow this case would interfere with using
Eric V. Smithf8e75492018-05-16 05:14:53 -0400116# functools.total_ordering.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500117
118# __hash__
119
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500120# +------------------- unsafe_hash= parameter
121# | +----------- eq= parameter
122# | | +--- frozen= parameter
123# | | |
124# v v v | | |
125# | no | yes | <--- class has explicitly defined __hash__
126# +=======+=======+=======+========+========+
127# | False | False | False | | | No __eq__, use the base class __hash__
128# +-------+-------+-------+--------+--------+
129# | False | False | True | | | No __eq__, use the base class __hash__
130# +-------+-------+-------+--------+--------+
131# | False | True | False | None | | <-- the default, not hashable
132# +-------+-------+-------+--------+--------+
133# | False | True | True | add | | Frozen, so hashable, allows override
134# +-------+-------+-------+--------+--------+
135# | True | False | False | add | raise | Has no __eq__, but hashable
136# +-------+-------+-------+--------+--------+
137# | True | False | True | add | raise | Has no __eq__, but hashable
138# +-------+-------+-------+--------+--------+
139# | True | True | False | add | raise | Not frozen, but hashable
140# +-------+-------+-------+--------+--------+
141# | True | True | True | add | raise | Frozen, so hashable
142# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500143# For boxes that are blank, __hash__ is untouched and therefore
Eric V. Smithf8e75492018-05-16 05:14:53 -0400144# inherited from the base class. If the base is object, then
145# id-based hashing is used.
146#
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400147# Note that a class may already have __hash__=None if it specified an
Eric V. Smithf8e75492018-05-16 05:14:53 -0400148# __eq__ method in the class body (not one that was created by
149# @dataclass).
150#
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500151# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500152
153
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500154# Raised when an attempt is made to modify a frozen class.
155class FrozenInstanceError(AttributeError): pass
156
Eric V. Smithf8e75492018-05-16 05:14:53 -0400157# A sentinel object for default values to signal that a default
158# factory will be used. This is given a nice repr() which will appear
159# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500160class _HAS_DEFAULT_FACTORY_CLASS:
161 def __repr__(self):
162 return '<factory>'
163_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
164
Eric V. Smith03220fd2017-12-29 13:59:58 -0500165# A sentinel object to detect if a parameter is supplied or not. Use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400166# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500167class _MISSING_TYPE:
168 pass
169MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500170
171# Since most per-field metadata will be unused, create an empty
Eric V. Smithf8e75492018-05-16 05:14:53 -0400172# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500173_EMPTY_METADATA = types.MappingProxyType({})
174
175# Markers for the various kinds of fields and pseudo-fields.
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400176class _FIELD_BASE:
177 def __init__(self, name):
178 self.name = name
179 def __repr__(self):
180 return self.name
181_FIELD = _FIELD_BASE('_FIELD')
182_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
183_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500184
185# The name of an attribute on the class where we store the Field
Eric V. Smithf8e75492018-05-16 05:14:53 -0400186# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400187_FIELDS = '__dataclass_fields__'
188
189# The name of an attribute on the class that stores the parameters to
190# @dataclass.
191_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500192
193# The name of the function, that if it exists, is called at the end of
194# __init__.
195_POST_INIT_NAME = '__post_init__'
196
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400197# String regex that string annotations for ClassVar or InitVar must match.
198# Allows "identifier.identifier[" or "identifier[".
199# https://bugs.python.org/issue33453 for details.
200_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500201
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300202class InitVar:
Augusto Hack01ee12b2019-06-02 23:14:48 -0300203 __slots__ = ('type', )
204
205 def __init__(self, type):
206 self.type = type
207
208 def __repr__(self):
Samuel Colvin793cb852019-10-13 12:45:36 +0100209 if isinstance(self.type, type):
210 type_name = self.type.__name__
211 else:
212 # typing objects, e.g. List[int]
213 type_name = repr(self.type)
214 return f'dataclasses.InitVar[{type_name}]'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500215
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300216 def __class_getitem__(cls, type):
217 return InitVar(type)
218
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500219
220# Instances of Field are only ever created from within this module,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400221# and only from the field() function, although Field instances are
222# exposed externally as (conceptually) read-only objects.
223#
224# name and type are filled in after the fact, not in __init__.
225# They're not known at the time this class is instantiated, but it's
226# convenient if they're available later.
227#
Eric V. Smithf199bc62018-03-18 20:40:34 -0400228# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf8e75492018-05-16 05:14:53 -0400229# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500230class Field:
231 __slots__ = ('name',
232 'type',
233 'default',
234 'default_factory',
235 'repr',
236 'hash',
237 'init',
238 'compare',
239 'metadata',
240 '_field_type', # Private: not to be used by user code.
241 )
242
243 def __init__(self, default, default_factory, init, repr, hash, compare,
244 metadata):
245 self.name = None
246 self.type = None
247 self.default = default
248 self.default_factory = default_factory
249 self.init = init
250 self.repr = repr
251 self.hash = hash
252 self.compare = compare
253 self.metadata = (_EMPTY_METADATA
Christopher Huntb01786c2019-02-12 06:50:49 -0500254 if metadata is None else
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500255 types.MappingProxyType(metadata))
256 self._field_type = None
257
258 def __repr__(self):
259 return ('Field('
260 f'name={self.name!r},'
Eric V. Smith2473eea2018-05-14 11:37:28 -0400261 f'type={self.type!r},'
262 f'default={self.default!r},'
263 f'default_factory={self.default_factory!r},'
264 f'init={self.init!r},'
265 f'repr={self.repr!r},'
266 f'hash={self.hash!r},'
267 f'compare={self.compare!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400268 f'metadata={self.metadata!r},'
269 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500270 ')')
271
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400272 # This is used to support the PEP 487 __set_name__ protocol in the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400273 # case where we're using a field that contains a descriptor as a
Artjome55ca3f2018-07-06 02:09:13 +0300274 # default value. For details on __set_name__, see
Eric V. Smithf8e75492018-05-16 05:14:53 -0400275 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
276 #
277 # Note that in _process_class, this Field object is overwritten
278 # with the default value, so the end result is a descriptor that
279 # had __set_name__ called on it at the right time.
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400280 def __set_name__(self, owner, name):
Eric V. Smith52199522018-03-29 11:07:48 -0400281 func = getattr(type(self.default), '__set_name__', None)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400282 if func:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400283 # There is a __set_name__ method on the descriptor, call
284 # it.
Eric V. Smith52199522018-03-29 11:07:48 -0400285 func(self.default, owner, name)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400286
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500287
Eric V. Smithf199bc62018-03-18 20:40:34 -0400288class _DataclassParams:
289 __slots__ = ('init',
290 'repr',
291 'eq',
292 'order',
293 'unsafe_hash',
294 'frozen',
295 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400296
Eric V. Smithf199bc62018-03-18 20:40:34 -0400297 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
298 self.init = init
299 self.repr = repr
300 self.eq = eq
301 self.order = order
302 self.unsafe_hash = unsafe_hash
303 self.frozen = frozen
304
305 def __repr__(self):
306 return ('_DataclassParams('
Eric V. Smith30590422018-05-14 17:16:52 -0400307 f'init={self.init!r},'
308 f'repr={self.repr!r},'
309 f'eq={self.eq!r},'
310 f'order={self.order!r},'
311 f'unsafe_hash={self.unsafe_hash!r},'
312 f'frozen={self.frozen!r}'
Eric V. Smithf199bc62018-03-18 20:40:34 -0400313 ')')
314
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400315
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500316# This function is used instead of exposing Field creation directly,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400317# so that a type checker can be told (via overloads) that this is a
318# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500319def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500320 hash=None, compare=True, metadata=None):
321 """Return an object to identify dataclass fields.
322
Eric V. Smithf8e75492018-05-16 05:14:53 -0400323 default is the default value of the field. default_factory is a
324 0-argument function called to initialize a field's value. If init
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500325 is True, the field will be a parameter to the class's __init__()
Eric V. Smithf8e75492018-05-16 05:14:53 -0400326 function. If repr is True, the field will be included in the
327 object's repr(). If hash is True, the field will be included in
328 the object's hash(). If compare is True, the field will be used
329 in comparison functions. metadata, if specified, must be a
330 mapping which is stored but not otherwise examined by dataclass.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500331
332 It is an error to specify both default and default_factory.
333 """
334
Eric V. Smith03220fd2017-12-29 13:59:58 -0500335 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500336 raise ValueError('cannot specify both default and default_factory')
337 return Field(default, default_factory, init, repr, hash, compare,
338 metadata)
339
340
341def _tuple_str(obj_name, fields):
342 # Return a string representing each field of obj_name as a tuple
Eric V. Smithf8e75492018-05-16 05:14:53 -0400343 # member. So, if fields is ['x', 'y'] and obj_name is "self",
344 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500345
346 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500347 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500348 return '()'
349 # Note the trailing comma, needed if this turns out to be a 1-tuple.
350 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
351
352
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530353# This function's logic is copied from "recursive_repr" function in
354# reprlib module to avoid dependency.
355def _recursive_repr(user_function):
356 # Decorator to make a repr function return "..." for a recursive
357 # call.
358 repr_running = set()
359
360 @functools.wraps(user_function)
361 def wrapper(self):
362 key = id(self), _thread.get_ident()
363 if key in repr_running:
364 return '...'
365 repr_running.add(key)
366 try:
367 result = user_function(self)
368 finally:
369 repr_running.discard(key)
370 return result
371 return wrapper
372
373
Eric V. Smithea8fc522018-01-27 19:07:40 -0500374def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500375 return_type=MISSING):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400376 # Note that we mutate locals when exec() is called. Caller
377 # beware! The only callers are internal to this module, so no
378 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500379 if locals is None:
380 locals = {}
Yury Selivanovd219cc42019-12-09 09:54:20 -0500381 if 'BUILTINS' not in locals:
382 locals['BUILTINS'] = builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500383 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500384 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500385 locals['_return_type'] = return_type
386 return_annotation = '->_return_type'
387 args = ','.join(args)
Yury Selivanovd219cc42019-12-09 09:54:20 -0500388 body = '\n'.join(f' {b}' for b in body)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500389
Eric V. Smithf199bc62018-03-18 20:40:34 -0400390 # Compute the text of the entire function.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500391 txt = f' def {name}({args}){return_annotation}:\n{body}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500392
Yury Selivanovd219cc42019-12-09 09:54:20 -0500393 local_vars = ', '.join(locals.keys())
394 txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
395
396 ns = {}
397 exec(txt, globals, ns)
398 return ns['__create_fn__'](**locals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500399
400
401def _field_assign(frozen, name, value, self_name):
402 # If we're a frozen class, then assign to our fields in __init__
Eric V. Smithf8e75492018-05-16 05:14:53 -0400403 # via object.__setattr__. Otherwise, just use a simple
404 # assignment.
405 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500406 # self_name is what "self" is called in this function: don't
Eric V. Smithf8e75492018-05-16 05:14:53 -0400407 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500408 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500409 return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500410 return f'{self_name}.{name}={value}'
411
412
413def _field_init(f, frozen, globals, self_name):
414 # Return the text of the line in the body of __init__ that will
Eric V. Smithf8e75492018-05-16 05:14:53 -0400415 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500416
417 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500418 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500419 if f.init:
420 # This field has a default factory. If a parameter is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400421 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500422 globals[default_name] = f.default_factory
423 value = (f'{default_name}() '
424 f'if {f.name} is _HAS_DEFAULT_FACTORY '
425 f'else {f.name}')
426 else:
427 # This is a field that's not in the __init__ params, but
Eric V. Smithf8e75492018-05-16 05:14:53 -0400428 # has a default factory function. It needs to be
429 # initialized here by calling the factory function,
430 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500431
432 # For a field initialized with a default=defaultvalue, the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400433 # class dict just has the default value
434 # (cls.fieldname=defaultvalue). But that won't work for a
435 # default factory, the factory must be called in __init__
436 # and we must assign that to self.fieldname. We can't
437 # fall back to the class dict's value, both because it's
438 # not set, and because it might be different per-class
439 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500440
441 globals[default_name] = f.default_factory
442 value = f'{default_name}()'
443 else:
444 # No default factory.
445 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500446 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500447 # There's no default, just do an assignment.
448 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500449 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500450 globals[default_name] = f.default
451 value = f.name
452 else:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400453 # This field does not need initialization. Signify that
454 # to the caller by returning None.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500455 return None
456
457 # Only test this now, so that we can create variables for the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400458 # default. However, return None to signify that we're not going
459 # to actually do the assignment statement for InitVars.
Eric V. Smithe7adf2b2018-06-07 14:43:59 -0400460 if f._field_type is _FIELD_INITVAR:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500461 return None
462
463 # Now, actually generate the field assignment.
464 return _field_assign(frozen, f.name, value, self_name)
465
466
467def _init_param(f):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400468 # Return the __init__ parameter string for this field. For
469 # example, the equivalent of 'x:int=3' (except instead of 'int',
470 # reference a variable set to int, and instead of '3', reference a
471 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500472 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400473 # There's no default, and no default_factory, just output the
474 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500475 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500476 elif f.default is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400477 # There's a default, this will be the name that's used to look
478 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500479 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500480 elif f.default_factory is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400481 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500482 default = '=_HAS_DEFAULT_FACTORY'
483 return f'{f.name}:_type_{f.name}{default}'
484
485
Yury Selivanovd219cc42019-12-09 09:54:20 -0500486def _init_fn(fields, frozen, has_post_init, self_name, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500487 # fields contains both real fields and InitVar pseudo-fields.
488
489 # Make sure we don't have fields without defaults following fields
Eric V. Smithf8e75492018-05-16 05:14:53 -0400490 # with defaults. This actually would be caught when exec-ing the
491 # function source code, but catching it here gives a better error
492 # message, and future-proofs us in case we build up the function
493 # using ast.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500494 seen_default = False
495 for f in fields:
496 # Only consider fields in the __init__ call.
497 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500498 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500499 seen_default = True
500 elif seen_default:
501 raise TypeError(f'non-default argument {f.name!r} '
502 'follows default argument')
503
Yury Selivanovd219cc42019-12-09 09:54:20 -0500504 locals = {f'_type_{f.name}': f.type for f in fields}
505 locals.update({
506 'MISSING': MISSING,
507 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
508 })
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500509
510 body_lines = []
511 for f in fields:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500512 line = _field_init(f, frozen, locals, self_name)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400513 # line is None means that this field doesn't require
Eric V. Smithf8e75492018-05-16 05:14:53 -0400514 # initialization (it's a pseudo-field). Just skip it.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400515 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500516 body_lines.append(line)
517
518 # Does this class have a post-init function?
519 if has_post_init:
520 params_str = ','.join(f.name for f in fields
521 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400522 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500523
524 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500525 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500526 body_lines = ['pass']
527
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500528 return _create_fn('__init__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400529 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500530 body_lines,
531 locals=locals,
532 globals=globals,
533 return_type=None)
534
535
Yury Selivanovd219cc42019-12-09 09:54:20 -0500536def _repr_fn(fields, globals):
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530537 fn = _create_fn('__repr__',
538 ('self',),
539 ['return self.__class__.__qualname__ + f"(' +
540 ', '.join([f"{f.name}={{self.{f.name}!r}}"
541 for f in fields]) +
Yury Selivanovd219cc42019-12-09 09:54:20 -0500542 ')"'],
543 globals=globals)
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530544 return _recursive_repr(fn)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500545
546
Yury Selivanovd219cc42019-12-09 09:54:20 -0500547def _frozen_get_del_attr(cls, fields, globals):
548 locals = {'cls': cls,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400549 'FrozenInstanceError': FrozenInstanceError}
550 if fields:
551 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
552 else:
553 # Special case for the zero-length tuple.
554 fields_str = '()'
555 return (_create_fn('__setattr__',
556 ('self', 'name', 'value'),
557 (f'if type(self) is cls or name in {fields_str}:',
558 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
559 f'super(cls, self).__setattr__(name, value)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500560 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400561 globals=globals),
562 _create_fn('__delattr__',
563 ('self', 'name'),
564 (f'if type(self) is cls or name in {fields_str}:',
565 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
566 f'super(cls, self).__delattr__(name)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500567 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400568 globals=globals),
569 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500570
571
Yury Selivanovd219cc42019-12-09 09:54:20 -0500572def _cmp_fn(name, op, self_tuple, other_tuple, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500573 # Create a comparison function. If the fields in the object are
Eric V. Smithf8e75492018-05-16 05:14:53 -0400574 # named 'x' and 'y', then self_tuple is the string
575 # '(self.x,self.y)' and other_tuple is the string
576 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500577
578 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400579 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500580 [ 'if other.__class__ is self.__class__:',
581 f' return {self_tuple}{op}{other_tuple}',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500582 'return NotImplemented'],
583 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500584
585
Yury Selivanovd219cc42019-12-09 09:54:20 -0500586def _hash_fn(fields, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500587 self_tuple = _tuple_str('self', fields)
588 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400589 ('self',),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500590 [f'return hash({self_tuple})'],
591 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500592
593
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400594def _is_classvar(a_type, typing):
Eric V. Smith92858352018-05-16 07:24:00 -0400595 # This test uses a typing internal class, but it's the best way to
596 # test if this is a ClassVar.
597 return (a_type is typing.ClassVar
598 or (type(a_type) is typing._GenericAlias
599 and a_type.__origin__ is typing.ClassVar))
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400600
601
602def _is_initvar(a_type, dataclasses):
603 # The module we're checking against is the module we're
604 # currently in (dataclasses.py).
Augusto Hack01ee12b2019-06-02 23:14:48 -0300605 return (a_type is dataclasses.InitVar
606 or type(a_type) is dataclasses.InitVar)
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400607
608
609def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
610 # Given a type annotation string, does it refer to a_type in
611 # a_module? For example, when checking that annotation denotes a
612 # ClassVar, then a_module is typing, and a_type is
613 # typing.ClassVar.
614
615 # It's possible to look up a_module given a_type, but it involves
616 # looking in sys.modules (again!), and seems like a waste since
617 # the caller already knows a_module.
618
619 # - annotation is a string type annotation
620 # - cls is the class that this annotation was found in
621 # - a_module is the module we want to match
622 # - a_type is the type in that module we want to match
623 # - is_type_predicate is a function called with (obj, a_module)
624 # that determines if obj is of the desired type.
625
626 # Since this test does not do a local namespace lookup (and
627 # instead only a module (global) lookup), there are some things it
628 # gets wrong.
629
Eric V. Smithf8e75492018-05-16 05:14:53 -0400630 # With string annotations, cv0 will be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400631 # CV = ClassVar
632 # @dataclass
633 # class C0:
634 # cv0: CV
635
Eric V. Smithf8e75492018-05-16 05:14:53 -0400636 # But in this example cv1 will not be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400637 # @dataclass
638 # class C1:
639 # CV = ClassVar
640 # cv1: CV
641
Eric V. Smithf8e75492018-05-16 05:14:53 -0400642 # In C1, the code in this function (_is_type) will look up "CV" in
643 # the module and not find it, so it will not consider cv1 as a
644 # ClassVar. This is a fairly obscure corner case, and the best
645 # way to fix it would be to eval() the string "CV" with the
646 # correct global and local namespaces. However that would involve
647 # a eval() penalty for every single field of every dataclass
648 # that's defined. It was judged not worth it.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400649
650 match = _MODULE_IDENTIFIER_RE.match(annotation)
651 if match:
652 ns = None
653 module_name = match.group(1)
654 if not module_name:
655 # No module name, assume the class's module did
656 # "from dataclasses import InitVar".
657 ns = sys.modules.get(cls.__module__).__dict__
658 else:
659 # Look up module_name in the class's module.
660 module = sys.modules.get(cls.__module__)
661 if module and module.__dict__.get(module_name) is a_module:
662 ns = sys.modules.get(a_type.__module__).__dict__
663 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
664 return True
665 return False
666
667
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500668def _get_field(cls, a_name, a_type):
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400669 # Return a Field object for this field name and type. ClassVars
Eric V. Smithf8e75492018-05-16 05:14:53 -0400670 # and InitVars are also returned, but marked as such (see
671 # f._field_type).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500672
Eric V. Smithf8e75492018-05-16 05:14:53 -0400673 # If the default value isn't derived from Field, then it's only a
674 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500675 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500676 if isinstance(default, Field):
677 f = default
678 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400679 if isinstance(default, types.MemberDescriptorType):
680 # This is a field in __slots__, so it has no default value.
681 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500682 f = field(default=default)
683
Eric V. Smithf8e75492018-05-16 05:14:53 -0400684 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500685 f.name = a_name
686 f.type = a_type
687
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400688 # Assume it's a normal field until proven otherwise. We're next
Eric V. Smithf8e75492018-05-16 05:14:53 -0400689 # going to decide if it's a ClassVar or InitVar, everything else
690 # is just a normal field.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400691 f._field_type = _FIELD
692
693 # In addition to checking for actual types here, also check for
Eric V. Smithf8e75492018-05-16 05:14:53 -0400694 # string annotations. get_type_hints() won't always work for us
695 # (see https://github.com/python/typing/issues/508 for example),
696 # plus it's expensive and would require an eval for every stirng
697 # annotation. So, make a best effort to see if this is a ClassVar
698 # or InitVar using regex's and checking that the thing referenced
699 # is actually of the correct type.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400700
701 # For the complete discussion, see https://bugs.python.org/issue33453
702
703 # If typing has not been imported, then it's impossible for any
Eric V. Smithf8e75492018-05-16 05:14:53 -0400704 # annotation to be a ClassVar. So, only look for ClassVar if
705 # typing has been imported by any module (not necessarily cls's
706 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500707 typing = sys.modules.get('typing')
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400708 if typing:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400709 if (_is_classvar(a_type, typing)
710 or (isinstance(f.type, str)
711 and _is_type(f.type, cls, typing, typing.ClassVar,
712 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500713 f._field_type = _FIELD_CLASSVAR
714
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400715 # If the type is InitVar, or if it's a matching string annotation,
716 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500717 if f._field_type is _FIELD:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400718 # The module we're checking against is the module we're
719 # currently in (dataclasses.py).
720 dataclasses = sys.modules[__name__]
721 if (_is_initvar(a_type, dataclasses)
722 or (isinstance(f.type, str)
723 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
724 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500725 f._field_type = _FIELD_INITVAR
726
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400727 # Validations for individual fields. This is delayed until now,
728 # instead of in the Field() constructor, since only here do we
729 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500730
731 # Special restrictions for ClassVar and InitVar.
732 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500733 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500734 raise TypeError(f'field {f.name} cannot have a '
735 'default factory')
736 # Should I check for other field settings? default_factory
Eric V. Smithf8e75492018-05-16 05:14:53 -0400737 # seems the most serious to check for. Maybe add others. For
738 # example, how about init=False (or really,
739 # init=<not-the-default-init-value>)? It makes no sense for
740 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500741
742 # For real fields, disallow mutable defaults for known types.
743 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
744 raise ValueError(f'mutable default {type(f.default)} for field '
745 f'{f.name} is not allowed: use default_factory')
746
747 return f
748
749
Eric V. Smithea8fc522018-01-27 19:07:40 -0500750def _set_new_attribute(cls, name, value):
751 # Never overwrites an existing attribute. Returns True if the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400752 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500753 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500754 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500755 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500756 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500757
758
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500759# Decide if/how we're going to create a hash function. Key is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400760# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
761# take. The common case is to do nothing, so instead of providing a
762# function that is a no-op, use None to signify that.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400763
Yury Selivanovd219cc42019-12-09 09:54:20 -0500764def _hash_set_none(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400765 return None
766
Yury Selivanovd219cc42019-12-09 09:54:20 -0500767def _hash_add(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400768 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
Yury Selivanovd219cc42019-12-09 09:54:20 -0500769 return _hash_fn(flds, globals)
Eric V. Smith01d618c2018-03-24 22:10:14 -0400770
Yury Selivanovd219cc42019-12-09 09:54:20 -0500771def _hash_exception(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400772 # Raise an exception.
773 raise TypeError(f'Cannot overwrite attribute __hash__ '
774 f'in class {cls.__name__}')
775
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500776#
777# +-------------------------------------- unsafe_hash?
778# | +------------------------------- eq?
779# | | +------------------------ frozen?
780# | | | +---------------- has-explicit-hash?
781# | | | |
782# | | | | +------- action
783# | | | | |
784# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400785_hash_action = {(False, False, False, False): None,
786 (False, False, False, True ): None,
787 (False, False, True, False): None,
788 (False, False, True, True ): None,
789 (False, True, False, False): _hash_set_none,
790 (False, True, False, True ): None,
791 (False, True, True, False): _hash_add,
792 (False, True, True, True ): None,
793 (True, False, False, False): _hash_add,
794 (True, False, False, True ): _hash_exception,
795 (True, False, True, False): _hash_add,
796 (True, False, True, True ): _hash_exception,
797 (True, True, False, False): _hash_add,
798 (True, True, False, True ): _hash_exception,
799 (True, True, True, False): _hash_add,
800 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500801 }
802# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Eric V. Smithf8e75492018-05-16 05:14:53 -0400803# version of this table.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500804
805
Eric V. Smithf199bc62018-03-18 20:40:34 -0400806def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500807 # Now that dicts retain insertion order, there's no reason to use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400808 # an ordered dict. I am leveraging that ordering here, because
809 # derived class fields overwrite base class fields, but the order
810 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500811 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500812
Yury Selivanovd219cc42019-12-09 09:54:20 -0500813 if cls.__module__ in sys.modules:
814 globals = sys.modules[cls.__module__].__dict__
815 else:
816 # Theoretically this can happen if someone writes
817 # a custom string to cls.__module__. In which case
818 # such dataclass won't be fully introspectable
819 # (w.r.t. typing.get_type_hints) but will still function
820 # correctly.
821 globals = {}
822
Eric V. Smithf199bc62018-03-18 20:40:34 -0400823 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
824 unsafe_hash, frozen))
825
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500826 # Find our base classes in reverse MRO order, and exclude
Eric V. Smithf8e75492018-05-16 05:14:53 -0400827 # ourselves. In reversed order so that more derived classes
828 # override earlier field definitions in base classes. As long as
829 # we're iterating over them, see if any are frozen.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400830 any_frozen_base = False
831 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500832 for b in cls.__mro__[-1:0:-1]:
833 # Only process classes that have been processed by our
Eric V. Smithf8e75492018-05-16 05:14:53 -0400834 # decorator. That is, they have a _FIELDS attribute.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400835 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500836 if base_fields:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400837 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500838 for f in base_fields.values():
839 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400840 if getattr(b, _PARAMS).frozen:
841 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500842
Eric V. Smith56970b82018-03-22 16:28:48 -0400843 # Annotations that are defined in this class (not in base
Eric V. Smithf8e75492018-05-16 05:14:53 -0400844 # classes). If __annotations__ isn't present, then this class
845 # adds no new annotations. We use this to compute fields that are
846 # added by this class.
847 #
Eric V. Smith56970b82018-03-22 16:28:48 -0400848 # Fields are found from cls_annotations, which is guaranteed to be
Eric V. Smithf8e75492018-05-16 05:14:53 -0400849 # ordered. Default values are from class attributes, if a field
850 # has a default. If the default value is a Field(), then it
851 # contains additional info beyond (and possibly including) the
852 # actual default value. Pseudo-fields ClassVars and InitVars are
853 # included, despite the fact that they're not real fields. That's
854 # dealt with later.
Eric V. Smith56970b82018-03-22 16:28:48 -0400855 cls_annotations = cls.__dict__.get('__annotations__', {})
856
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500857 # Now find fields in our class. While doing so, validate some
Eric V. Smithf8e75492018-05-16 05:14:53 -0400858 # things, and set the default values (as class attributes) where
859 # we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400860 cls_fields = [_get_field(cls, name, type)
861 for name, type in cls_annotations.items()]
862 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500863 fields[f.name] = f
864
Eric V. Smithf8e75492018-05-16 05:14:53 -0400865 # If the class attribute (which is the default value for this
866 # field) exists and is of type 'Field', replace it with the
867 # real default. This is so that normal class introspection
868 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500869 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500870 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500871 # If there's no default, delete the class attribute.
Eric V. Smithf8e75492018-05-16 05:14:53 -0400872 # This happens if we specify field(repr=False), for
873 # example (that is, we specified a field object, but
874 # no default value). Also if we're using a default
875 # factory. The class attribute should not be set at
876 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500877 delattr(cls, f.name)
878 else:
879 setattr(cls, f.name, f.default)
880
Eric V. Smith56970b82018-03-22 16:28:48 -0400881 # Do we have any Field members that don't also have annotations?
882 for name, value in cls.__dict__.items():
883 if isinstance(value, Field) and not name in cls_annotations:
884 raise TypeError(f'{name!r} is a field but has no type annotation')
885
Eric V. Smithf199bc62018-03-18 20:40:34 -0400886 # Check rules that apply if we are derived from any dataclasses.
887 if has_dataclass_bases:
888 # Raise an exception if any of our bases are frozen, but we're not.
889 if any_frozen_base and not frozen:
890 raise TypeError('cannot inherit non-frozen dataclass from a '
891 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500892
Eric V. Smithf199bc62018-03-18 20:40:34 -0400893 # Raise an exception if we're frozen, but none of our bases are.
894 if not any_frozen_base and frozen:
895 raise TypeError('cannot inherit frozen dataclass from a '
896 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500897
Eric V. Smithf8e75492018-05-16 05:14:53 -0400898 # Remember all of the fields on our class (including bases). This
899 # also marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400900 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500901
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500902 # Was this class defined with an explicit __hash__? Note that if
Eric V. Smithf8e75492018-05-16 05:14:53 -0400903 # __eq__ is defined in this class, then python will automatically
904 # set __hash__ to None. This is a heuristic, as it's possible
905 # that such a __hash__ == None was not auto-generated, but it
906 # close enough.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500907 class_hash = cls.__dict__.get('__hash__', MISSING)
908 has_explicit_hash = not (class_hash is MISSING or
909 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500910
Eric V. Smithf8e75492018-05-16 05:14:53 -0400911 # If we're generating ordering methods, we must be generating the
912 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500913 if order and not eq:
914 raise ValueError('eq must be true if order is true')
915
916 if init:
917 # Does this class have a post-init function?
918 has_post_init = hasattr(cls, _POST_INIT_NAME)
919
920 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500921 flds = [f for f in fields.values()
922 if f._field_type in (_FIELD, _FIELD_INITVAR)]
923 _set_new_attribute(cls, '__init__',
924 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500925 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500926 has_post_init,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400927 # The name to use for the "self"
928 # param in __init__. Use "self"
929 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500930 '__dataclass_self__' if 'self' in fields
931 else 'self',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500932 globals,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500933 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500934
935 # Get the fields as a list, and include only real fields. This is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400936 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500937 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500938
939 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500940 flds = [f for f in field_list if f.repr]
Yury Selivanovd219cc42019-12-09 09:54:20 -0500941 _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500942
943 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500944 # Create _eq__ method. There's no need for a __ne__ method,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400945 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500946 flds = [f for f in field_list if f.compare]
947 self_tuple = _tuple_str('self', flds)
948 other_tuple = _tuple_str('other', flds)
949 _set_new_attribute(cls, '__eq__',
950 _cmp_fn('__eq__', '==',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500951 self_tuple, other_tuple,
952 globals=globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500953
954 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500955 # Create and set the ordering methods.
956 flds = [f for f in field_list if f.compare]
957 self_tuple = _tuple_str('self', flds)
958 other_tuple = _tuple_str('other', flds)
959 for name, op in [('__lt__', '<'),
960 ('__le__', '<='),
961 ('__gt__', '>'),
962 ('__ge__', '>='),
963 ]:
964 if _set_new_attribute(cls, name,
Yury Selivanovd219cc42019-12-09 09:54:20 -0500965 _cmp_fn(name, op, self_tuple, other_tuple,
966 globals=globals)):
Eric V. Smithea8fc522018-01-27 19:07:40 -0500967 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500968 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500969 'functools.total_ordering')
970
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500971 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500972 for fn in _frozen_get_del_attr(cls, field_list, globals):
Eric V. Smithf199bc62018-03-18 20:40:34 -0400973 if _set_new_attribute(cls, fn.__name__, fn):
974 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500975 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500976
977 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500978 hash_action = _hash_action[bool(unsafe_hash),
979 bool(eq),
980 bool(frozen),
981 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -0400982 if hash_action:
983 # No need to call _set_new_attribute here, since by the time
Eric V. Smithf8e75492018-05-16 05:14:53 -0400984 # we're here the overwriting is unconditional.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500985 cls.__hash__ = hash_action(cls, field_list, globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500986
987 if not getattr(cls, '__doc__'):
988 # Create a class doc-string.
989 cls.__doc__ = (cls.__name__ +
990 str(inspect.signature(cls)).replace(' -> None', ''))
991
992 return cls
993
994
Serhiy Storchaka2085bd02019-06-01 11:00:15 +0300995def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -0500996 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500997 """Returns the same class as was passed in, with dunder methods
998 added based on the fields defined in the class.
999
1000 Examines PEP 526 __annotations__ to determine fields.
1001
1002 If init is true, an __init__() method is added to the class. If
1003 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001004 comparison dunder methods are added. If unsafe_hash is true, a
1005 __hash__() method function is added. If frozen is true, fields may
1006 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001007 """
1008
1009 def wrap(cls):
Eric V. Smithf199bc62018-03-18 20:40:34 -04001010 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001011
1012 # See if we're being called as @dataclass or @dataclass().
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001013 if cls is None:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001014 # We're called with parens.
1015 return wrap
1016
1017 # We're called as @dataclass without parens.
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001018 return wrap(cls)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001019
1020
1021def fields(class_or_instance):
1022 """Return a tuple describing the fields of this dataclass.
1023
1024 Accepts a dataclass or an instance of one. Tuple elements are of
1025 type Field.
1026 """
1027
1028 # Might it be worth caching this, per class?
1029 try:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001030 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001031 except AttributeError:
1032 raise TypeError('must be called with a dataclass type or instance')
1033
Eric V. Smithd1388922018-01-07 14:30:17 -05001034 # Exclude pseudo-fields. Note that fields is sorted by insertion
Eric V. Smithf8e75492018-05-16 05:14:53 -04001035 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001036 return tuple(f for f in fields.values() if f._field_type is _FIELD)
1037
1038
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001039def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001040 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001041 return hasattr(type(obj), _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001042
1043
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001044def is_dataclass(obj):
1045 """Returns True if obj is a dataclass or an instance of a
1046 dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001047 cls = obj if isinstance(obj, type) else type(obj)
1048 return hasattr(cls, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001049
1050
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001051def asdict(obj, *, dict_factory=dict):
1052 """Return the fields of a dataclass instance as a new dictionary mapping
1053 field names to field values.
1054
1055 Example usage:
1056
1057 @dataclass
1058 class C:
1059 x: int
1060 y: int
1061
1062 c = C(1, 2)
1063 assert asdict(c) == {'x': 1, 'y': 2}
1064
1065 If given, 'dict_factory' will be used instead of built-in dict.
1066 The function applies recursively to field values that are
1067 dataclass instances. This will also look into built-in containers:
1068 tuples, lists, and dicts.
1069 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001070 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001071 raise TypeError("asdict() should be called on dataclass instances")
1072 return _asdict_inner(obj, dict_factory)
1073
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001074
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001075def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001076 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001077 result = []
1078 for f in fields(obj):
1079 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1080 result.append((f.name, value))
1081 return dict_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001082 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1083 # obj is a namedtuple. Recurse into it, but the returned
1084 # object is another namedtuple of the same type. This is
1085 # similar to how other list- or tuple-derived classes are
1086 # treated (see below), but we just need to create them
1087 # differently because a namedtuple's __init__ needs to be
1088 # called differently (see bpo-34363).
1089
1090 # I'm not using namedtuple's _asdict()
1091 # method, because:
1092 # - it does not recurse in to the namedtuple fields and
1093 # convert them to dicts (using dict_factory).
1094 # - I don't actually want to return a dict here. The the main
1095 # use case here is json.dumps, and it handles converting
1096 # namedtuples to lists. Admittedly we're losing some
1097 # information here when we produce a json list instead of a
1098 # dict. Note that if we returned dicts here instead of
1099 # namedtuples, we could no longer call asdict() on a data
1100 # structure where a namedtuple was used as a dict key.
1101
1102 return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001103 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001104 # Assume we can create an object of this type by passing in a
1105 # generator (which is not true for namedtuples, handled
1106 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001107 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1108 elif isinstance(obj, dict):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001109 return type(obj)((_asdict_inner(k, dict_factory),
1110 _asdict_inner(v, dict_factory))
1111 for k, v in obj.items())
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001112 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001113 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001114
1115
1116def astuple(obj, *, tuple_factory=tuple):
1117 """Return the fields of a dataclass instance as a new tuple of field values.
1118
1119 Example usage::
1120
1121 @dataclass
1122 class C:
1123 x: int
1124 y: int
1125
1126 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001127 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001128
1129 If given, 'tuple_factory' will be used instead of built-in tuple.
1130 The function applies recursively to field values that are
1131 dataclass instances. This will also look into built-in containers:
1132 tuples, lists, and dicts.
1133 """
1134
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001135 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001136 raise TypeError("astuple() should be called on dataclass instances")
1137 return _astuple_inner(obj, tuple_factory)
1138
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001139
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001140def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001141 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001142 result = []
1143 for f in fields(obj):
1144 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1145 result.append(value)
1146 return tuple_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001147 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1148 # obj is a namedtuple. Recurse into it, but the returned
1149 # object is another namedtuple of the same type. This is
1150 # similar to how other list- or tuple-derived classes are
1151 # treated (see below), but we just need to create them
1152 # differently because a namedtuple's __init__ needs to be
1153 # called differently (see bpo-34363).
1154 return type(obj)(*[_astuple_inner(v, tuple_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001155 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001156 # Assume we can create an object of this type by passing in a
1157 # generator (which is not true for namedtuples, handled
1158 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001159 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1160 elif isinstance(obj, dict):
1161 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1162 for k, v in obj.items())
1163 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001164 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001165
1166
Eric V. Smithd80b4432018-01-06 17:09:58 -05001167def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001168 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001169 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001170 """Return a new dynamically created dataclass.
1171
Eric V. Smithed7d4292018-01-06 16:14:03 -05001172 The dataclass name will be 'cls_name'. 'fields' is an iterable
1173 of either (name), (name, type) or (name, type, Field) objects. If type is
1174 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001175 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001176
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001177 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001178
1179 is equivalent to:
1180
1181 @dataclass
1182 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001183 x: 'typing.Any'
1184 y: int
1185 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001186
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001187 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001188
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001189 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001190 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001191 """
1192
1193 if namespace is None:
1194 namespace = {}
1195 else:
1196 # Copy namespace since we're going to mutate it.
1197 namespace = namespace.copy()
1198
Eric V. Smith4e812962018-05-16 11:31:29 -04001199 # While we're looking through the field names, validate that they
1200 # are identifiers, are not keywords, and not duplicates.
1201 seen = set()
Eric V. Smithd1388922018-01-07 14:30:17 -05001202 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001203 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001204 if isinstance(item, str):
1205 name = item
1206 tp = 'typing.Any'
1207 elif len(item) == 2:
1208 name, tp, = item
1209 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001210 name, tp, spec = item
1211 namespace[name] = spec
Eric V. Smith4e812962018-05-16 11:31:29 -04001212 else:
1213 raise TypeError(f'Invalid field: {item!r}')
1214
1215 if not isinstance(name, str) or not name.isidentifier():
Min ho Kim96e12d52019-07-22 06:12:33 +10001216 raise TypeError(f'Field names must be valid identifiers: {name!r}')
Eric V. Smith4e812962018-05-16 11:31:29 -04001217 if keyword.iskeyword(name):
1218 raise TypeError(f'Field names must not be keywords: {name!r}')
1219 if name in seen:
1220 raise TypeError(f'Field name duplicated: {name!r}')
1221
1222 seen.add(name)
Eric V. Smithed7d4292018-01-06 16:14:03 -05001223 anns[name] = tp
1224
1225 namespace['__annotations__'] = anns
Ivan Levkivskyi5a7092d2018-03-31 13:41:17 +01001226 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1227 # of generic dataclassses.
1228 cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace))
Eric V. Smithd80b4432018-01-06 17:09:58 -05001229 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001230 unsafe_hash=unsafe_hash, frozen=frozen)
1231
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001232
Serhiy Storchaka2d88e632019-06-26 19:07:44 +03001233def replace(obj, /, **changes):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001234 """Return a new object replacing specified fields with new values.
1235
1236 This is especially useful for frozen classes. Example usage:
1237
1238 @dataclass(frozen=True)
1239 class C:
1240 x: int
1241 y: int
1242
1243 c = C(1, 2)
1244 c1 = replace(c, x=3)
1245 assert c1.x == 3 and c1.y == 2
1246 """
1247
Eric V. Smithf8e75492018-05-16 05:14:53 -04001248 # We're going to mutate 'changes', but that's okay because it's a
1249 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001250
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001251 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001252 raise TypeError("replace() should be called on dataclass instances")
1253
1254 # It's an error to have init=False fields in 'changes'.
1255 # If a field is not in 'changes', read its value from the provided obj.
1256
Eric V. Smithf199bc62018-03-18 20:40:34 -04001257 for f in getattr(obj, _FIELDS).values():
Eric V. Smithe7adf2b2018-06-07 14:43:59 -04001258 # Only consider normal fields or InitVars.
1259 if f._field_type is _FIELD_CLASSVAR:
1260 continue
1261
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001262 if not f.init:
1263 # Error if this field is specified in changes.
1264 if f.name in changes:
1265 raise ValueError(f'field {f.name} is declared with '
1266 'init=False, it cannot be specified with '
1267 'replace()')
1268 continue
1269
1270 if f.name not in changes:
Dong-hee Na3d70f7a2018-06-23 23:46:32 +09001271 if f._field_type is _FIELD_INITVAR:
1272 raise ValueError(f"InitVar {f.name!r} "
1273 'must be specified with replace()')
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001274 changes[f.name] = getattr(obj, f.name)
1275
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001276 # Create the new object, which calls __init__() and
Eric V. Smithf8e75492018-05-16 05:14:53 -04001277 # __post_init__() (if defined), using all of the init fields we've
1278 # added and/or left in 'changes'. If there are values supplied in
1279 # changes that aren't fields, this will correctly raise a
1280 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001281 return obj.__class__(**changes)