blob: 2c5593bfc50dc060becb0aa49e2721de9758afb7 [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
Eric V. Smithf0db54a2017-12-04 16:58:55 -05007
8__all__ = ['dataclass',
9 'field',
Eric V. Smith8e4560a2018-03-21 17:10:22 -040010 'Field',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050011 'FrozenInstanceError',
12 'InitVar',
Eric V. Smith03220fd2017-12-29 13:59:58 -050013 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050014
15 # Helper functions.
16 'fields',
17 'asdict',
18 'astuple',
19 'make_dataclass',
20 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050021 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050022 ]
23
Eric V. Smithea8fc522018-01-27 19:07:40 -050024# Conditions for adding methods. The boxes indicate what action the
Eric V. Smithf8e75492018-05-16 05:14:53 -040025# dataclass decorator takes. For all of these tables, when I talk
26# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
27# referring to the arguments to the @dataclass decorator. When
28# checking if a dunder method already exists, I mean check for an
29# entry in the class's __dict__. I never check to see if an attribute
30# is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050031
32# Key:
33# +=========+=========================================+
34# + Value | Meaning |
35# +=========+=========================================+
36# | <blank> | No action: no method is added. |
37# +---------+-----------------------------------------+
38# | add | Generated method is added. |
39# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050040# | raise | TypeError is raised. |
41# +---------+-----------------------------------------+
42# | None | Attribute is set to None. |
43# +=========+=========================================+
44
45# __init__
46#
47# +--- init= parameter
48# |
49# v | | |
50# | no | yes | <--- class has __init__ in __dict__?
51# +=======+=======+=======+
52# | False | | |
53# +-------+-------+-------+
54# | True | add | | <- the default
55# +=======+=======+=======+
56
57# __repr__
58#
59# +--- repr= parameter
60# |
61# v | | |
62# | no | yes | <--- class has __repr__ in __dict__?
63# +=======+=======+=======+
64# | False | | |
65# +-------+-------+-------+
66# | True | add | | <- the default
67# +=======+=======+=======+
68
69
70# __setattr__
71# __delattr__
72#
73# +--- frozen= parameter
74# |
75# v | | |
76# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
77# +=======+=======+=======+
78# | False | | | <- the default
79# +-------+-------+-------+
80# | True | add | raise |
81# +=======+=======+=======+
82# Raise because not adding these methods would break the "frozen-ness"
Eric V. Smithf8e75492018-05-16 05:14:53 -040083# of the class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050084
85# __eq__
86#
87# +--- eq= parameter
88# |
89# v | | |
90# | no | yes | <--- class has __eq__ in __dict__?
91# +=======+=======+=======+
92# | False | | |
93# +-------+-------+-------+
94# | True | add | | <- the default
95# +=======+=======+=======+
96
97# __lt__
98# __le__
99# __gt__
100# __ge__
101#
102# +--- order= parameter
103# |
104# v | | |
105# | no | yes | <--- class has any comparison method in __dict__?
106# +=======+=======+=======+
107# | False | | | <- the default
108# +-------+-------+-------+
109# | True | add | raise |
110# +=======+=======+=======+
111# Raise because to allow this case would interfere with using
Eric V. Smithf8e75492018-05-16 05:14:53 -0400112# functools.total_ordering.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500113
114# __hash__
115
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500116# +------------------- unsafe_hash= parameter
117# | +----------- eq= parameter
118# | | +--- frozen= parameter
119# | | |
120# v v v | | |
121# | no | yes | <--- class has explicitly defined __hash__
122# +=======+=======+=======+========+========+
123# | False | False | False | | | No __eq__, use the base class __hash__
124# +-------+-------+-------+--------+--------+
125# | False | False | True | | | No __eq__, use the base class __hash__
126# +-------+-------+-------+--------+--------+
127# | False | True | False | None | | <-- the default, not hashable
128# +-------+-------+-------+--------+--------+
129# | False | True | True | add | | Frozen, so hashable, allows override
130# +-------+-------+-------+--------+--------+
131# | True | False | False | add | raise | Has no __eq__, but hashable
132# +-------+-------+-------+--------+--------+
133# | True | False | True | add | raise | Has no __eq__, but hashable
134# +-------+-------+-------+--------+--------+
135# | True | True | False | add | raise | Not frozen, but hashable
136# +-------+-------+-------+--------+--------+
137# | True | True | True | add | raise | Frozen, so hashable
138# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500139# For boxes that are blank, __hash__ is untouched and therefore
Eric V. Smithf8e75492018-05-16 05:14:53 -0400140# inherited from the base class. If the base is object, then
141# id-based hashing is used.
142#
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400143# Note that a class may already have __hash__=None if it specified an
Eric V. Smithf8e75492018-05-16 05:14:53 -0400144# __eq__ method in the class body (not one that was created by
145# @dataclass).
146#
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500147# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500148
149
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500150# Raised when an attempt is made to modify a frozen class.
151class FrozenInstanceError(AttributeError): pass
152
Eric V. Smithf8e75492018-05-16 05:14:53 -0400153# A sentinel object for default values to signal that a default
154# factory will be used. This is given a nice repr() which will appear
155# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500156class _HAS_DEFAULT_FACTORY_CLASS:
157 def __repr__(self):
158 return '<factory>'
159_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
160
Eric V. Smith03220fd2017-12-29 13:59:58 -0500161# A sentinel object to detect if a parameter is supplied or not. Use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400162# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500163class _MISSING_TYPE:
164 pass
165MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500166
167# Since most per-field metadata will be unused, create an empty
Eric V. Smithf8e75492018-05-16 05:14:53 -0400168# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500169_EMPTY_METADATA = types.MappingProxyType({})
170
171# Markers for the various kinds of fields and pseudo-fields.
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400172class _FIELD_BASE:
173 def __init__(self, name):
174 self.name = name
175 def __repr__(self):
176 return self.name
177_FIELD = _FIELD_BASE('_FIELD')
178_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
179_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500180
181# The name of an attribute on the class where we store the Field
Eric V. Smithf8e75492018-05-16 05:14:53 -0400182# objects. Also used to check if a class is a Data Class.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400183_FIELDS = '__dataclass_fields__'
184
185# The name of an attribute on the class that stores the parameters to
186# @dataclass.
187_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500188
189# The name of the function, that if it exists, is called at the end of
190# __init__.
191_POST_INIT_NAME = '__post_init__'
192
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400193# String regex that string annotations for ClassVar or InitVar must match.
194# Allows "identifier.identifier[" or "identifier[".
195# https://bugs.python.org/issue33453 for details.
196_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500197
198class _InitVarMeta(type):
199 def __getitem__(self, params):
200 return self
201
202class InitVar(metaclass=_InitVarMeta):
203 pass
204
205
206# Instances of Field are only ever created from within this module,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400207# and only from the field() function, although Field instances are
208# exposed externally as (conceptually) read-only objects.
209#
210# name and type are filled in after the fact, not in __init__.
211# They're not known at the time this class is instantiated, but it's
212# convenient if they're available later.
213#
Eric V. Smithf199bc62018-03-18 20:40:34 -0400214# When cls._FIELDS is filled in with a list of Field objects, the name
Eric V. Smithf8e75492018-05-16 05:14:53 -0400215# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500216class Field:
217 __slots__ = ('name',
218 'type',
219 'default',
220 'default_factory',
221 'repr',
222 'hash',
223 'init',
224 'compare',
225 'metadata',
226 '_field_type', # Private: not to be used by user code.
227 )
228
229 def __init__(self, default, default_factory, init, repr, hash, compare,
230 metadata):
231 self.name = None
232 self.type = None
233 self.default = default
234 self.default_factory = default_factory
235 self.init = init
236 self.repr = repr
237 self.hash = hash
238 self.compare = compare
239 self.metadata = (_EMPTY_METADATA
240 if metadata is None or len(metadata) == 0 else
241 types.MappingProxyType(metadata))
242 self._field_type = None
243
244 def __repr__(self):
245 return ('Field('
246 f'name={self.name!r},'
Eric V. Smith2473eea2018-05-14 11:37:28 -0400247 f'type={self.type!r},'
248 f'default={self.default!r},'
249 f'default_factory={self.default_factory!r},'
250 f'init={self.init!r},'
251 f'repr={self.repr!r},'
252 f'hash={self.hash!r},'
253 f'compare={self.compare!r},'
Eric V. Smith01abc6e2018-05-15 08:36:21 -0400254 f'metadata={self.metadata!r},'
255 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500256 ')')
257
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400258 # This is used to support the PEP 487 __set_name__ protocol in the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400259 # case where we're using a field that contains a descriptor as a
260 # defaul value. For details on __set_name__, see
261 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
262 #
263 # Note that in _process_class, this Field object is overwritten
264 # with the default value, so the end result is a descriptor that
265 # had __set_name__ called on it at the right time.
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400266 def __set_name__(self, owner, name):
Eric V. Smith52199522018-03-29 11:07:48 -0400267 func = getattr(type(self.default), '__set_name__', None)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400268 if func:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400269 # There is a __set_name__ method on the descriptor, call
270 # it.
Eric V. Smith52199522018-03-29 11:07:48 -0400271 func(self.default, owner, name)
Eric V. Smithde7a2f02018-03-26 13:29:16 -0400272
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500273
Eric V. Smithf199bc62018-03-18 20:40:34 -0400274class _DataclassParams:
275 __slots__ = ('init',
276 'repr',
277 'eq',
278 'order',
279 'unsafe_hash',
280 'frozen',
281 )
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400282
Eric V. Smithf199bc62018-03-18 20:40:34 -0400283 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
284 self.init = init
285 self.repr = repr
286 self.eq = eq
287 self.order = order
288 self.unsafe_hash = unsafe_hash
289 self.frozen = frozen
290
291 def __repr__(self):
292 return ('_DataclassParams('
Eric V. Smith30590422018-05-14 17:16:52 -0400293 f'init={self.init!r},'
294 f'repr={self.repr!r},'
295 f'eq={self.eq!r},'
296 f'order={self.order!r},'
297 f'unsafe_hash={self.unsafe_hash!r},'
298 f'frozen={self.frozen!r}'
Eric V. Smithf199bc62018-03-18 20:40:34 -0400299 ')')
300
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400301
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500302# This function is used instead of exposing Field creation directly,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400303# so that a type checker can be told (via overloads) that this is a
304# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500305def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500306 hash=None, compare=True, metadata=None):
307 """Return an object to identify dataclass fields.
308
Eric V. Smithf8e75492018-05-16 05:14:53 -0400309 default is the default value of the field. default_factory is a
310 0-argument function called to initialize a field's value. If init
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500311 is True, the field will be a parameter to the class's __init__()
Eric V. Smithf8e75492018-05-16 05:14:53 -0400312 function. If repr is True, the field will be included in the
313 object's repr(). If hash is True, the field will be included in
314 the object's hash(). If compare is True, the field will be used
315 in comparison functions. metadata, if specified, must be a
316 mapping which is stored but not otherwise examined by dataclass.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500317
318 It is an error to specify both default and default_factory.
319 """
320
Eric V. Smith03220fd2017-12-29 13:59:58 -0500321 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500322 raise ValueError('cannot specify both default and default_factory')
323 return Field(default, default_factory, init, repr, hash, compare,
324 metadata)
325
326
327def _tuple_str(obj_name, fields):
328 # Return a string representing each field of obj_name as a tuple
Eric V. Smithf8e75492018-05-16 05:14:53 -0400329 # member. So, if fields is ['x', 'y'] and obj_name is "self",
330 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500331
332 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500333 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500334 return '()'
335 # Note the trailing comma, needed if this turns out to be a 1-tuple.
336 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
337
338
Eric V. Smithea8fc522018-01-27 19:07:40 -0500339def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500340 return_type=MISSING):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400341 # Note that we mutate locals when exec() is called. Caller
342 # beware! The only callers are internal to this module, so no
343 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500344 if locals is None:
345 locals = {}
346 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500347 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500348 locals['_return_type'] = return_type
349 return_annotation = '->_return_type'
350 args = ','.join(args)
351 body = '\n'.join(f' {b}' for b in body)
352
Eric V. Smithf199bc62018-03-18 20:40:34 -0400353 # Compute the text of the entire function.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500354 txt = f'def {name}({args}){return_annotation}:\n{body}'
355
356 exec(txt, globals, locals)
357 return locals[name]
358
359
360def _field_assign(frozen, name, value, self_name):
361 # If we're a frozen class, then assign to our fields in __init__
Eric V. Smithf8e75492018-05-16 05:14:53 -0400362 # via object.__setattr__. Otherwise, just use a simple
363 # assignment.
364 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500365 # self_name is what "self" is called in this function: don't
Eric V. Smithf8e75492018-05-16 05:14:53 -0400366 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500367 if frozen:
368 return f'object.__setattr__({self_name},{name!r},{value})'
369 return f'{self_name}.{name}={value}'
370
371
372def _field_init(f, frozen, globals, self_name):
373 # Return the text of the line in the body of __init__ that will
Eric V. Smithf8e75492018-05-16 05:14:53 -0400374 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500375
376 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500377 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500378 if f.init:
379 # This field has a default factory. If a parameter is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400380 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500381 globals[default_name] = f.default_factory
382 value = (f'{default_name}() '
383 f'if {f.name} is _HAS_DEFAULT_FACTORY '
384 f'else {f.name}')
385 else:
386 # This is a field that's not in the __init__ params, but
Eric V. Smithf8e75492018-05-16 05:14:53 -0400387 # has a default factory function. It needs to be
388 # initialized here by calling the factory function,
389 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500390
391 # For a field initialized with a default=defaultvalue, the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400392 # class dict just has the default value
393 # (cls.fieldname=defaultvalue). But that won't work for a
394 # default factory, the factory must be called in __init__
395 # and we must assign that to self.fieldname. We can't
396 # fall back to the class dict's value, both because it's
397 # not set, and because it might be different per-class
398 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500399
400 globals[default_name] = f.default_factory
401 value = f'{default_name}()'
402 else:
403 # No default factory.
404 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500405 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500406 # There's no default, just do an assignment.
407 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500408 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500409 globals[default_name] = f.default
410 value = f.name
411 else:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400412 # This field does not need initialization. Signify that
413 # to the caller by returning None.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500414 return None
415
416 # Only test this now, so that we can create variables for the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400417 # default. However, return None to signify that we're not going
418 # to actually do the assignment statement for InitVars.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500419 if f._field_type == _FIELD_INITVAR:
420 return None
421
422 # Now, actually generate the field assignment.
423 return _field_assign(frozen, f.name, value, self_name)
424
425
426def _init_param(f):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400427 # Return the __init__ parameter string for this field. For
428 # example, the equivalent of 'x:int=3' (except instead of 'int',
429 # reference a variable set to int, and instead of '3', reference a
430 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500431 if f.default is MISSING and f.default_factory is MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400432 # There's no default, and no default_factory, just output the
433 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500434 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500435 elif f.default is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400436 # There's a default, this will be the name that's used to look
437 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500438 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500439 elif f.default_factory is not MISSING:
Eric V. Smithf8e75492018-05-16 05:14:53 -0400440 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500441 default = '=_HAS_DEFAULT_FACTORY'
442 return f'{f.name}:_type_{f.name}{default}'
443
444
445def _init_fn(fields, frozen, has_post_init, self_name):
446 # fields contains both real fields and InitVar pseudo-fields.
447
448 # Make sure we don't have fields without defaults following fields
Eric V. Smithf8e75492018-05-16 05:14:53 -0400449 # with defaults. This actually would be caught when exec-ing the
450 # function source code, but catching it here gives a better error
451 # message, and future-proofs us in case we build up the function
452 # using ast.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500453 seen_default = False
454 for f in fields:
455 # Only consider fields in the __init__ call.
456 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500457 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500458 seen_default = True
459 elif seen_default:
460 raise TypeError(f'non-default argument {f.name!r} '
461 'follows default argument')
462
Eric V. Smith03220fd2017-12-29 13:59:58 -0500463 globals = {'MISSING': MISSING,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500464 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
465
466 body_lines = []
467 for f in fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500468 line = _field_init(f, frozen, globals, self_name)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400469 # line is None means that this field doesn't require
Eric V. Smithf8e75492018-05-16 05:14:53 -0400470 # initialization (it's a pseudo-field). Just skip it.
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400471 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500472 body_lines.append(line)
473
474 # Does this class have a post-init function?
475 if has_post_init:
476 params_str = ','.join(f.name for f in fields
477 if f._field_type is _FIELD_INITVAR)
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400478 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500479
480 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500481 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500482 body_lines = ['pass']
483
484 locals = {f'_type_{f.name}': f.type for f in fields}
485 return _create_fn('__init__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400486 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500487 body_lines,
488 locals=locals,
489 globals=globals,
490 return_type=None)
491
492
493def _repr_fn(fields):
494 return _create_fn('__repr__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400495 ('self',),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500496 ['return self.__class__.__qualname__ + f"(' +
497 ', '.join([f"{f.name}={{self.{f.name}!r}}"
498 for f in fields]) +
499 ')"'])
500
501
Eric V. Smithf199bc62018-03-18 20:40:34 -0400502def _frozen_get_del_attr(cls, fields):
Eric V. Smithf8e75492018-05-16 05:14:53 -0400503 # XXX: globals is modified on the first call to _create_fn, then
504 # the modified version is used in the second call. Is this okay?
Eric V. Smithf199bc62018-03-18 20:40:34 -0400505 globals = {'cls': cls,
506 'FrozenInstanceError': FrozenInstanceError}
507 if fields:
508 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
509 else:
510 # Special case for the zero-length tuple.
511 fields_str = '()'
512 return (_create_fn('__setattr__',
513 ('self', 'name', 'value'),
514 (f'if type(self) is cls or name in {fields_str}:',
515 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
516 f'super(cls, self).__setattr__(name, value)'),
517 globals=globals),
518 _create_fn('__delattr__',
519 ('self', 'name'),
520 (f'if type(self) is cls or name in {fields_str}:',
521 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
522 f'super(cls, self).__delattr__(name)'),
523 globals=globals),
524 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500525
526
527def _cmp_fn(name, op, self_tuple, other_tuple):
528 # Create a comparison function. If the fields in the object are
Eric V. Smithf8e75492018-05-16 05:14:53 -0400529 # named 'x' and 'y', then self_tuple is the string
530 # '(self.x,self.y)' and other_tuple is the string
531 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500532
533 return _create_fn(name,
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400534 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500535 [ 'if other.__class__ is self.__class__:',
536 f' return {self_tuple}{op}{other_tuple}',
537 'return NotImplemented'])
538
539
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500540def _hash_fn(fields):
541 self_tuple = _tuple_str('self', fields)
542 return _create_fn('__hash__',
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400543 ('self',),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500544 [f'return hash({self_tuple})'])
545
546
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400547def _is_classvar(a_type, typing):
Eric V. Smith92858352018-05-16 07:24:00 -0400548 # This test uses a typing internal class, but it's the best way to
549 # test if this is a ClassVar.
550 return (a_type is typing.ClassVar
551 or (type(a_type) is typing._GenericAlias
552 and a_type.__origin__ is typing.ClassVar))
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400553
554
555def _is_initvar(a_type, dataclasses):
556 # The module we're checking against is the module we're
557 # currently in (dataclasses.py).
558 return a_type is dataclasses.InitVar
559
560
561def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
562 # Given a type annotation string, does it refer to a_type in
563 # a_module? For example, when checking that annotation denotes a
564 # ClassVar, then a_module is typing, and a_type is
565 # typing.ClassVar.
566
567 # It's possible to look up a_module given a_type, but it involves
568 # looking in sys.modules (again!), and seems like a waste since
569 # the caller already knows a_module.
570
571 # - annotation is a string type annotation
572 # - cls is the class that this annotation was found in
573 # - a_module is the module we want to match
574 # - a_type is the type in that module we want to match
575 # - is_type_predicate is a function called with (obj, a_module)
576 # that determines if obj is of the desired type.
577
578 # Since this test does not do a local namespace lookup (and
579 # instead only a module (global) lookup), there are some things it
580 # gets wrong.
581
Eric V. Smithf8e75492018-05-16 05:14:53 -0400582 # With string annotations, cv0 will be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400583 # CV = ClassVar
584 # @dataclass
585 # class C0:
586 # cv0: CV
587
Eric V. Smithf8e75492018-05-16 05:14:53 -0400588 # But in this example cv1 will not be detected as a ClassVar:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400589 # @dataclass
590 # class C1:
591 # CV = ClassVar
592 # cv1: CV
593
Eric V. Smithf8e75492018-05-16 05:14:53 -0400594 # In C1, the code in this function (_is_type) will look up "CV" in
595 # the module and not find it, so it will not consider cv1 as a
596 # ClassVar. This is a fairly obscure corner case, and the best
597 # way to fix it would be to eval() the string "CV" with the
598 # correct global and local namespaces. However that would involve
599 # a eval() penalty for every single field of every dataclass
600 # that's defined. It was judged not worth it.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400601
602 match = _MODULE_IDENTIFIER_RE.match(annotation)
603 if match:
604 ns = None
605 module_name = match.group(1)
606 if not module_name:
607 # No module name, assume the class's module did
608 # "from dataclasses import InitVar".
609 ns = sys.modules.get(cls.__module__).__dict__
610 else:
611 # Look up module_name in the class's module.
612 module = sys.modules.get(cls.__module__)
613 if module and module.__dict__.get(module_name) is a_module:
614 ns = sys.modules.get(a_type.__module__).__dict__
615 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
616 return True
617 return False
618
619
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500620def _get_field(cls, a_name, a_type):
Eric V. Smithf96ddad2018-03-24 17:20:26 -0400621 # Return a Field object for this field name and type. ClassVars
Eric V. Smithf8e75492018-05-16 05:14:53 -0400622 # and InitVars are also returned, but marked as such (see
623 # f._field_type).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500624
Eric V. Smithf8e75492018-05-16 05:14:53 -0400625 # If the default value isn't derived from Field, then it's only a
626 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500627 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500628 if isinstance(default, Field):
629 f = default
630 else:
Eric V. Smith7389fd92018-03-19 21:07:51 -0400631 if isinstance(default, types.MemberDescriptorType):
632 # This is a field in __slots__, so it has no default value.
633 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500634 f = field(default=default)
635
Eric V. Smithf8e75492018-05-16 05:14:53 -0400636 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500637 f.name = a_name
638 f.type = a_type
639
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400640 # Assume it's a normal field until proven otherwise. We're next
Eric V. Smithf8e75492018-05-16 05:14:53 -0400641 # going to decide if it's a ClassVar or InitVar, everything else
642 # is just a normal field.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400643 f._field_type = _FIELD
644
645 # In addition to checking for actual types here, also check for
Eric V. Smithf8e75492018-05-16 05:14:53 -0400646 # string annotations. get_type_hints() won't always work for us
647 # (see https://github.com/python/typing/issues/508 for example),
648 # plus it's expensive and would require an eval for every stirng
649 # annotation. So, make a best effort to see if this is a ClassVar
650 # or InitVar using regex's and checking that the thing referenced
651 # is actually of the correct type.
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400652
653 # For the complete discussion, see https://bugs.python.org/issue33453
654
655 # If typing has not been imported, then it's impossible for any
Eric V. Smithf8e75492018-05-16 05:14:53 -0400656 # annotation to be a ClassVar. So, only look for ClassVar if
657 # typing has been imported by any module (not necessarily cls's
658 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500659 typing = sys.modules.get('typing')
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400660 if typing:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400661 if (_is_classvar(a_type, typing)
662 or (isinstance(f.type, str)
663 and _is_type(f.type, cls, typing, typing.ClassVar,
664 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500665 f._field_type = _FIELD_CLASSVAR
666
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400667 # If the type is InitVar, or if it's a matching string annotation,
668 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500669 if f._field_type is _FIELD:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400670 # The module we're checking against is the module we're
671 # currently in (dataclasses.py).
672 dataclasses = sys.modules[__name__]
673 if (_is_initvar(a_type, dataclasses)
674 or (isinstance(f.type, str)
675 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
676 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500677 f._field_type = _FIELD_INITVAR
678
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400679 # Validations for individual fields. This is delayed until now,
680 # instead of in the Field() constructor, since only here do we
681 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500682
683 # Special restrictions for ClassVar and InitVar.
684 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500685 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500686 raise TypeError(f'field {f.name} cannot have a '
687 'default factory')
688 # Should I check for other field settings? default_factory
Eric V. Smithf8e75492018-05-16 05:14:53 -0400689 # seems the most serious to check for. Maybe add others. For
690 # example, how about init=False (or really,
691 # init=<not-the-default-init-value>)? It makes no sense for
692 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500693
694 # For real fields, disallow mutable defaults for known types.
695 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
696 raise ValueError(f'mutable default {type(f.default)} for field '
697 f'{f.name} is not allowed: use default_factory')
698
699 return f
700
701
Eric V. Smithea8fc522018-01-27 19:07:40 -0500702def _set_new_attribute(cls, name, value):
703 # Never overwrites an existing attribute. Returns True if the
Eric V. Smithf8e75492018-05-16 05:14:53 -0400704 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500705 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500706 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500707 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500708 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500709
710
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500711# Decide if/how we're going to create a hash function. Key is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400712# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
713# take. The common case is to do nothing, so instead of providing a
714# function that is a no-op, use None to signify that.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400715
716def _hash_set_none(cls, fields):
717 return None
718
719def _hash_add(cls, fields):
720 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
721 return _hash_fn(flds)
722
723def _hash_exception(cls, fields):
724 # Raise an exception.
725 raise TypeError(f'Cannot overwrite attribute __hash__ '
726 f'in class {cls.__name__}')
727
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500728#
729# +-------------------------------------- unsafe_hash?
730# | +------------------------------- eq?
731# | | +------------------------ frozen?
732# | | | +---------------- has-explicit-hash?
733# | | | |
734# | | | | +------- action
735# | | | | |
736# v v v v v
Eric V. Smith01d618c2018-03-24 22:10:14 -0400737_hash_action = {(False, False, False, False): None,
738 (False, False, False, True ): None,
739 (False, False, True, False): None,
740 (False, False, True, True ): None,
741 (False, True, False, False): _hash_set_none,
742 (False, True, False, True ): None,
743 (False, True, True, False): _hash_add,
744 (False, True, True, True ): None,
745 (True, False, False, False): _hash_add,
746 (True, False, False, True ): _hash_exception,
747 (True, False, True, False): _hash_add,
748 (True, False, True, True ): _hash_exception,
749 (True, True, False, False): _hash_add,
750 (True, True, False, True ): _hash_exception,
751 (True, True, True, False): _hash_add,
752 (True, True, True, True ): _hash_exception,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500753 }
754# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Eric V. Smithf8e75492018-05-16 05:14:53 -0400755# version of this table.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500756
757
Eric V. Smithf199bc62018-03-18 20:40:34 -0400758def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500759 # Now that dicts retain insertion order, there's no reason to use
Eric V. Smithf8e75492018-05-16 05:14:53 -0400760 # an ordered dict. I am leveraging that ordering here, because
761 # derived class fields overwrite base class fields, but the order
762 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500763 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500764
Eric V. Smithf199bc62018-03-18 20:40:34 -0400765 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
766 unsafe_hash, frozen))
767
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500768 # Find our base classes in reverse MRO order, and exclude
Eric V. Smithf8e75492018-05-16 05:14:53 -0400769 # ourselves. In reversed order so that more derived classes
770 # override earlier field definitions in base classes. As long as
771 # we're iterating over them, see if any are frozen.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400772 any_frozen_base = False
773 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500774 for b in cls.__mro__[-1:0:-1]:
775 # Only process classes that have been processed by our
Eric V. Smithf8e75492018-05-16 05:14:53 -0400776 # decorator. That is, they have a _FIELDS attribute.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400777 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500778 if base_fields:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400779 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500780 for f in base_fields.values():
781 fields[f.name] = f
Eric V. Smithf199bc62018-03-18 20:40:34 -0400782 if getattr(b, _PARAMS).frozen:
783 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500784
Eric V. Smith56970b82018-03-22 16:28:48 -0400785 # Annotations that are defined in this class (not in base
Eric V. Smithf8e75492018-05-16 05:14:53 -0400786 # classes). If __annotations__ isn't present, then this class
787 # adds no new annotations. We use this to compute fields that are
788 # added by this class.
789 #
Eric V. Smith56970b82018-03-22 16:28:48 -0400790 # Fields are found from cls_annotations, which is guaranteed to be
Eric V. Smithf8e75492018-05-16 05:14:53 -0400791 # ordered. Default values are from class attributes, if a field
792 # has a default. If the default value is a Field(), then it
793 # contains additional info beyond (and possibly including) the
794 # actual default value. Pseudo-fields ClassVars and InitVars are
795 # included, despite the fact that they're not real fields. That's
796 # dealt with later.
Eric V. Smith56970b82018-03-22 16:28:48 -0400797 cls_annotations = cls.__dict__.get('__annotations__', {})
798
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500799 # Now find fields in our class. While doing so, validate some
Eric V. Smithf8e75492018-05-16 05:14:53 -0400800 # things, and set the default values (as class attributes) where
801 # we can.
Eric V. Smith56970b82018-03-22 16:28:48 -0400802 cls_fields = [_get_field(cls, name, type)
803 for name, type in cls_annotations.items()]
804 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500805 fields[f.name] = f
806
Eric V. Smithf8e75492018-05-16 05:14:53 -0400807 # If the class attribute (which is the default value for this
808 # field) exists and is of type 'Field', replace it with the
809 # real default. This is so that normal class introspection
810 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500811 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500812 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500813 # If there's no default, delete the class attribute.
Eric V. Smithf8e75492018-05-16 05:14:53 -0400814 # This happens if we specify field(repr=False), for
815 # example (that is, we specified a field object, but
816 # no default value). Also if we're using a default
817 # factory. The class attribute should not be set at
818 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500819 delattr(cls, f.name)
820 else:
821 setattr(cls, f.name, f.default)
822
Eric V. Smith56970b82018-03-22 16:28:48 -0400823 # Do we have any Field members that don't also have annotations?
824 for name, value in cls.__dict__.items():
825 if isinstance(value, Field) and not name in cls_annotations:
826 raise TypeError(f'{name!r} is a field but has no type annotation')
827
Eric V. Smithf199bc62018-03-18 20:40:34 -0400828 # Check rules that apply if we are derived from any dataclasses.
829 if has_dataclass_bases:
830 # Raise an exception if any of our bases are frozen, but we're not.
831 if any_frozen_base and not frozen:
832 raise TypeError('cannot inherit non-frozen dataclass from a '
833 'frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500834
Eric V. Smithf199bc62018-03-18 20:40:34 -0400835 # Raise an exception if we're frozen, but none of our bases are.
836 if not any_frozen_base and frozen:
837 raise TypeError('cannot inherit frozen dataclass from a '
838 'non-frozen one')
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500839
Eric V. Smithf8e75492018-05-16 05:14:53 -0400840 # Remember all of the fields on our class (including bases). This
841 # also marks this class as being a dataclass.
Eric V. Smithf199bc62018-03-18 20:40:34 -0400842 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500843
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500844 # Was this class defined with an explicit __hash__? Note that if
Eric V. Smithf8e75492018-05-16 05:14:53 -0400845 # __eq__ is defined in this class, then python will automatically
846 # set __hash__ to None. This is a heuristic, as it's possible
847 # that such a __hash__ == None was not auto-generated, but it
848 # close enough.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500849 class_hash = cls.__dict__.get('__hash__', MISSING)
850 has_explicit_hash = not (class_hash is MISSING or
851 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500852
Eric V. Smithf8e75492018-05-16 05:14:53 -0400853 # If we're generating ordering methods, we must be generating the
854 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500855 if order and not eq:
856 raise ValueError('eq must be true if order is true')
857
858 if init:
859 # Does this class have a post-init function?
860 has_post_init = hasattr(cls, _POST_INIT_NAME)
861
862 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500863 flds = [f for f in fields.values()
864 if f._field_type in (_FIELD, _FIELD_INITVAR)]
865 _set_new_attribute(cls, '__init__',
866 _init_fn(flds,
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500867 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500868 has_post_init,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400869 # The name to use for the "self"
870 # param in __init__. Use "self"
871 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500872 '__dataclass_self__' if 'self' in fields
873 else 'self',
874 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500875
876 # Get the fields as a list, and include only real fields. This is
Eric V. Smithf8e75492018-05-16 05:14:53 -0400877 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500878 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500879
880 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500881 flds = [f for f in field_list if f.repr]
882 _set_new_attribute(cls, '__repr__', _repr_fn(flds))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500883
884 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500885 # Create _eq__ method. There's no need for a __ne__ method,
Eric V. Smithf8e75492018-05-16 05:14:53 -0400886 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500887 flds = [f for f in field_list if f.compare]
888 self_tuple = _tuple_str('self', flds)
889 other_tuple = _tuple_str('other', flds)
890 _set_new_attribute(cls, '__eq__',
891 _cmp_fn('__eq__', '==',
892 self_tuple, other_tuple))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500893
894 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500895 # Create and set the ordering methods.
896 flds = [f for f in field_list if f.compare]
897 self_tuple = _tuple_str('self', flds)
898 other_tuple = _tuple_str('other', flds)
899 for name, op in [('__lt__', '<'),
900 ('__le__', '<='),
901 ('__gt__', '>'),
902 ('__ge__', '>='),
903 ]:
904 if _set_new_attribute(cls, name,
905 _cmp_fn(name, op, self_tuple, other_tuple)):
906 raise TypeError(f'Cannot overwrite attribute {name} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500907 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500908 'functools.total_ordering')
909
Eric V. Smith2fa6b9e2018-02-26 20:38:33 -0500910 if frozen:
Eric V. Smithf199bc62018-03-18 20:40:34 -0400911 for fn in _frozen_get_del_attr(cls, field_list):
912 if _set_new_attribute(cls, fn.__name__, fn):
913 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500914 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500915
916 # Decide if/how we're going to create a hash function.
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500917 hash_action = _hash_action[bool(unsafe_hash),
918 bool(eq),
919 bool(frozen),
920 has_explicit_hash]
Eric V. Smith01d618c2018-03-24 22:10:14 -0400921 if hash_action:
922 # No need to call _set_new_attribute here, since by the time
Eric V. Smithf8e75492018-05-16 05:14:53 -0400923 # we're here the overwriting is unconditional.
Eric V. Smith01d618c2018-03-24 22:10:14 -0400924 cls.__hash__ = hash_action(cls, field_list)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500925
926 if not getattr(cls, '__doc__'):
927 # Create a class doc-string.
928 cls.__doc__ = (cls.__name__ +
929 str(inspect.signature(cls)).replace(' -> None', ''))
930
931 return cls
932
933
934# _cls should never be specified by keyword, so start it with an
Eric V. Smithf8e75492018-05-16 05:14:53 -0400935# underscore. The presence of _cls is used to detect if this
936# decorator is being called with parameters or not.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500937def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -0500938 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500939 """Returns the same class as was passed in, with dunder methods
940 added based on the fields defined in the class.
941
942 Examines PEP 526 __annotations__ to determine fields.
943
944 If init is true, an __init__() method is added to the class. If
945 repr is true, a __repr__() method is added. If order is true, rich
Eric V. Smithdbf9cff2018-02-25 21:30:17 -0500946 comparison dunder methods are added. If unsafe_hash is true, a
947 __hash__() method function is added. If frozen is true, fields may
948 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500949 """
950
951 def wrap(cls):
Eric V. Smithf199bc62018-03-18 20:40:34 -0400952 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500953
954 # See if we're being called as @dataclass or @dataclass().
955 if _cls is None:
956 # We're called with parens.
957 return wrap
958
959 # We're called as @dataclass without parens.
960 return wrap(_cls)
961
962
963def fields(class_or_instance):
964 """Return a tuple describing the fields of this dataclass.
965
966 Accepts a dataclass or an instance of one. Tuple elements are of
967 type Field.
968 """
969
970 # Might it be worth caching this, per class?
971 try:
Eric V. Smith2a7bacb2018-05-15 22:44:27 -0400972 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500973 except AttributeError:
974 raise TypeError('must be called with a dataclass type or instance')
975
Eric V. Smithd1388922018-01-07 14:30:17 -0500976 # Exclude pseudo-fields. Note that fields is sorted by insertion
Eric V. Smithf8e75492018-05-16 05:14:53 -0400977 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500978 return tuple(f for f in fields.values() if f._field_type is _FIELD)
979
980
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500981def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500982 """Returns True if obj is an instance of a dataclass."""
Eric V. Smithf199bc62018-03-18 20:40:34 -0400983 return not isinstance(obj, type) and hasattr(obj, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500984
985
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500986def is_dataclass(obj):
987 """Returns True if obj is a dataclass or an instance of a
988 dataclass."""
Eric V. Smithf199bc62018-03-18 20:40:34 -0400989 return hasattr(obj, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500990
991
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500992def asdict(obj, *, dict_factory=dict):
993 """Return the fields of a dataclass instance as a new dictionary mapping
994 field names to field values.
995
996 Example usage:
997
998 @dataclass
999 class C:
1000 x: int
1001 y: int
1002
1003 c = C(1, 2)
1004 assert asdict(c) == {'x': 1, 'y': 2}
1005
1006 If given, 'dict_factory' will be used instead of built-in dict.
1007 The function applies recursively to field values that are
1008 dataclass instances. This will also look into built-in containers:
1009 tuples, lists, and dicts.
1010 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001011 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001012 raise TypeError("asdict() should be called on dataclass instances")
1013 return _asdict_inner(obj, dict_factory)
1014
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001015
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001016def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001017 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001018 result = []
1019 for f in fields(obj):
1020 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1021 result.append((f.name, value))
1022 return dict_factory(result)
1023 elif isinstance(obj, (list, tuple)):
1024 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1025 elif isinstance(obj, dict):
1026 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
1027 for k, v in obj.items())
1028 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001029 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001030
1031
1032def astuple(obj, *, tuple_factory=tuple):
1033 """Return the fields of a dataclass instance as a new tuple of field values.
1034
1035 Example usage::
1036
1037 @dataclass
1038 class C:
1039 x: int
1040 y: int
1041
1042 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001043 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001044
1045 If given, 'tuple_factory' will be used instead of built-in tuple.
1046 The function applies recursively to field values that are
1047 dataclass instances. This will also look into built-in containers:
1048 tuples, lists, and dicts.
1049 """
1050
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001051 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001052 raise TypeError("astuple() should be called on dataclass instances")
1053 return _astuple_inner(obj, tuple_factory)
1054
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001055
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001056def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001057 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001058 result = []
1059 for f in fields(obj):
1060 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1061 result.append(value)
1062 return tuple_factory(result)
1063 elif isinstance(obj, (list, tuple)):
1064 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1065 elif isinstance(obj, dict):
1066 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1067 for k, v in obj.items())
1068 else:
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001069 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001070
1071
Eric V. Smithd80b4432018-01-06 17:09:58 -05001072def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Eric V. Smith5da8cfb2018-03-01 08:01:41 -05001073 repr=True, eq=True, order=False, unsafe_hash=False,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001074 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001075 """Return a new dynamically created dataclass.
1076
Eric V. Smithed7d4292018-01-06 16:14:03 -05001077 The dataclass name will be 'cls_name'. 'fields' is an iterable
1078 of either (name), (name, type) or (name, type, Field) objects. If type is
1079 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001080 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001081
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001082 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001083
1084 is equivalent to:
1085
1086 @dataclass
1087 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001088 x: 'typing.Any'
1089 y: int
1090 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001091
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001092 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001093
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001094 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001095 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001096 """
1097
1098 if namespace is None:
1099 namespace = {}
1100 else:
1101 # Copy namespace since we're going to mutate it.
1102 namespace = namespace.copy()
1103
Eric V. Smith4e812962018-05-16 11:31:29 -04001104 # While we're looking through the field names, validate that they
1105 # are identifiers, are not keywords, and not duplicates.
1106 seen = set()
Eric V. Smithd1388922018-01-07 14:30:17 -05001107 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001108 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001109 if isinstance(item, str):
1110 name = item
1111 tp = 'typing.Any'
1112 elif len(item) == 2:
1113 name, tp, = item
1114 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001115 name, tp, spec = item
1116 namespace[name] = spec
Eric V. Smith4e812962018-05-16 11:31:29 -04001117 else:
1118 raise TypeError(f'Invalid field: {item!r}')
1119
1120 if not isinstance(name, str) or not name.isidentifier():
1121 raise TypeError(f'Field names must be valid identifers: {name!r}')
1122 if keyword.iskeyword(name):
1123 raise TypeError(f'Field names must not be keywords: {name!r}')
1124 if name in seen:
1125 raise TypeError(f'Field name duplicated: {name!r}')
1126
1127 seen.add(name)
Eric V. Smithed7d4292018-01-06 16:14:03 -05001128 anns[name] = tp
1129
1130 namespace['__annotations__'] = anns
Ivan Levkivskyi5a7092d2018-03-31 13:41:17 +01001131 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1132 # of generic dataclassses.
1133 cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace))
Eric V. Smithd80b4432018-01-06 17:09:58 -05001134 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Eric V. Smithdbf9cff2018-02-25 21:30:17 -05001135 unsafe_hash=unsafe_hash, frozen=frozen)
1136
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001137
1138def replace(obj, **changes):
1139 """Return a new object replacing specified fields with new values.
1140
1141 This is especially useful for frozen classes. Example usage:
1142
1143 @dataclass(frozen=True)
1144 class C:
1145 x: int
1146 y: int
1147
1148 c = C(1, 2)
1149 c1 = replace(c, x=3)
1150 assert c1.x == 3 and c1.y == 2
1151 """
1152
Eric V. Smithf8e75492018-05-16 05:14:53 -04001153 # We're going to mutate 'changes', but that's okay because it's a
1154 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001155
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001156 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001157 raise TypeError("replace() should be called on dataclass instances")
1158
1159 # It's an error to have init=False fields in 'changes'.
1160 # If a field is not in 'changes', read its value from the provided obj.
1161
Eric V. Smithf199bc62018-03-18 20:40:34 -04001162 for f in getattr(obj, _FIELDS).values():
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001163 if not f.init:
1164 # Error if this field is specified in changes.
1165 if f.name in changes:
1166 raise ValueError(f'field {f.name} is declared with '
1167 'init=False, it cannot be specified with '
1168 'replace()')
1169 continue
1170
1171 if f.name not in changes:
1172 changes[f.name] = getattr(obj, f.name)
1173
Eric V. Smithf96ddad2018-03-24 17:20:26 -04001174 # Create the new object, which calls __init__() and
Eric V. Smithf8e75492018-05-16 05:14:53 -04001175 # __post_init__() (if defined), using all of the init fields we've
1176 # added and/or left in 'changes'. If there are values supplied in
1177 # changes that aren't fields, this will correctly raise a
1178 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001179 return obj.__class__(**changes)