blob: 422a95cebe8534e70009b267299d3fb949e916d6 [file] [log] [blame]
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001import re
Eric V. Smithf0db54a2017-12-04 16:58:55 -05002import sys
Eric V. Smithf96ddad2018-03-24 17:20:26 -04003import copy
Eric V. Smithf0db54a2017-12-04 16:58:55 -05004import types
Eric V. Smithf0db54a2017-12-04 16:58:55 -05005import inspect
Eric V. Smith4e812962018-05-16 11:31:29 -04006import keyword
Vadim Pushtaev4d12e4d2018-08-12 14:46:05 +03007import builtins
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +05308import functools
Ben Avrahamibef7d292020-10-06 20:40:50 +03009import abc
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +053010import _thread
Batuhan Taskayac7437e22020-10-21 16:49:22 +030011from types import FunctionType, GenericAlias
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +053012
Eric V. Smithf0db54a2017-12-04 16:58:55 -050013
14__all__ = ['dataclass',
15 'field',
Eric V. Smith8e4560a2018-03-21 17:10:22 -040016 'Field',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050017 'FrozenInstanceError',
18 'InitVar',
Eric V. Smith03220fd2017-12-29 13:59:58 -050019 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050020
21 # Helper functions.
22 'fields',
23 'asdict',
24 'astuple',
25 'make_dataclass',
26 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050027 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050028 ]
29
Eric V. Smithea8fc522018-01-27 19:07:40 -050030# Conditions for adding methods. The boxes indicate what action the
Eric V. Smithf8e75492018-05-16 05:14:53 -040031# dataclass decorator takes. For all of these tables, when I talk
32# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
33# referring to the arguments to the @dataclass decorator. When
34# checking if a dunder method already exists, I mean check for an
35# entry in the class's __dict__. I never check to see if an attribute
36# is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050037
38# Key:
39# +=========+=========================================+
40# + Value | Meaning |
41# +=========+=========================================+
42# | <blank> | No action: no method is added. |
43# +---------+-----------------------------------------+
44# | add | Generated method is added. |
45# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050046# | raise | TypeError is raised. |
47# +---------+-----------------------------------------+
48# | None | Attribute is set to None. |
49# +=========+=========================================+
50
51# __init__
52#
53# +--- init= parameter
54# |
55# v | | |
56# | no | yes | <--- class has __init__ in __dict__?
57# +=======+=======+=======+
58# | False | | |
59# +-------+-------+-------+
60# | True | add | | <- the default
61# +=======+=======+=======+
62
63# __repr__
64#
65# +--- repr= parameter
66# |
67# v | | |
68# | no | yes | <--- class has __repr__ in __dict__?
69# +=======+=======+=======+
70# | False | | |
71# +-------+-------+-------+
72# | True | add | | <- the default
73# +=======+=======+=======+
74
75
76# __setattr__
77# __delattr__
78#
79# +--- frozen= parameter
80# |
81# v | | |
82# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
83# +=======+=======+=======+
84# | False | | | <- the default
85# +-------+-------+-------+
86# | True | add | raise |
87# +=======+=======+=======+
88# Raise because not adding these methods would break the "frozen-ness"
Eric V. Smithf8e75492018-05-16 05:14:53 -040089# of the class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050090
91# __eq__
92#
93# +--- eq= parameter
94# |
95# v | | |
96# | no | yes | <--- class has __eq__ in __dict__?
97# +=======+=======+=======+
98# | False | | |
99# +-------+-------+-------+
100# | True | add | | <- the default
101# +=======+=======+=======+
102
103# __lt__
104# __le__
105# __gt__
106# __ge__
107#
108# +--- order= parameter
109# |
110# v | | |
111# | no | yes | <--- class has any comparison method in __dict__?
112# +=======+=======+=======+
113# | False | | | <- the default
114# +-------+-------+-------+
115# | True | add | raise |
116# +=======+=======+=======+
117# Raise because to allow this case would interfere with using
Eric V. Smithf8e75492018-05-16 05:14:53 -0400118# functools.total_ordering.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500119
120# __hash__
121
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500122# +------------------- unsafe_hash= parameter
123# | +----------- eq= parameter
124# | | +--- frozen= parameter
125# | | |
126# v v v | | |
127# | no | yes | <--- class has explicitly defined __hash__
128# +=======+=======+=======+========+========+
129# | False | False | False | | | No __eq__, use the base class __hash__
130# +-------+-------+-------+--------+--------+
131# | False | False | True | | | No __eq__, use the base class __hash__
132# +-------+-------+-------+--------+--------+
133# | False | True | False | None | | <-- the default, not hashable
134# +-------+-------+-------+--------+--------+
135# | False | True | True | add | | Frozen, so hashable, allows override
136# +-------+-------+-------+--------+--------+
137# | True | False | False | add | raise | Has no __eq__, but hashable
138# +-------+-------+-------+--------+--------+
139# | True | False | True | add | raise | Has no __eq__, but hashable
140# +-------+-------+-------+--------+--------+
141# | True | True | False | add | raise | Not frozen, but hashable
142# +-------+-------+-------+--------+--------+
143# | True | True | True | add | raise | Frozen, so hashable
144# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500145# For boxes that are blank, __hash__ is untouched and therefore
Eric V. Smithf8e75492018-05-16 05:14:53 -0400146# inherited from the base class. If the base is object, then
147# id-based hashing is used.
148#
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400149# Note that a class may already have __hash__=None if it specified an
Eric V. Smithf8e75492018-05-16 05:14:53 -0400150# __eq__ method in the class body (not one that was created by
151# @dataclass).
152#
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500153# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500154
Brandt Bucher145bf262021-02-26 14:51:55 -0800155# __match_args__
156#
157# | no | yes | <--- class has __match_args__ in __dict__?
158# +=======+=======+
159# | add | | <- the default
160# +=======+=======+
161# __match_args__ is always added unless the class already defines it. It is a
162# tuple of __init__ parameter names; non-init fields must be matched by keyword.
163
Eric V. Smithea8fc522018-01-27 19:07:40 -0500164
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500165# Raised when an attempt is made to modify a frozen class.
166class FrozenInstanceError(AttributeError): pass
167
Eric V. Smithf8e75492018-05-16 05:14:53 -0400168# A sentinel object for default values to signal that a default
169# factory will be used. This is given a nice repr() which will appear
170# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500171class _HAS_DEFAULT_FACTORY_CLASS:
172 def __repr__(self):
173 return '<factory>'
174_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
175
Eric V. Smith03220fd2017-12-29 13:59:58 -0500176# A sentinel object to detect if a parameter is supplied or not. Use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400177# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500178class _MISSING_TYPE:
179 pass
180MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500181
182# Since most per-field metadata will be unused, create an empty
Eric V. Smithf8e75492018-05-16 05:14:53 -0400183# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500184_EMPTY_METADATA = types.MappingProxyType({})
185
186# Markers for the various kinds of fields and pseudo-fields.
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400187class _FIELD_BASE:
188 def __init__(self, name):
189 self.name = name
190 def __repr__(self):
191 return self.name
192_FIELD = _FIELD_BASE('_FIELD')
193_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
194_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500195
196# The name of an attribute on the class where we store the Field
Eric V. Smithf8e75492018-05-16 05:14:53 -0400197# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400198_FIELDS = '__dataclass_fields__'
199
200# The name of an attribute on the class that stores the parameters to
201# @dataclass.
202_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500203
204# The name of the function, that if it exists, is called at the end of
205# __init__.
206_POST_INIT_NAME = '__post_init__'
207
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400208# String regex that string annotations for ClassVar or InitVar must match.
209# Allows "identifier.identifier[" or "identifier[".
210# https://bugs.python.org/issue33453 for details.
211_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500212
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300213class InitVar:
Augusto Hack01ee12b2019-06-02 23:14:48 -0300214 __slots__ = ('type', )
215
216 def __init__(self, type):
217 self.type = type
218
219 def __repr__(self):
Samuel Colvin793cb852019-10-13 12:45:36 +0100220 if isinstance(self.type, type):
221 type_name = self.type.__name__
222 else:
223 # typing objects, e.g. List[int]
224 type_name = repr(self.type)
225 return f'dataclasses.InitVar[{type_name}]'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500226
Serhiy Storchakab4d0b392019-09-22 13:32:41 +0300227 def __class_getitem__(cls, type):
228 return InitVar(type)
229
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500230
231# Instances of Field are only ever created from within this module,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400232# and only from the field() function, although Field instances are
233# exposed externally as (conceptually) read-only objects.
234#
235# name and type are filled in after the fact, not in __init__.
236# They're not known at the time this class is instantiated, but it's
237# convenient if they're available later.
238#
Eric V. Smithf199bc62018-03-18 20:40:34 -0400239# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf8e75492018-05-16 05:14:53 -0400240# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500241class Field:
242 __slots__ = ('name',
243 'type',
244 'default',
245 'default_factory',
246 'repr',
247 'hash',
248 'init',
249 'compare',
250 'metadata',
251 '_field_type', # Private: not to be used by user code.
252 )
253
254 def __init__(self, default, default_factory, init, repr, hash, compare,
255 metadata):
256 self.name = None
257 self.type = None
258 self.default = default
259 self.default_factory = default_factory
260 self.init = init
261 self.repr = repr
262 self.hash = hash
263 self.compare = compare
264 self.metadata = (_EMPTY_METADATA
Christopher Huntb01786c2019-02-12 06:50:49 -0500265 if metadata is None else
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500266 types.MappingProxyType(metadata))
267 self._field_type = None
268
269 def __repr__(self):
270 return ('Field('
271 f'name={self.name!r},'
Eric V. Smith2473eea2018-05-14 11:37:28 -0400272 f'type={self.type!r},'
273 f'default={self.default!r},'
274 f'default_factory={self.default_factory!r},'
275 f'init={self.init!r},'
276 f'repr={self.repr!r},'
277 f'hash={self.hash!r},'
278 f'compare={self.compare!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400279 f'metadata={self.metadata!r},'
280 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500281 ')')
282
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400283 # This is used to support the PEP 487 __set_name__ protocol in the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400284 # case where we're using a field that contains a descriptor as a
Artjome55ca3f2018-07-06 02:09:13 +0300285 # default value. For details on __set_name__, see
Eric V. Smithf8e75492018-05-16 05:14:53 -0400286 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
287 #
288 # Note that in _process_class, this Field object is overwritten
289 # with the default value, so the end result is a descriptor that
290 # had __set_name__ called on it at the right time.
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400291 def __set_name__(self, owner, name):
Eric V. Smith52199522018-03-29 11:07:48 -0400292 func = getattr(type(self.default), '__set_name__', None)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400293 if func:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400294 # There is a __set_name__ method on the descriptor, call
295 # it.
Eric V. Smith52199522018-03-29 11:07:48 -0400296 func(self.default, owner, name)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400297
Ethan Smithd01628e2020-04-14 16:14:15 -0700298 __class_getitem__ = classmethod(GenericAlias)
299
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500300
Eric V. Smithf199bc62018-03-18 20:40:34 -0400301class _DataclassParams:
302 __slots__ = ('init',
303 'repr',
304 'eq',
305 'order',
306 'unsafe_hash',
307 'frozen',
308 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400309
Eric V. Smithf199bc62018-03-18 20:40:34 -0400310 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
311 self.init = init
312 self.repr = repr
313 self.eq = eq
314 self.order = order
315 self.unsafe_hash = unsafe_hash
316 self.frozen = frozen
317
318 def __repr__(self):
319 return ('_DataclassParams('
Eric V. Smith30590422018-05-14 17:16:52 -0400320 f'init={self.init!r},'
321 f'repr={self.repr!r},'
322 f'eq={self.eq!r},'
323 f'order={self.order!r},'
324 f'unsafe_hash={self.unsafe_hash!r},'
325 f'frozen={self.frozen!r}'
Eric V. Smithf199bc62018-03-18 20:40:34 -0400326 ')')
327
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400328
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500329# This function is used instead of exposing Field creation directly,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400330# so that a type checker can be told (via overloads) that this is a
331# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500332def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500333 hash=None, compare=True, metadata=None):
334 """Return an object to identify dataclass fields.
335
Eric V. Smithf8e75492018-05-16 05:14:53 -0400336 default is the default value of the field. default_factory is a
337 0-argument function called to initialize a field's value. If init
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500338 is True, the field will be a parameter to the class's __init__()
Eric V. Smithf8e75492018-05-16 05:14:53 -0400339 function. If repr is True, the field will be included in the
340 object's repr(). If hash is True, the field will be included in
341 the object's hash(). If compare is True, the field will be used
342 in comparison functions. metadata, if specified, must be a
343 mapping which is stored but not otherwise examined by dataclass.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500344
345 It is an error to specify both default and default_factory.
346 """
347
Eric V. Smith03220fd2017-12-29 13:59:58 -0500348 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500349 raise ValueError('cannot specify both default and default_factory')
350 return Field(default, default_factory, init, repr, hash, compare,
351 metadata)
352
353
354def _tuple_str(obj_name, fields):
355 # Return a string representing each field of obj_name as a tuple
Eric V. Smithf8e75492018-05-16 05:14:53 -0400356 # member. So, if fields is ['x', 'y'] and obj_name is "self",
357 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500358
359 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500360 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500361 return '()'
362 # Note the trailing comma, needed if this turns out to be a 1-tuple.
363 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
364
365
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530366# This function's logic is copied from "recursive_repr" function in
367# reprlib module to avoid dependency.
368def _recursive_repr(user_function):
369 # Decorator to make a repr function return "..." for a recursive
370 # call.
371 repr_running = set()
372
373 @functools.wraps(user_function)
374 def wrapper(self):
375 key = id(self), _thread.get_ident()
376 if key in repr_running:
377 return '...'
378 repr_running.add(key)
379 try:
380 result = user_function(self)
381 finally:
382 repr_running.discard(key)
383 return result
384 return wrapper
385
386
Eric V. Smithea8fc522018-01-27 19:07:40 -0500387def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500388 return_type=MISSING):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400389 # Note that we mutate locals when exec() is called. Caller
390 # beware! The only callers are internal to this module, so no
391 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500392 if locals is None:
393 locals = {}
Yury Selivanovd219cc42019-12-09 09:54:20 -0500394 if 'BUILTINS' not in locals:
395 locals['BUILTINS'] = builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500396 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500397 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500398 locals['_return_type'] = return_type
399 return_annotation = '->_return_type'
400 args = ','.join(args)
Yury Selivanovd219cc42019-12-09 09:54:20 -0500401 body = '\n'.join(f' {b}' for b in body)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500402
Eric V. Smithf199bc62018-03-18 20:40:34 -0400403 # Compute the text of the entire function.
Yury Selivanovd219cc42019-12-09 09:54:20 -0500404 txt = f' def {name}({args}){return_annotation}:\n{body}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500405
Yury Selivanovd219cc42019-12-09 09:54:20 -0500406 local_vars = ', '.join(locals.keys())
407 txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
408
409 ns = {}
410 exec(txt, globals, ns)
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300411 func = ns['__create_fn__'](**locals)
412 for arg, annotation in func.__annotations__.copy().items():
413 func.__annotations__[arg] = locals[annotation]
414 return func
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500415
416def _field_assign(frozen, name, value, self_name):
417 # If we're a frozen class, then assign to our fields in __init__
Eric V. Smithf8e75492018-05-16 05:14:53 -0400418 # via object.__setattr__. Otherwise, just use a simple
419 # assignment.
420 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500421 # self_name is what "self" is called in this function: don't
Eric V. Smithf8e75492018-05-16 05:14:53 -0400422 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500423 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500424 return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500425 return f'{self_name}.{name}={value}'
426
427
428def _field_init(f, frozen, globals, self_name):
429 # Return the text of the line in the body of __init__ that will
Eric V. Smithf8e75492018-05-16 05:14:53 -0400430 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500431
432 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500433 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500434 if f.init:
435 # This field has a default factory. If a parameter is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400436 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500437 globals[default_name] = f.default_factory
438 value = (f'{default_name}() '
439 f'if {f.name} is _HAS_DEFAULT_FACTORY '
440 f'else {f.name}')
441 else:
442 # This is a field that's not in the __init__ params, but
Eric V. Smithf8e75492018-05-16 05:14:53 -0400443 # has a default factory function. It needs to be
444 # initialized here by calling the factory function,
445 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500446
447 # For a field initialized with a default=defaultvalue, the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400448 # class dict just has the default value
449 # (cls.fieldname=defaultvalue). But that won't work for a
450 # default factory, the factory must be called in __init__
451 # and we must assign that to self.fieldname. We can't
452 # fall back to the class dict's value, both because it's
453 # not set, and because it might be different per-class
454 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500455
456 globals[default_name] = f.default_factory
457 value = f'{default_name}()'
458 else:
459 # No default factory.
460 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500461 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500462 # There's no default, just do an assignment.
463 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500464 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500465 globals[default_name] = f.default
466 value = f.name
467 else:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400468 # This field does not need initialization. Signify that
469 # to the caller by returning None.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500470 return None
471
472 # Only test this now, so that we can create variables for the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400473 # default. However, return None to signify that we're not going
474 # to actually do the assignment statement for InitVars.
Eric V. Smithe7adf2b2018-06-07 14:43:59 -0400475 if f._field_type is _FIELD_INITVAR:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500476 return None
477
478 # Now, actually generate the field assignment.
479 return _field_assign(frozen, f.name, value, self_name)
480
481
482def _init_param(f):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400483 # Return the __init__ parameter string for this field. For
484 # example, the equivalent of 'x:int=3' (except instead of 'int',
485 # reference a variable set to int, and instead of '3', reference a
486 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500487 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400488 # There's no default, and no default_factory, just output the
489 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500490 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500491 elif f.default is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400492 # There's a default, this will be the name that's used to look
493 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500494 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500495 elif f.default_factory is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400496 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500497 default = '=_HAS_DEFAULT_FACTORY'
498 return f'{f.name}:_type_{f.name}{default}'
499
500
Yury Selivanovd219cc42019-12-09 09:54:20 -0500501def _init_fn(fields, frozen, has_post_init, self_name, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500502 # fields contains both real fields and InitVar pseudo-fields.
503
504 # Make sure we don't have fields without defaults following fields
Eric V. Smithf8e75492018-05-16 05:14:53 -0400505 # with defaults. This actually would be caught when exec-ing the
506 # function source code, but catching it here gives a better error
507 # message, and future-proofs us in case we build up the function
508 # using ast.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500509 seen_default = False
510 for f in fields:
511 # Only consider fields in the __init__ call.
512 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500513 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500514 seen_default = True
515 elif seen_default:
516 raise TypeError(f'non-default argument {f.name!r} '
517 'follows default argument')
518
Yury Selivanovd219cc42019-12-09 09:54:20 -0500519 locals = {f'_type_{f.name}': f.type for f in fields}
520 locals.update({
521 'MISSING': MISSING,
522 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
523 })
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500524
525 body_lines = []
526 for f in fields:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500527 line = _field_init(f, frozen, locals, self_name)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400528 # line is None means that this field doesn't require
Eric V. Smithf8e75492018-05-16 05:14:53 -0400529 # initialization (it's a pseudo-field). Just skip it.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400530 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500531 body_lines.append(line)
532
533 # Does this class have a post-init function?
534 if has_post_init:
535 params_str = ','.join(f.name for f in fields
536 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400537 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500538
539 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500540 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500541 body_lines = ['pass']
542
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500543 return _create_fn('__init__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400544 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500545 body_lines,
546 locals=locals,
547 globals=globals,
548 return_type=None)
549
550
Yury Selivanovd219cc42019-12-09 09:54:20 -0500551def _repr_fn(fields, globals):
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530552 fn = _create_fn('__repr__',
553 ('self',),
554 ['return self.__class__.__qualname__ + f"(' +
555 ', '.join([f"{f.name}={{self.{f.name}!r}}"
556 for f in fields]) +
Yury Selivanovd219cc42019-12-09 09:54:20 -0500557 ')"'],
558 globals=globals)
Srinivas Thatiparthy (శ్రీనివాస్ తాటిపర్తి)dd13c882018-10-19 22:24:50 +0530559 return _recursive_repr(fn)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500560
561
Yury Selivanovd219cc42019-12-09 09:54:20 -0500562def _frozen_get_del_attr(cls, fields, globals):
563 locals = {'cls': cls,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400564 'FrozenInstanceError': FrozenInstanceError}
565 if fields:
566 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
567 else:
568 # Special case for the zero-length tuple.
569 fields_str = '()'
570 return (_create_fn('__setattr__',
571 ('self', 'name', 'value'),
572 (f'if type(self) is cls or name in {fields_str}:',
573 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
574 f'super(cls, self).__setattr__(name, value)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500575 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400576 globals=globals),
577 _create_fn('__delattr__',
578 ('self', 'name'),
579 (f'if type(self) is cls or name in {fields_str}:',
580 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
581 f'super(cls, self).__delattr__(name)'),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500582 locals=locals,
Eric V. Smithf199bc62018-03-18 20:40:34 -0400583 globals=globals),
584 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500585
586
Yury Selivanovd219cc42019-12-09 09:54:20 -0500587def _cmp_fn(name, op, self_tuple, other_tuple, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500588 # Create a comparison function. If the fields in the object are
Eric V. Smithf8e75492018-05-16 05:14:53 -0400589 # named 'x' and 'y', then self_tuple is the string
590 # '(self.x,self.y)' and other_tuple is the string
591 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500592
593 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400594 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500595 [ 'if other.__class__ is self.__class__:',
596 f' return {self_tuple}{op}{other_tuple}',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500597 'return NotImplemented'],
598 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500599
600
Yury Selivanovd219cc42019-12-09 09:54:20 -0500601def _hash_fn(fields, globals):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500602 self_tuple = _tuple_str('self', fields)
603 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400604 ('self',),
Yury Selivanovd219cc42019-12-09 09:54:20 -0500605 [f'return hash({self_tuple})'],
606 globals=globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500607
608
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400609def _is_classvar(a_type, typing):
Eric V. Smith92858352018-05-16 07:24:00 -0400610 # This test uses a typing internal class, but it's the best way to
611 # test if this is a ClassVar.
612 return (a_type is typing.ClassVar
613 or (type(a_type) is typing._GenericAlias
614 and a_type.__origin__ is typing.ClassVar))
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400615
616
617def _is_initvar(a_type, dataclasses):
618 # The module we're checking against is the module we're
619 # currently in (dataclasses.py).
Augusto Hack01ee12b2019-06-02 23:14:48 -0300620 return (a_type is dataclasses.InitVar
621 or type(a_type) is dataclasses.InitVar)
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400622
623
624def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
625 # Given a type annotation string, does it refer to a_type in
626 # a_module? For example, when checking that annotation denotes a
627 # ClassVar, then a_module is typing, and a_type is
628 # typing.ClassVar.
629
630 # It's possible to look up a_module given a_type, but it involves
631 # looking in sys.modules (again!), and seems like a waste since
632 # the caller already knows a_module.
633
634 # - annotation is a string type annotation
635 # - cls is the class that this annotation was found in
636 # - a_module is the module we want to match
637 # - a_type is the type in that module we want to match
638 # - is_type_predicate is a function called with (obj, a_module)
639 # that determines if obj is of the desired type.
640
641 # Since this test does not do a local namespace lookup (and
642 # instead only a module (global) lookup), there are some things it
643 # gets wrong.
644
Eric V. Smithf8e75492018-05-16 05:14:53 -0400645 # With string annotations, cv0 will be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400646 # CV = ClassVar
647 # @dataclass
648 # class C0:
649 # cv0: CV
650
Eric V. Smithf8e75492018-05-16 05:14:53 -0400651 # But in this example cv1 will not be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400652 # @dataclass
653 # class C1:
654 # CV = ClassVar
655 # cv1: CV
656
Eric V. Smithf8e75492018-05-16 05:14:53 -0400657 # In C1, the code in this function (_is_type) will look up "CV" in
658 # the module and not find it, so it will not consider cv1 as a
659 # ClassVar. This is a fairly obscure corner case, and the best
660 # way to fix it would be to eval() the string "CV" with the
661 # correct global and local namespaces. However that would involve
662 # a eval() penalty for every single field of every dataclass
663 # that's defined. It was judged not worth it.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400664
Batuhan Taskaya044a1042020-10-06 23:03:02 +0300665 # Strip away the extra quotes as a result of double-stringifying when the
666 # 'annotations' feature became default.
667 if annotation.startswith(("'", '"')) and annotation.endswith(("'", '"')):
668 annotation = annotation[1:-1]
669
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400670 match = _MODULE_IDENTIFIER_RE.match(annotation)
671 if match:
672 ns = None
673 module_name = match.group(1)
674 if not module_name:
675 # No module name, assume the class's module did
676 # "from dataclasses import InitVar".
677 ns = sys.modules.get(cls.__module__).__dict__
678 else:
679 # Look up module_name in the class's module.
680 module = sys.modules.get(cls.__module__)
681 if module and module.__dict__.get(module_name) is a_module:
682 ns = sys.modules.get(a_type.__module__).__dict__
683 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
684 return True
685 return False
686
687
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500688def _get_field(cls, a_name, a_type):
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400689 # Return a Field object for this field name and type. ClassVars
Eric V. Smithf8e75492018-05-16 05:14:53 -0400690 # and InitVars are also returned, but marked as such (see
691 # f._field_type).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500692
Eric V. Smithf8e75492018-05-16 05:14:53 -0400693 # If the default value isn't derived from Field, then it's only a
694 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500695 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500696 if isinstance(default, Field):
697 f = default
698 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400699 if isinstance(default, types.MemberDescriptorType):
700 # This is a field in __slots__, so it has no default value.
701 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500702 f = field(default=default)
703
Eric V. Smithf8e75492018-05-16 05:14:53 -0400704 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500705 f.name = a_name
706 f.type = a_type
707
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400708 # Assume it's a normal field until proven otherwise. We're next
Eric V. Smithf8e75492018-05-16 05:14:53 -0400709 # going to decide if it's a ClassVar or InitVar, everything else
710 # is just a normal field.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400711 f._field_type = _FIELD
712
713 # In addition to checking for actual types here, also check for
Eric V. Smithf8e75492018-05-16 05:14:53 -0400714 # string annotations. get_type_hints() won't always work for us
715 # (see https://github.com/python/typing/issues/508 for example),
716 # plus it's expensive and would require an eval for every stirng
717 # annotation. So, make a best effort to see if this is a ClassVar
718 # or InitVar using regex's and checking that the thing referenced
719 # is actually of the correct type.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400720
721 # For the complete discussion, see https://bugs.python.org/issue33453
722
723 # If typing has not been imported, then it's impossible for any
Eric V. Smithf8e75492018-05-16 05:14:53 -0400724 # annotation to be a ClassVar. So, only look for ClassVar if
725 # typing has been imported by any module (not necessarily cls's
726 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500727 typing = sys.modules.get('typing')
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400728 if typing:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400729 if (_is_classvar(a_type, typing)
730 or (isinstance(f.type, str)
731 and _is_type(f.type, cls, typing, typing.ClassVar,
732 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500733 f._field_type = _FIELD_CLASSVAR
734
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400735 # If the type is InitVar, or if it's a matching string annotation,
736 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500737 if f._field_type is _FIELD:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400738 # The module we're checking against is the module we're
739 # currently in (dataclasses.py).
740 dataclasses = sys.modules[__name__]
741 if (_is_initvar(a_type, dataclasses)
742 or (isinstance(f.type, str)
743 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
744 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500745 f._field_type = _FIELD_INITVAR
746
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400747 # Validations for individual fields. This is delayed until now,
748 # instead of in the Field() constructor, since only here do we
749 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500750
751 # Special restrictions for ClassVar and InitVar.
752 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500753 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500754 raise TypeError(f'field {f.name} cannot have a '
755 'default factory')
756 # Should I check for other field settings? default_factory
Eric V. Smithf8e75492018-05-16 05:14:53 -0400757 # seems the most serious to check for. Maybe add others. For
758 # example, how about init=False (or really,
759 # init=<not-the-default-init-value>)? It makes no sense for
760 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500761
762 # For real fields, disallow mutable defaults for known types.
763 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
764 raise ValueError(f'mutable default {type(f.default)} for field '
765 f'{f.name} is not allowed: use default_factory')
766
767 return f
768
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300769def _set_qualname(cls, value):
770 # Ensure that the functions returned from _create_fn uses the proper
771 # __qualname__ (the class they belong to).
772 if isinstance(value, FunctionType):
773 value.__qualname__ = f"{cls.__qualname__}.{value.__name__}"
774 return value
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500775
Eric V. Smithea8fc522018-01-27 19:07:40 -0500776def _set_new_attribute(cls, name, value):
777 # Never overwrites an existing attribute. Returns True if the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400778 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500779 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500780 return True
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300781 _set_qualname(cls, value)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500782 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500783 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500784
785
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500786# Decide if/how we're going to create a hash function. Key is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400787# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
788# take. The common case is to do nothing, so instead of providing a
789# function that is a no-op, use None to signify that.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400790
Yury Selivanovd219cc42019-12-09 09:54:20 -0500791def _hash_set_none(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400792 return None
793
Yury Selivanovd219cc42019-12-09 09:54:20 -0500794def _hash_add(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400795 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
Batuhan Taskayac7437e22020-10-21 16:49:22 +0300796 return _set_qualname(cls, _hash_fn(flds, globals))
Eric V. Smith01d618c2018-03-24 22:10:14 -0400797
Yury Selivanovd219cc42019-12-09 09:54:20 -0500798def _hash_exception(cls, fields, globals):
Eric V. Smith01d618c2018-03-24 22:10:14 -0400799 # Raise an exception.
800 raise TypeError(f'Cannot overwrite attribute __hash__ '
801 f'in class {cls.__name__}')
802
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500803#
804# +-------------------------------------- unsafe_hash?
805# | +------------------------------- eq?
806# | | +------------------------ frozen?
807# | | | +---------------- has-explicit-hash?
808# | | | |
809# | | | | +------- action
810# | | | | |
811# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400812_hash_action = {(False, False, False, False): None,
813 (False, False, False, True ): None,
814 (False, False, True, False): None,
815 (False, False, True, True ): None,
816 (False, True, False, False): _hash_set_none,
817 (False, True, False, True ): None,
818 (False, True, True, False): _hash_add,
819 (False, True, True, True ): None,
820 (True, False, False, False): _hash_add,
821 (True, False, False, True ): _hash_exception,
822 (True, False, True, False): _hash_add,
823 (True, False, True, True ): _hash_exception,
824 (True, True, False, False): _hash_add,
825 (True, True, False, True ): _hash_exception,
826 (True, True, True, False): _hash_add,
827 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500828 }
829# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Eric V. Smithf8e75492018-05-16 05:14:53 -0400830# version of this table.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500831
832
Eric V. Smithf199bc62018-03-18 20:40:34 -0400833def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500834 # Now that dicts retain insertion order, there's no reason to use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400835 # an ordered dict. I am leveraging that ordering here, because
836 # derived class fields overwrite base class fields, but the order
837 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500838 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500839
Yury Selivanovd219cc42019-12-09 09:54:20 -0500840 if cls.__module__ in sys.modules:
841 globals = sys.modules[cls.__module__].__dict__
842 else:
843 # Theoretically this can happen if someone writes
844 # a custom string to cls.__module__. In which case
845 # such dataclass won't be fully introspectable
846 # (w.r.t. typing.get_type_hints) but will still function
847 # correctly.
848 globals = {}
849
Eric V. Smithf199bc62018-03-18 20:40:34 -0400850 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
851 unsafe_hash, frozen))
852
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500853 # Find our base classes in reverse MRO order, and exclude
Eric V. Smithf8e75492018-05-16 05:14:53 -0400854 # ourselves. In reversed order so that more derived classes
855 # override earlier field definitions in base classes. As long as
856 # we're iterating over them, see if any are frozen.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400857 any_frozen_base = False
858 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500859 for b in cls.__mro__[-1:0:-1]:
860 # Only process classes that have been processed by our
Eric V. Smithf8e75492018-05-16 05:14:53 -0400861 # decorator. That is, they have a _FIELDS attribute.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400862 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500863 if base_fields:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400864 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500865 for f in base_fields.values():
866 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400867 if getattr(b, _PARAMS).frozen:
868 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500869
Eric V. Smith56970b82018-03-22 16:28:48 -0400870 # Annotations that are defined in this class (not in base
Eric V. Smithf8e75492018-05-16 05:14:53 -0400871 # classes). If __annotations__ isn't present, then this class
872 # adds no new annotations. We use this to compute fields that are
873 # added by this class.
874 #
Eric V. Smith56970b82018-03-22 16:28:48 -0400875 # Fields are found from cls_annotations, which is guaranteed to be
Eric V. Smithf8e75492018-05-16 05:14:53 -0400876 # ordered. Default values are from class attributes, if a field
877 # has a default. If the default value is a Field(), then it
878 # contains additional info beyond (and possibly including) the
879 # actual default value. Pseudo-fields ClassVars and InitVars are
880 # included, despite the fact that they're not real fields. That's
881 # dealt with later.
Eric V. Smith56970b82018-03-22 16:28:48 -0400882 cls_annotations = cls.__dict__.get('__annotations__', {})
883
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500884 # Now find fields in our class. While doing so, validate some
Eric V. Smithf8e75492018-05-16 05:14:53 -0400885 # things, and set the default values (as class attributes) where
886 # we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400887 cls_fields = [_get_field(cls, name, type)
888 for name, type in cls_annotations.items()]
889 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500890 fields[f.name] = f
891
Eric V. Smithf8e75492018-05-16 05:14:53 -0400892 # If the class attribute (which is the default value for this
893 # field) exists and is of type 'Field', replace it with the
894 # real default. This is so that normal class introspection
895 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500896 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500897 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500898 # If there's no default, delete the class attribute.
Eric V. Smithf8e75492018-05-16 05:14:53 -0400899 # This happens if we specify field(repr=False), for
900 # example (that is, we specified a field object, but
901 # no default value). Also if we're using a default
902 # factory. The class attribute should not be set at
903 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500904 delattr(cls, f.name)
905 else:
906 setattr(cls, f.name, f.default)
907
Eric V. Smith56970b82018-03-22 16:28:48 -0400908 # Do we have any Field members that don't also have annotations?
909 for name, value in cls.__dict__.items():
910 if isinstance(value, Field) and not name in cls_annotations:
911 raise TypeError(f'{name!r} is a field but has no type annotation')
912
Eric V. Smithf199bc62018-03-18 20:40:34 -0400913 # Check rules that apply if we are derived from any dataclasses.
914 if has_dataclass_bases:
915 # Raise an exception if any of our bases are frozen, but we're not.
916 if any_frozen_base and not frozen:
917 raise TypeError('cannot inherit non-frozen dataclass from a '
918 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500919
Eric V. Smithf199bc62018-03-18 20:40:34 -0400920 # Raise an exception if we're frozen, but none of our bases are.
921 if not any_frozen_base and frozen:
922 raise TypeError('cannot inherit frozen dataclass from a '
923 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500924
Eric V. Smithf8e75492018-05-16 05:14:53 -0400925 # Remember all of the fields on our class (including bases). This
926 # also marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400927 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500928
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500929 # Was this class defined with an explicit __hash__? Note that if
Eric V. Smithf8e75492018-05-16 05:14:53 -0400930 # __eq__ is defined in this class, then python will automatically
931 # set __hash__ to None. This is a heuristic, as it's possible
932 # that such a __hash__ == None was not auto-generated, but it
933 # close enough.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500934 class_hash = cls.__dict__.get('__hash__', MISSING)
935 has_explicit_hash = not (class_hash is MISSING or
936 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500937
Eric V. Smithf8e75492018-05-16 05:14:53 -0400938 # If we're generating ordering methods, we must be generating the
939 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500940 if order and not eq:
941 raise ValueError('eq must be true if order is true')
942
943 if init:
944 # Does this class have a post-init function?
945 has_post_init = hasattr(cls, _POST_INIT_NAME)
946
947 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500948 flds = [f for f in fields.values()
949 if f._field_type in (_FIELD, _FIELD_INITVAR)]
950 _set_new_attribute(cls, '__init__',
951 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500952 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500953 has_post_init,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400954 # The name to use for the "self"
955 # param in __init__. Use "self"
956 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500957 '__dataclass_self__' if 'self' in fields
958 else 'self',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500959 globals,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500960 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500961
962 # Get the fields as a list, and include only real fields. This is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400963 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500964 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500965
966 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500967 flds = [f for f in field_list if f.repr]
Yury Selivanovd219cc42019-12-09 09:54:20 -0500968 _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500969
970 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500971 # Create _eq__ method. There's no need for a __ne__ method,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400972 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500973 flds = [f for f in field_list if f.compare]
974 self_tuple = _tuple_str('self', flds)
975 other_tuple = _tuple_str('other', flds)
976 _set_new_attribute(cls, '__eq__',
977 _cmp_fn('__eq__', '==',
Yury Selivanovd219cc42019-12-09 09:54:20 -0500978 self_tuple, other_tuple,
979 globals=globals))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500980
981 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500982 # Create and set the ordering methods.
983 flds = [f for f in field_list if f.compare]
984 self_tuple = _tuple_str('self', flds)
985 other_tuple = _tuple_str('other', flds)
986 for name, op in [('__lt__', '<'),
987 ('__le__', '<='),
988 ('__gt__', '>'),
989 ('__ge__', '>='),
990 ]:
991 if _set_new_attribute(cls, name,
Yury Selivanovd219cc42019-12-09 09:54:20 -0500992 _cmp_fn(name, op, self_tuple, other_tuple,
993 globals=globals)):
Eric V. Smithea8fc522018-01-27 19:07:40 -0500994 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500995 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500996 'functools.total_ordering')
997
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500998 if frozen:
Yury Selivanovd219cc42019-12-09 09:54:20 -0500999 for fn in _frozen_get_del_attr(cls, field_list, globals):
Eric V. Smithf199bc62018-03-18 20:40:34 -04001000 if _set_new_attribute(cls, fn.__name__, fn):
1001 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001002 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -05001003
1004 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001005 hash_action = _hash_action[bool(unsafe_hash),
1006 bool(eq),
1007 bool(frozen),
1008 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -04001009 if hash_action:
1010 # No need to call _set_new_attribute here, since by the time
Eric V. Smithf8e75492018-05-16 05:14:53 -04001011 # we're here the overwriting is unconditional.
Yury Selivanovd219cc42019-12-09 09:54:20 -05001012 cls.__hash__ = hash_action(cls, field_list, globals)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001013
1014 if not getattr(cls, '__doc__'):
1015 # Create a class doc-string.
1016 cls.__doc__ = (cls.__name__ +
Batuhan Taskaya044a1042020-10-06 23:03:02 +03001017 str(inspect.signature(cls)).replace(' -> NoneType', ''))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001018
Brandt Bucher145bf262021-02-26 14:51:55 -08001019 if '__match_args__' not in cls.__dict__:
1020 cls.__match_args__ = tuple(f.name for f in flds if f.init)
1021
Ben Avrahamibef7d292020-10-06 20:40:50 +03001022 abc.update_abstractmethods(cls)
1023
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001024 return cls
1025
1026
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001027def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001028 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001029 """Returns the same class as was passed in, with dunder methods
1030 added based on the fields defined in the class.
1031
1032 Examines PEP 526 __annotations__ to determine fields.
1033
1034 If init is true, an __init__() method is added to the class. If
1035 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001036 comparison dunder methods are added. If unsafe_hash is true, a
1037 __hash__() method function is added. If frozen is true, fields may
1038 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001039 """
1040
1041 def wrap(cls):
Eric V. Smithf199bc62018-03-18 20:40:34 -04001042 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001043
1044 # See if we're being called as @dataclass or @dataclass().
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001045 if cls is None:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001046 # We're called with parens.
1047 return wrap
1048
1049 # We're called as @dataclass without parens.
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001050 return wrap(cls)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001051
1052
1053def fields(class_or_instance):
1054 """Return a tuple describing the fields of this dataclass.
1055
1056 Accepts a dataclass or an instance of one. Tuple elements are of
1057 type Field.
1058 """
1059
1060 # Might it be worth caching this, per class?
1061 try:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -04001062 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001063 except AttributeError:
1064 raise TypeError('must be called with a dataclass type or instance')
1065
Eric V. Smithd1388922018-01-07 14:30:17 -05001066 # Exclude pseudo-fields. Note that fields is sorted by insertion
Eric V. Smithf8e75492018-05-16 05:14:53 -04001067 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001068 return tuple(f for f in fields.values() if f._field_type is _FIELD)
1069
1070
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001071def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001072 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001073 return hasattr(type(obj), _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001074
1075
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001076def is_dataclass(obj):
1077 """Returns True if obj is a dataclass or an instance of a
1078 dataclass."""
Eric V. Smithb0f4dab2019-08-20 01:40:28 -04001079 cls = obj if isinstance(obj, type) else type(obj)
1080 return hasattr(cls, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001081
1082
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001083def asdict(obj, *, dict_factory=dict):
1084 """Return the fields of a dataclass instance as a new dictionary mapping
1085 field names to field values.
1086
1087 Example usage:
1088
1089 @dataclass
1090 class C:
1091 x: int
1092 y: int
1093
1094 c = C(1, 2)
1095 assert asdict(c) == {'x': 1, 'y': 2}
1096
1097 If given, 'dict_factory' will be used instead of built-in dict.
1098 The function applies recursively to field values that are
1099 dataclass instances. This will also look into built-in containers:
1100 tuples, lists, and dicts.
1101 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001102 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001103 raise TypeError("asdict() should be called on dataclass instances")
1104 return _asdict_inner(obj, dict_factory)
1105
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001106
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001107def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001108 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001109 result = []
1110 for f in fields(obj):
1111 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1112 result.append((f.name, value))
1113 return dict_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001114 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1115 # obj is a namedtuple. Recurse into it, but the returned
1116 # object is another namedtuple of the same type. This is
1117 # similar to how other list- or tuple-derived classes are
1118 # treated (see below), but we just need to create them
1119 # differently because a namedtuple's __init__ needs to be
1120 # called differently (see bpo-34363).
1121
1122 # I'm not using namedtuple's _asdict()
1123 # method, because:
1124 # - it does not recurse in to the namedtuple fields and
1125 # convert them to dicts (using dict_factory).
Jürgen Gmach80526f62020-06-24 12:46:52 +02001126 # - I don't actually want to return a dict here. The main
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001127 # use case here is json.dumps, and it handles converting
1128 # namedtuples to lists. Admittedly we're losing some
1129 # information here when we produce a json list instead of a
1130 # dict. Note that if we returned dicts here instead of
1131 # namedtuples, we could no longer call asdict() on a data
1132 # structure where a namedtuple was used as a dict key.
1133
1134 return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001135 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001136 # Assume we can create an object of this type by passing in a
1137 # generator (which is not true for namedtuples, handled
1138 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001139 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1140 elif isinstance(obj, dict):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001141 return type(obj)((_asdict_inner(k, dict_factory),
1142 _asdict_inner(v, dict_factory))
1143 for k, v in obj.items())
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001144 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001145 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001146
1147
1148def astuple(obj, *, tuple_factory=tuple):
1149 """Return the fields of a dataclass instance as a new tuple of field values.
1150
1151 Example usage::
1152
1153 @dataclass
1154 class C:
1155 x: int
1156 y: int
1157
1158 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001159 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001160
1161 If given, 'tuple_factory' will be used instead of built-in tuple.
1162 The function applies recursively to field values that are
1163 dataclass instances. This will also look into built-in containers:
1164 tuples, lists, and dicts.
1165 """
1166
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001167 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001168 raise TypeError("astuple() should be called on dataclass instances")
1169 return _astuple_inner(obj, tuple_factory)
1170
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001171
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001172def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001173 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001174 result = []
1175 for f in fields(obj):
1176 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1177 result.append(value)
1178 return tuple_factory(result)
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001179 elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
1180 # obj is a namedtuple. Recurse into it, but the returned
1181 # object is another namedtuple of the same type. This is
1182 # similar to how other list- or tuple-derived classes are
1183 # treated (see below), but we just need to create them
1184 # differently because a namedtuple's __init__ needs to be
1185 # called differently (see bpo-34363).
1186 return type(obj)(*[_astuple_inner(v, tuple_factory) for v in obj])
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001187 elif isinstance(obj, (list, tuple)):
Eric V. Smith9b9d97d2018-09-14 11:32:16 -04001188 # Assume we can create an object of this type by passing in a
1189 # generator (which is not true for namedtuples, handled
1190 # above).
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001191 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1192 elif isinstance(obj, dict):
1193 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1194 for k, v in obj.items())
1195 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001196 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001197
1198
Eric V. Smithd80b4432018-01-06 17:09:58 -05001199def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001200 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001201 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001202 """Return a new dynamically created dataclass.
1203
Eric V. Smithed7d4292018-01-06 16:14:03 -05001204 The dataclass name will be 'cls_name'. 'fields' is an iterable
1205 of either (name), (name, type) or (name, type, Field) objects. If type is
1206 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001207 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001208
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001209 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001210
1211 is equivalent to:
1212
1213 @dataclass
1214 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001215 x: 'typing.Any'
1216 y: int
1217 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001218
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001219 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001220
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001221 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001222 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001223 """
1224
1225 if namespace is None:
1226 namespace = {}
1227 else:
1228 # Copy namespace since we're going to mutate it.
1229 namespace = namespace.copy()
1230
Eric V. Smith4e812962018-05-16 11:31:29 -04001231 # While we're looking through the field names, validate that they
1232 # are identifiers, are not keywords, and not duplicates.
1233 seen = set()
Eric V. Smithd1388922018-01-07 14:30:17 -05001234 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001235 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001236 if isinstance(item, str):
1237 name = item
1238 tp = 'typing.Any'
1239 elif len(item) == 2:
1240 name, tp, = item
1241 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001242 name, tp, spec = item
1243 namespace[name] = spec
Eric V. Smith4e812962018-05-16 11:31:29 -04001244 else:
1245 raise TypeError(f'Invalid field: {item!r}')
1246
1247 if not isinstance(name, str) or not name.isidentifier():
Min ho Kim96e12d52019-07-22 06:12:33 +10001248 raise TypeError(f'Field names must be valid identifiers: {name!r}')
Eric V. Smith4e812962018-05-16 11:31:29 -04001249 if keyword.iskeyword(name):
1250 raise TypeError(f'Field names must not be keywords: {name!r}')
1251 if name in seen:
1252 raise TypeError(f'Field name duplicated: {name!r}')
1253
1254 seen.add(name)
Eric V. Smithed7d4292018-01-06 16:14:03 -05001255 anns[name] = tp
1256
1257 namespace['__annotations__'] = anns
Ivan Levkivskyi5a7092d2018-03-31 13:41:17 +01001258 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1259 # of generic dataclassses.
1260 cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace))
Eric V. Smithd80b4432018-01-06 17:09:58 -05001261 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001262 unsafe_hash=unsafe_hash, frozen=frozen)
1263
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001264
Serhiy Storchaka2d88e632019-06-26 19:07:44 +03001265def replace(obj, /, **changes):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001266 """Return a new object replacing specified fields with new values.
1267
1268 This is especially useful for frozen classes. Example usage:
1269
1270 @dataclass(frozen=True)
1271 class C:
1272 x: int
1273 y: int
1274
1275 c = C(1, 2)
1276 c1 = replace(c, x=3)
1277 assert c1.x == 3 and c1.y == 2
1278 """
1279
Eric V. Smithf8e75492018-05-16 05:14:53 -04001280 # We're going to mutate 'changes', but that's okay because it's a
1281 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001282
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001283 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001284 raise TypeError("replace() should be called on dataclass instances")
1285
1286 # It's an error to have init=False fields in 'changes'.
1287 # If a field is not in 'changes', read its value from the provided obj.
1288
Eric V. Smithf199bc62018-03-18 20:40:34 -04001289 for f in getattr(obj, _FIELDS).values():
Eric V. Smithe7adf2b2018-06-07 14:43:59 -04001290 # Only consider normal fields or InitVars.
1291 if f._field_type is _FIELD_CLASSVAR:
1292 continue
1293
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001294 if not f.init:
1295 # Error if this field is specified in changes.
1296 if f.name in changes:
1297 raise ValueError(f'field {f.name} is declared with '
1298 'init=False, it cannot be specified with '
1299 'replace()')
1300 continue
1301
1302 if f.name not in changes:
Dong-hee Na3d70f7a2018-06-23 23:46:32 +09001303 if f._field_type is _FIELD_INITVAR:
1304 raise ValueError(f"InitVar {f.name!r} "
1305 'must be specified with replace()')
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001306 changes[f.name] = getattr(obj, f.name)
1307
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001308 # Create the new object, which calls __init__() and
Eric V. Smithf8e75492018-05-16 05:14:53 -04001309 # __post_init__() (if defined), using all of the init fields we've
1310 # added and/or left in 'changes'. If there are values supplied in
1311 # changes that aren't fields, this will correctly raise a
1312 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001313 return obj.__class__(**changes)