blob: a43d07693ac35e41c3bf2820f6bb83ae80b8d5ea [file] [log] [blame]
Miss Islington (bot)c73268a2018-05-15 21:22:13 -07001import re
Eric V. Smithf0db54a2017-12-04 16:58:55 -05002import sys
Miss Islington (bot)02c19a62018-03-24 14:42:28 -07003import copy
Eric V. Smithf0db54a2017-12-04 16:58:55 -05004import types
Eric V. Smithf0db54a2017-12-04 16:58:55 -05005import inspect
Miss Islington (bot)6409e752018-05-16 09:28:22 -07006import keyword
Miss Islington (bot)32e58fc2018-08-12 20:32:44 -07007import builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -05008
9__all__ = ['dataclass',
10 'field',
Miss Islington (bot)4ddc99d2018-03-21 14:44:23 -070011 'Field',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050012 'FrozenInstanceError',
13 'InitVar',
Eric V. Smith03220fd2017-12-29 13:59:58 -050014 'MISSING',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050015
16 # Helper functions.
17 'fields',
18 'asdict',
19 'astuple',
20 'make_dataclass',
21 'replace',
Eric V. Smithe7ba0132018-01-06 12:41:53 -050022 'is_dataclass',
Eric V. Smithf0db54a2017-12-04 16:58:55 -050023 ]
24
Eric V. Smithea8fc522018-01-27 19:07:40 -050025# Conditions for adding methods. The boxes indicate what action the
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -070026# dataclass decorator takes. For all of these tables, when I talk
27# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm
28# referring to the arguments to the @dataclass decorator. When
29# checking if a dunder method already exists, I mean check for an
30# entry in the class's __dict__. I never check to see if an attribute
31# is defined in a base class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050032
33# Key:
34# +=========+=========================================+
35# + Value | Meaning |
36# +=========+=========================================+
37# | <blank> | No action: no method is added. |
38# +---------+-----------------------------------------+
39# | add | Generated method is added. |
40# +---------+-----------------------------------------+
Eric V. Smithea8fc522018-01-27 19:07:40 -050041# | raise | TypeError is raised. |
42# +---------+-----------------------------------------+
43# | None | Attribute is set to None. |
44# +=========+=========================================+
45
46# __init__
47#
48# +--- init= parameter
49# |
50# v | | |
51# | no | yes | <--- class has __init__ in __dict__?
52# +=======+=======+=======+
53# | False | | |
54# +-------+-------+-------+
55# | True | add | | <- the default
56# +=======+=======+=======+
57
58# __repr__
59#
60# +--- repr= parameter
61# |
62# v | | |
63# | no | yes | <--- class has __repr__ in __dict__?
64# +=======+=======+=======+
65# | False | | |
66# +-------+-------+-------+
67# | True | add | | <- the default
68# +=======+=======+=======+
69
70
71# __setattr__
72# __delattr__
73#
74# +--- frozen= parameter
75# |
76# v | | |
77# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__?
78# +=======+=======+=======+
79# | False | | | <- the default
80# +-------+-------+-------+
81# | True | add | raise |
82# +=======+=======+=======+
83# Raise because not adding these methods would break the "frozen-ness"
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -070084# of the class.
Eric V. Smithea8fc522018-01-27 19:07:40 -050085
86# __eq__
87#
88# +--- eq= parameter
89# |
90# v | | |
91# | no | yes | <--- class has __eq__ in __dict__?
92# +=======+=======+=======+
93# | False | | |
94# +-------+-------+-------+
95# | True | add | | <- the default
96# +=======+=======+=======+
97
98# __lt__
99# __le__
100# __gt__
101# __ge__
102#
103# +--- order= parameter
104# |
105# v | | |
106# | no | yes | <--- class has any comparison method in __dict__?
107# +=======+=======+=======+
108# | False | | | <- the default
109# +-------+-------+-------+
110# | True | add | raise |
111# +=======+=======+=======+
112# Raise because to allow this case would interfere with using
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700113# functools.total_ordering.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500114
115# __hash__
116
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800117# +------------------- unsafe_hash= parameter
118# | +----------- eq= parameter
119# | | +--- frozen= parameter
120# | | |
121# v v v | | |
122# | no | yes | <--- class has explicitly defined __hash__
123# +=======+=======+=======+========+========+
124# | False | False | False | | | No __eq__, use the base class __hash__
125# +-------+-------+-------+--------+--------+
126# | False | False | True | | | No __eq__, use the base class __hash__
127# +-------+-------+-------+--------+--------+
128# | False | True | False | None | | <-- the default, not hashable
129# +-------+-------+-------+--------+--------+
130# | False | True | True | add | | Frozen, so hashable, allows override
131# +-------+-------+-------+--------+--------+
132# | True | False | False | add | raise | Has no __eq__, but hashable
133# +-------+-------+-------+--------+--------+
134# | True | False | True | add | raise | Has no __eq__, but hashable
135# +-------+-------+-------+--------+--------+
136# | True | True | False | add | raise | Not frozen, but hashable
137# +-------+-------+-------+--------+--------+
138# | True | True | True | add | raise | Frozen, so hashable
139# +=======+=======+=======+========+========+
Eric V. Smithea8fc522018-01-27 19:07:40 -0500140# For boxes that are blank, __hash__ is untouched and therefore
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700141# inherited from the base class. If the base is object, then
142# id-based hashing is used.
143#
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700144# Note that a class may already have __hash__=None if it specified an
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700145# __eq__ method in the class body (not one that was created by
146# @dataclass).
147#
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800148# See _hash_action (below) for a coded version of this table.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500149
150
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500151# Raised when an attempt is made to modify a frozen class.
152class FrozenInstanceError(AttributeError): pass
153
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700154# A sentinel object for default values to signal that a default
155# factory will be used. This is given a nice repr() which will appear
156# in the function signature of dataclasses' constructors.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500157class _HAS_DEFAULT_FACTORY_CLASS:
158 def __repr__(self):
159 return '<factory>'
160_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
161
Eric V. Smith03220fd2017-12-29 13:59:58 -0500162# A sentinel object to detect if a parameter is supplied or not. Use
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700163# a class to give it a better repr.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500164class _MISSING_TYPE:
165 pass
166MISSING = _MISSING_TYPE()
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500167
168# Since most per-field metadata will be unused, create an empty
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700169# read-only proxy that can be shared among all fields.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500170_EMPTY_METADATA = types.MappingProxyType({})
171
172# Markers for the various kinds of fields and pseudo-fields.
Miss Islington (bot)5c7e0792018-05-15 06:01:51 -0700173class _FIELD_BASE:
174 def __init__(self, name):
175 self.name = name
176 def __repr__(self):
177 return self.name
178_FIELD = _FIELD_BASE('_FIELD')
179_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR')
180_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500181
182# The name of an attribute on the class where we store the Field
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700183# objects. Also used to check if a class is a Data Class.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700184_FIELDS = '__dataclass_fields__'
185
186# The name of an attribute on the class that stores the parameters to
187# @dataclass.
188_PARAMS = '__dataclass_params__'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500189
190# The name of the function, that if it exists, is called at the end of
191# __init__.
192_POST_INIT_NAME = '__post_init__'
193
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700194# String regex that string annotations for ClassVar or InitVar must match.
195# Allows "identifier.identifier[" or "identifier[".
196# https://bugs.python.org/issue33453 for details.
197_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500198
199class _InitVarMeta(type):
200 def __getitem__(self, params):
201 return self
202
203class InitVar(metaclass=_InitVarMeta):
204 pass
205
206
207# Instances of Field are only ever created from within this module,
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700208# and only from the field() function, although Field instances are
209# exposed externally as (conceptually) read-only objects.
210#
211# name and type are filled in after the fact, not in __init__.
212# They're not known at the time this class is instantiated, but it's
213# convenient if they're available later.
214#
Miss Islington (bot)45648312018-03-18 18:03:36 -0700215# When cls._FIELDS is filled in with a list of Field objects, the name
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700216# and type fields will have been populated.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500217class Field:
218 __slots__ = ('name',
219 'type',
220 'default',
221 'default_factory',
222 'repr',
223 'hash',
224 'init',
225 'compare',
226 'metadata',
227 '_field_type', # Private: not to be used by user code.
228 )
229
230 def __init__(self, default, default_factory, init, repr, hash, compare,
231 metadata):
232 self.name = None
233 self.type = None
234 self.default = default
235 self.default_factory = default_factory
236 self.init = init
237 self.repr = repr
238 self.hash = hash
239 self.compare = compare
240 self.metadata = (_EMPTY_METADATA
241 if metadata is None or len(metadata) == 0 else
242 types.MappingProxyType(metadata))
243 self._field_type = None
244
245 def __repr__(self):
246 return ('Field('
247 f'name={self.name!r},'
Miss Islington (bot)ceb45f02018-05-14 10:31:10 -0700248 f'type={self.type!r},'
249 f'default={self.default!r},'
250 f'default_factory={self.default_factory!r},'
251 f'init={self.init!r},'
252 f'repr={self.repr!r},'
253 f'hash={self.hash!r},'
254 f'compare={self.compare!r},'
Miss Islington (bot)5c7e0792018-05-15 06:01:51 -0700255 f'metadata={self.metadata!r},'
256 f'_field_type={self._field_type}'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500257 ')')
258
Miss Islington (bot)c6147ac2018-03-26 10:55:13 -0700259 # This is used to support the PEP 487 __set_name__ protocol in the
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700260 # case where we're using a field that contains a descriptor as a
Miss Islington (bot)3a7ee282018-07-05 16:28:18 -0700261 # default value. For details on __set_name__, see
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700262 # https://www.python.org/dev/peps/pep-0487/#implementation-details.
263 #
264 # Note that in _process_class, this Field object is overwritten
265 # with the default value, so the end result is a descriptor that
266 # had __set_name__ called on it at the right time.
Miss Islington (bot)c6147ac2018-03-26 10:55:13 -0700267 def __set_name__(self, owner, name):
Miss Islington (bot)faa6f5c2018-03-29 08:32:36 -0700268 func = getattr(type(self.default), '__set_name__', None)
Miss Islington (bot)c6147ac2018-03-26 10:55:13 -0700269 if func:
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700270 # There is a __set_name__ method on the descriptor, call
271 # it.
Miss Islington (bot)faa6f5c2018-03-29 08:32:36 -0700272 func(self.default, owner, name)
Miss Islington (bot)c6147ac2018-03-26 10:55:13 -0700273
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500274
Miss Islington (bot)45648312018-03-18 18:03:36 -0700275class _DataclassParams:
276 __slots__ = ('init',
277 'repr',
278 'eq',
279 'order',
280 'unsafe_hash',
281 'frozen',
282 )
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700283
Miss Islington (bot)45648312018-03-18 18:03:36 -0700284 def __init__(self, init, repr, eq, order, unsafe_hash, frozen):
285 self.init = init
286 self.repr = repr
287 self.eq = eq
288 self.order = order
289 self.unsafe_hash = unsafe_hash
290 self.frozen = frozen
291
292 def __repr__(self):
293 return ('_DataclassParams('
Miss Islington (bot)b57aeac2018-05-14 16:57:30 -0700294 f'init={self.init!r},'
295 f'repr={self.repr!r},'
296 f'eq={self.eq!r},'
297 f'order={self.order!r},'
298 f'unsafe_hash={self.unsafe_hash!r},'
299 f'frozen={self.frozen!r}'
Miss Islington (bot)45648312018-03-18 18:03:36 -0700300 ')')
301
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700302
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500303# This function is used instead of exposing Field creation directly,
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700304# so that a type checker can be told (via overloads) that this is a
305# function whose type depends on its parameters.
Eric V. Smith03220fd2017-12-29 13:59:58 -0500306def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500307 hash=None, compare=True, metadata=None):
308 """Return an object to identify dataclass fields.
309
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700310 default is the default value of the field. default_factory is a
311 0-argument function called to initialize a field's value. If init
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500312 is True, the field will be a parameter to the class's __init__()
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700313 function. If repr is True, the field will be included in the
314 object's repr(). If hash is True, the field will be included in
315 the object's hash(). If compare is True, the field will be used
316 in comparison functions. metadata, if specified, must be a
317 mapping which is stored but not otherwise examined by dataclass.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500318
319 It is an error to specify both default and default_factory.
320 """
321
Eric V. Smith03220fd2017-12-29 13:59:58 -0500322 if default is not MISSING and default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500323 raise ValueError('cannot specify both default and default_factory')
324 return Field(default, default_factory, init, repr, hash, compare,
325 metadata)
326
327
328def _tuple_str(obj_name, fields):
329 # Return a string representing each field of obj_name as a tuple
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700330 # member. So, if fields is ['x', 'y'] and obj_name is "self",
331 # return "(self.x,self.y)".
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500332
333 # Special case for the 0-tuple.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500334 if not fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500335 return '()'
336 # Note the trailing comma, needed if this turns out to be a 1-tuple.
337 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)'
338
339
Eric V. Smithea8fc522018-01-27 19:07:40 -0500340def _create_fn(name, args, body, *, globals=None, locals=None,
Eric V. Smith03220fd2017-12-29 13:59:58 -0500341 return_type=MISSING):
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700342 # Note that we mutate locals when exec() is called. Caller
343 # beware! The only callers are internal to this module, so no
344 # worries about external callers.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500345 if locals is None:
346 locals = {}
Miss Islington (bot)32e58fc2018-08-12 20:32:44 -0700347 # __builtins__ may be the "builtins" module or
348 # the value of its "__dict__",
349 # so make sure "__builtins__" is the module.
350 if globals is not None and '__builtins__' not in globals:
351 globals['__builtins__'] = builtins
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500352 return_annotation = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500353 if return_type is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500354 locals['_return_type'] = return_type
355 return_annotation = '->_return_type'
356 args = ','.join(args)
357 body = '\n'.join(f' {b}' for b in body)
358
Miss Islington (bot)45648312018-03-18 18:03:36 -0700359 # Compute the text of the entire function.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500360 txt = f'def {name}({args}){return_annotation}:\n{body}'
361
362 exec(txt, globals, locals)
363 return locals[name]
364
365
366def _field_assign(frozen, name, value, self_name):
367 # If we're a frozen class, then assign to our fields in __init__
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700368 # via object.__setattr__. Otherwise, just use a simple
369 # assignment.
370 #
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500371 # self_name is what "self" is called in this function: don't
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700372 # hard-code "self", since that might be a field name.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500373 if frozen:
Miss Islington (bot)32e58fc2018-08-12 20:32:44 -0700374 return f'__builtins__.object.__setattr__({self_name},{name!r},{value})'
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500375 return f'{self_name}.{name}={value}'
376
377
378def _field_init(f, frozen, globals, self_name):
379 # Return the text of the line in the body of __init__ that will
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700380 # initialize this field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500381
382 default_name = f'_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500383 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500384 if f.init:
385 # This field has a default factory. If a parameter is
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700386 # given, use it. If not, call the factory.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500387 globals[default_name] = f.default_factory
388 value = (f'{default_name}() '
389 f'if {f.name} is _HAS_DEFAULT_FACTORY '
390 f'else {f.name}')
391 else:
392 # This is a field that's not in the __init__ params, but
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700393 # has a default factory function. It needs to be
394 # initialized here by calling the factory function,
395 # because there's no other way to initialize it.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500396
397 # For a field initialized with a default=defaultvalue, the
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700398 # class dict just has the default value
399 # (cls.fieldname=defaultvalue). But that won't work for a
400 # default factory, the factory must be called in __init__
401 # and we must assign that to self.fieldname. We can't
402 # fall back to the class dict's value, both because it's
403 # not set, and because it might be different per-class
404 # (which, after all, is why we have a factory function!).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500405
406 globals[default_name] = f.default_factory
407 value = f'{default_name}()'
408 else:
409 # No default factory.
410 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500411 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500412 # There's no default, just do an assignment.
413 value = f.name
Eric V. Smith03220fd2017-12-29 13:59:58 -0500414 elif f.default is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500415 globals[default_name] = f.default
416 value = f.name
417 else:
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700418 # This field does not need initialization. Signify that
419 # to the caller by returning None.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500420 return None
421
422 # Only test this now, so that we can create variables for the
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700423 # default. However, return None to signify that we're not going
424 # to actually do the assignment statement for InitVars.
Miss Islington (bot)0aee3be2018-06-07 13:15:23 -0700425 if f._field_type is _FIELD_INITVAR:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500426 return None
427
428 # Now, actually generate the field assignment.
429 return _field_assign(frozen, f.name, value, self_name)
430
431
432def _init_param(f):
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700433 # Return the __init__ parameter string for this field. For
434 # example, the equivalent of 'x:int=3' (except instead of 'int',
435 # reference a variable set to int, and instead of '3', reference a
436 # variable set to 3).
Eric V. Smith03220fd2017-12-29 13:59:58 -0500437 if f.default is MISSING and f.default_factory is MISSING:
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700438 # There's no default, and no default_factory, just output the
439 # variable name and type.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500440 default = ''
Eric V. Smith03220fd2017-12-29 13:59:58 -0500441 elif f.default is not MISSING:
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700442 # There's a default, this will be the name that's used to look
443 # it up.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500444 default = f'=_dflt_{f.name}'
Eric V. Smith03220fd2017-12-29 13:59:58 -0500445 elif f.default_factory is not MISSING:
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700446 # There's a factory function. Set a marker.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500447 default = '=_HAS_DEFAULT_FACTORY'
448 return f'{f.name}:_type_{f.name}{default}'
449
450
451def _init_fn(fields, frozen, has_post_init, self_name):
452 # fields contains both real fields and InitVar pseudo-fields.
453
454 # Make sure we don't have fields without defaults following fields
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700455 # with defaults. This actually would be caught when exec-ing the
456 # function source code, but catching it here gives a better error
457 # message, and future-proofs us in case we build up the function
458 # using ast.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500459 seen_default = False
460 for f in fields:
461 # Only consider fields in the __init__ call.
462 if f.init:
Eric V. Smith03220fd2017-12-29 13:59:58 -0500463 if not (f.default is MISSING and f.default_factory is MISSING):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500464 seen_default = True
465 elif seen_default:
466 raise TypeError(f'non-default argument {f.name!r} '
467 'follows default argument')
468
Eric V. Smith03220fd2017-12-29 13:59:58 -0500469 globals = {'MISSING': MISSING,
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500470 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY}
471
472 body_lines = []
473 for f in fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500474 line = _field_init(f, frozen, globals, self_name)
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700475 # line is None means that this field doesn't require
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700476 # initialization (it's a pseudo-field). Just skip it.
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700477 if line:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500478 body_lines.append(line)
479
480 # Does this class have a post-init function?
481 if has_post_init:
482 params_str = ','.join(f.name for f in fields
483 if f._field_type is _FIELD_INITVAR)
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700484 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})')
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500485
486 # If no body lines, use 'pass'.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500487 if not body_lines:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500488 body_lines = ['pass']
489
490 locals = {f'_type_{f.name}': f.type for f in fields}
491 return _create_fn('__init__',
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700492 [self_name] + [_init_param(f) for f in fields if f.init],
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500493 body_lines,
494 locals=locals,
495 globals=globals,
496 return_type=None)
497
498
499def _repr_fn(fields):
500 return _create_fn('__repr__',
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700501 ('self',),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500502 ['return self.__class__.__qualname__ + f"(' +
503 ', '.join([f"{f.name}={{self.{f.name}!r}}"
504 for f in fields]) +
505 ')"'])
506
507
Miss Islington (bot)45648312018-03-18 18:03:36 -0700508def _frozen_get_del_attr(cls, fields):
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700509 # XXX: globals is modified on the first call to _create_fn, then
510 # the modified version is used in the second call. Is this okay?
Miss Islington (bot)45648312018-03-18 18:03:36 -0700511 globals = {'cls': cls,
512 'FrozenInstanceError': FrozenInstanceError}
513 if fields:
514 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
515 else:
516 # Special case for the zero-length tuple.
517 fields_str = '()'
518 return (_create_fn('__setattr__',
519 ('self', 'name', 'value'),
520 (f'if type(self) is cls or name in {fields_str}:',
521 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
522 f'super(cls, self).__setattr__(name, value)'),
523 globals=globals),
524 _create_fn('__delattr__',
525 ('self', 'name'),
526 (f'if type(self) is cls or name in {fields_str}:',
527 ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
528 f'super(cls, self).__delattr__(name)'),
529 globals=globals),
530 )
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500531
532
533def _cmp_fn(name, op, self_tuple, other_tuple):
534 # Create a comparison function. If the fields in the object are
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700535 # named 'x' and 'y', then self_tuple is the string
536 # '(self.x,self.y)' and other_tuple is the string
537 # '(other.x,other.y)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500538
539 return _create_fn(name,
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700540 ('self', 'other'),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500541 [ 'if other.__class__ is self.__class__:',
542 f' return {self_tuple}{op}{other_tuple}',
543 'return NotImplemented'])
544
545
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500546def _hash_fn(fields):
547 self_tuple = _tuple_str('self', fields)
548 return _create_fn('__hash__',
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700549 ('self',),
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500550 [f'return hash({self_tuple})'])
551
552
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700553def _is_classvar(a_type, typing):
Miss Islington (bot)8e20fc32018-05-16 04:46:32 -0700554 # This test uses a typing internal class, but it's the best way to
555 # test if this is a ClassVar.
556 return (a_type is typing.ClassVar
557 or (type(a_type) is typing._GenericAlias
558 and a_type.__origin__ is typing.ClassVar))
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700559
560
561def _is_initvar(a_type, dataclasses):
562 # The module we're checking against is the module we're
563 # currently in (dataclasses.py).
564 return a_type is dataclasses.InitVar
565
566
567def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
568 # Given a type annotation string, does it refer to a_type in
569 # a_module? For example, when checking that annotation denotes a
570 # ClassVar, then a_module is typing, and a_type is
571 # typing.ClassVar.
572
573 # It's possible to look up a_module given a_type, but it involves
574 # looking in sys.modules (again!), and seems like a waste since
575 # the caller already knows a_module.
576
577 # - annotation is a string type annotation
578 # - cls is the class that this annotation was found in
579 # - a_module is the module we want to match
580 # - a_type is the type in that module we want to match
581 # - is_type_predicate is a function called with (obj, a_module)
582 # that determines if obj is of the desired type.
583
584 # Since this test does not do a local namespace lookup (and
585 # instead only a module (global) lookup), there are some things it
586 # gets wrong.
587
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700588 # With string annotations, cv0 will be detected as a ClassVar:
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700589 # CV = ClassVar
590 # @dataclass
591 # class C0:
592 # cv0: CV
593
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700594 # But in this example cv1 will not be detected as a ClassVar:
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700595 # @dataclass
596 # class C1:
597 # CV = ClassVar
598 # cv1: CV
599
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700600 # In C1, the code in this function (_is_type) will look up "CV" in
601 # the module and not find it, so it will not consider cv1 as a
602 # ClassVar. This is a fairly obscure corner case, and the best
603 # way to fix it would be to eval() the string "CV" with the
604 # correct global and local namespaces. However that would involve
605 # a eval() penalty for every single field of every dataclass
606 # that's defined. It was judged not worth it.
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700607
608 match = _MODULE_IDENTIFIER_RE.match(annotation)
609 if match:
610 ns = None
611 module_name = match.group(1)
612 if not module_name:
613 # No module name, assume the class's module did
614 # "from dataclasses import InitVar".
615 ns = sys.modules.get(cls.__module__).__dict__
616 else:
617 # Look up module_name in the class's module.
618 module = sys.modules.get(cls.__module__)
619 if module and module.__dict__.get(module_name) is a_module:
620 ns = sys.modules.get(a_type.__module__).__dict__
621 if ns and is_type_predicate(ns.get(match.group(2)), a_module):
622 return True
623 return False
624
625
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500626def _get_field(cls, a_name, a_type):
Miss Islington (bot)02c19a62018-03-24 14:42:28 -0700627 # Return a Field object for this field name and type. ClassVars
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700628 # and InitVars are also returned, but marked as such (see
629 # f._field_type).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500630
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700631 # If the default value isn't derived from Field, then it's only a
632 # normal default value. Convert it to a Field().
Eric V. Smith03220fd2017-12-29 13:59:58 -0500633 default = getattr(cls, a_name, MISSING)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500634 if isinstance(default, Field):
635 f = default
636 else:
Miss Islington (bot)3d41f482018-03-19 18:31:22 -0700637 if isinstance(default, types.MemberDescriptorType):
638 # This is a field in __slots__, so it has no default value.
639 default = MISSING
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500640 f = field(default=default)
641
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700642 # Only at this point do we know the name and the type. Set them.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500643 f.name = a_name
644 f.type = a_type
645
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700646 # Assume it's a normal field until proven otherwise. We're next
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700647 # going to decide if it's a ClassVar or InitVar, everything else
648 # is just a normal field.
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700649 f._field_type = _FIELD
650
651 # In addition to checking for actual types here, also check for
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700652 # string annotations. get_type_hints() won't always work for us
653 # (see https://github.com/python/typing/issues/508 for example),
654 # plus it's expensive and would require an eval for every stirng
655 # annotation. So, make a best effort to see if this is a ClassVar
656 # or InitVar using regex's and checking that the thing referenced
657 # is actually of the correct type.
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700658
659 # For the complete discussion, see https://bugs.python.org/issue33453
660
661 # If typing has not been imported, then it's impossible for any
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700662 # annotation to be a ClassVar. So, only look for ClassVar if
663 # typing has been imported by any module (not necessarily cls's
664 # module).
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500665 typing = sys.modules.get('typing')
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700666 if typing:
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700667 if (_is_classvar(a_type, typing)
668 or (isinstance(f.type, str)
669 and _is_type(f.type, cls, typing, typing.ClassVar,
670 _is_classvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500671 f._field_type = _FIELD_CLASSVAR
672
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700673 # If the type is InitVar, or if it's a matching string annotation,
674 # then it's an InitVar.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500675 if f._field_type is _FIELD:
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700676 # The module we're checking against is the module we're
677 # currently in (dataclasses.py).
678 dataclasses = sys.modules[__name__]
679 if (_is_initvar(a_type, dataclasses)
680 or (isinstance(f.type, str)
681 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar,
682 _is_initvar))):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500683 f._field_type = _FIELD_INITVAR
684
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700685 # Validations for individual fields. This is delayed until now,
686 # instead of in the Field() constructor, since only here do we
687 # know the field name, which allows for better error reporting.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500688
689 # Special restrictions for ClassVar and InitVar.
690 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500691 if f.default_factory is not MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500692 raise TypeError(f'field {f.name} cannot have a '
693 'default factory')
694 # Should I check for other field settings? default_factory
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700695 # seems the most serious to check for. Maybe add others. For
696 # example, how about init=False (or really,
697 # init=<not-the-default-init-value>)? It makes no sense for
698 # ClassVar and InitVar to specify init=<anything>.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500699
700 # For real fields, disallow mutable defaults for known types.
701 if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)):
702 raise ValueError(f'mutable default {type(f.default)} for field '
703 f'{f.name} is not allowed: use default_factory')
704
705 return f
706
707
Eric V. Smithea8fc522018-01-27 19:07:40 -0500708def _set_new_attribute(cls, name, value):
709 # Never overwrites an existing attribute. Returns True if the
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700710 # attribute already exists.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500711 if name in cls.__dict__:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500712 return True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500713 setattr(cls, name, value)
Eric V. Smithea8fc522018-01-27 19:07:40 -0500714 return False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500715
716
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800717# Decide if/how we're going to create a hash function. Key is
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700718# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to
719# take. The common case is to do nothing, so instead of providing a
720# function that is a no-op, use None to signify that.
Miss Islington (bot)9989efb2018-03-24 19:31:29 -0700721
722def _hash_set_none(cls, fields):
723 return None
724
725def _hash_add(cls, fields):
726 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
727 return _hash_fn(flds)
728
729def _hash_exception(cls, fields):
730 # Raise an exception.
731 raise TypeError(f'Cannot overwrite attribute __hash__ '
732 f'in class {cls.__name__}')
733
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800734#
735# +-------------------------------------- unsafe_hash?
736# | +------------------------------- eq?
737# | | +------------------------ frozen?
738# | | | +---------------- has-explicit-hash?
739# | | | |
740# | | | | +------- action
741# | | | | |
742# v v v v v
Miss Islington (bot)9989efb2018-03-24 19:31:29 -0700743_hash_action = {(False, False, False, False): None,
744 (False, False, False, True ): None,
745 (False, False, True, False): None,
746 (False, False, True, True ): None,
747 (False, True, False, False): _hash_set_none,
748 (False, True, False, True ): None,
749 (False, True, True, False): _hash_add,
750 (False, True, True, True ): None,
751 (True, False, False, False): _hash_add,
752 (True, False, False, True ): _hash_exception,
753 (True, False, True, False): _hash_add,
754 (True, False, True, True ): _hash_exception,
755 (True, True, False, False): _hash_add,
756 (True, True, False, True ): _hash_exception,
757 (True, True, True, False): _hash_add,
758 (True, True, True, True ): _hash_exception,
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800759 }
760# See https://bugs.python.org/issue32929#msg312829 for an if-statement
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700761# version of this table.
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800762
763
Miss Islington (bot)45648312018-03-18 18:03:36 -0700764def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
Eric V. Smithd1388922018-01-07 14:30:17 -0500765 # Now that dicts retain insertion order, there's no reason to use
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700766 # an ordered dict. I am leveraging that ordering here, because
767 # derived class fields overwrite base class fields, but the order
768 # is defined by the base class, which is found first.
Eric V. Smithd1388922018-01-07 14:30:17 -0500769 fields = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500770
Miss Islington (bot)45648312018-03-18 18:03:36 -0700771 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
772 unsafe_hash, frozen))
773
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500774 # Find our base classes in reverse MRO order, and exclude
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700775 # ourselves. In reversed order so that more derived classes
776 # override earlier field definitions in base classes. As long as
777 # we're iterating over them, see if any are frozen.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700778 any_frozen_base = False
779 has_dataclass_bases = False
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500780 for b in cls.__mro__[-1:0:-1]:
781 # Only process classes that have been processed by our
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700782 # decorator. That is, they have a _FIELDS attribute.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700783 base_fields = getattr(b, _FIELDS, None)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500784 if base_fields:
Miss Islington (bot)45648312018-03-18 18:03:36 -0700785 has_dataclass_bases = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500786 for f in base_fields.values():
787 fields[f.name] = f
Miss Islington (bot)45648312018-03-18 18:03:36 -0700788 if getattr(b, _PARAMS).frozen:
789 any_frozen_base = True
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500790
Miss Islington (bot)3b4c6b12018-03-22 13:58:59 -0700791 # Annotations that are defined in this class (not in base
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700792 # classes). If __annotations__ isn't present, then this class
793 # adds no new annotations. We use this to compute fields that are
794 # added by this class.
795 #
Miss Islington (bot)3b4c6b12018-03-22 13:58:59 -0700796 # Fields are found from cls_annotations, which is guaranteed to be
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700797 # ordered. Default values are from class attributes, if a field
798 # has a default. If the default value is a Field(), then it
799 # contains additional info beyond (and possibly including) the
800 # actual default value. Pseudo-fields ClassVars and InitVars are
801 # included, despite the fact that they're not real fields. That's
802 # dealt with later.
Miss Islington (bot)3b4c6b12018-03-22 13:58:59 -0700803 cls_annotations = cls.__dict__.get('__annotations__', {})
804
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500805 # Now find fields in our class. While doing so, validate some
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700806 # things, and set the default values (as class attributes) where
807 # we can.
Miss Islington (bot)3b4c6b12018-03-22 13:58:59 -0700808 cls_fields = [_get_field(cls, name, type)
809 for name, type in cls_annotations.items()]
810 for f in cls_fields:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500811 fields[f.name] = f
812
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700813 # If the class attribute (which is the default value for this
814 # field) exists and is of type 'Field', replace it with the
815 # real default. This is so that normal class introspection
816 # sees a real default value, not a Field.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500817 if isinstance(getattr(cls, f.name, None), Field):
Eric V. Smith03220fd2017-12-29 13:59:58 -0500818 if f.default is MISSING:
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500819 # If there's no default, delete the class attribute.
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700820 # This happens if we specify field(repr=False), for
821 # example (that is, we specified a field object, but
822 # no default value). Also if we're using a default
823 # factory. The class attribute should not be set at
824 # all in the post-processed class.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500825 delattr(cls, f.name)
826 else:
827 setattr(cls, f.name, f.default)
828
Miss Islington (bot)3b4c6b12018-03-22 13:58:59 -0700829 # Do we have any Field members that don't also have annotations?
830 for name, value in cls.__dict__.items():
831 if isinstance(value, Field) and not name in cls_annotations:
832 raise TypeError(f'{name!r} is a field but has no type annotation')
833
Miss Islington (bot)45648312018-03-18 18:03:36 -0700834 # Check rules that apply if we are derived from any dataclasses.
835 if has_dataclass_bases:
836 # Raise an exception if any of our bases are frozen, but we're not.
837 if any_frozen_base and not frozen:
838 raise TypeError('cannot inherit non-frozen dataclass from a '
839 'frozen one')
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800840
Miss Islington (bot)45648312018-03-18 18:03:36 -0700841 # Raise an exception if we're frozen, but none of our bases are.
842 if not any_frozen_base and frozen:
843 raise TypeError('cannot inherit frozen dataclass from a '
844 'non-frozen one')
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800845
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700846 # Remember all of the fields on our class (including bases). This
847 # also marks this class as being a dataclass.
Miss Islington (bot)45648312018-03-18 18:03:36 -0700848 setattr(cls, _FIELDS, fields)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500849
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800850 # Was this class defined with an explicit __hash__? Note that if
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700851 # __eq__ is defined in this class, then python will automatically
852 # set __hash__ to None. This is a heuristic, as it's possible
853 # that such a __hash__ == None was not auto-generated, but it
854 # close enough.
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800855 class_hash = cls.__dict__.get('__hash__', MISSING)
856 has_explicit_hash = not (class_hash is MISSING or
857 (class_hash is None and '__eq__' in cls.__dict__))
Eric V. Smithea8fc522018-01-27 19:07:40 -0500858
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700859 # If we're generating ordering methods, we must be generating the
860 # eq methods.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500861 if order and not eq:
862 raise ValueError('eq must be true if order is true')
863
864 if init:
865 # Does this class have a post-init function?
866 has_post_init = hasattr(cls, _POST_INIT_NAME)
867
868 # Include InitVars and regular fields (so, not ClassVars).
Eric V. Smithea8fc522018-01-27 19:07:40 -0500869 flds = [f for f in fields.values()
870 if f._field_type in (_FIELD, _FIELD_INITVAR)]
871 _set_new_attribute(cls, '__init__',
872 _init_fn(flds,
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800873 frozen,
Eric V. Smithea8fc522018-01-27 19:07:40 -0500874 has_post_init,
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700875 # The name to use for the "self"
876 # param in __init__. Use "self"
877 # if possible.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500878 '__dataclass_self__' if 'self' in fields
879 else 'self',
880 ))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500881
882 # Get the fields as a list, and include only real fields. This is
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700883 # used in all of the following methods.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500884 field_list = [f for f in fields.values() if f._field_type is _FIELD]
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500885
886 if repr:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500887 flds = [f for f in field_list if f.repr]
888 _set_new_attribute(cls, '__repr__', _repr_fn(flds))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500889
890 if eq:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500891 # Create _eq__ method. There's no need for a __ne__ method,
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700892 # since python will call __eq__ and negate it.
Eric V. Smithea8fc522018-01-27 19:07:40 -0500893 flds = [f for f in field_list if f.compare]
894 self_tuple = _tuple_str('self', flds)
895 other_tuple = _tuple_str('other', flds)
896 _set_new_attribute(cls, '__eq__',
897 _cmp_fn('__eq__', '==',
898 self_tuple, other_tuple))
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500899
900 if order:
Eric V. Smithea8fc522018-01-27 19:07:40 -0500901 # Create and set the ordering methods.
902 flds = [f for f in field_list if f.compare]
903 self_tuple = _tuple_str('self', flds)
904 other_tuple = _tuple_str('other', flds)
905 for name, op in [('__lt__', '<'),
906 ('__le__', '<='),
907 ('__gt__', '>'),
908 ('__ge__', '>='),
909 ]:
910 if _set_new_attribute(cls, name,
911 _cmp_fn(name, op, self_tuple, other_tuple)):
912 raise TypeError(f'Cannot overwrite attribute {name} '
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800913 f'in class {cls.__name__}. Consider using '
Eric V. Smithea8fc522018-01-27 19:07:40 -0500914 'functools.total_ordering')
915
Miss Islington (bot)a93e3dc2018-02-26 17:59:55 -0800916 if frozen:
Miss Islington (bot)45648312018-03-18 18:03:36 -0700917 for fn in _frozen_get_del_attr(cls, field_list):
918 if _set_new_attribute(cls, fn.__name__, fn):
919 raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800920 f'in class {cls.__name__}')
Eric V. Smithea8fc522018-01-27 19:07:40 -0500921
922 # Decide if/how we're going to create a hash function.
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800923 hash_action = _hash_action[bool(unsafe_hash),
924 bool(eq),
925 bool(frozen),
926 has_explicit_hash]
Miss Islington (bot)9989efb2018-03-24 19:31:29 -0700927 if hash_action:
928 # No need to call _set_new_attribute here, since by the time
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700929 # we're here the overwriting is unconditional.
Miss Islington (bot)9989efb2018-03-24 19:31:29 -0700930 cls.__hash__ = hash_action(cls, field_list)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500931
932 if not getattr(cls, '__doc__'):
933 # Create a class doc-string.
934 cls.__doc__ = (cls.__name__ +
935 str(inspect.signature(cls)).replace(' -> None', ''))
936
937 return cls
938
939
940# _cls should never be specified by keyword, so start it with an
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700941# underscore. The presence of _cls is used to detect if this
942# decorator is being called with parameters or not.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500943def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False,
Miss Islington (bot)398242a2018-03-01 05:30:13 -0800944 unsafe_hash=False, frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500945 """Returns the same class as was passed in, with dunder methods
946 added based on the fields defined in the class.
947
948 Examines PEP 526 __annotations__ to determine fields.
949
950 If init is true, an __init__() method is added to the class. If
951 repr is true, a __repr__() method is added. If order is true, rich
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -0800952 comparison dunder methods are added. If unsafe_hash is true, a
953 __hash__() method function is added. If frozen is true, fields may
954 not be assigned to after instance creation.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500955 """
956
957 def wrap(cls):
Miss Islington (bot)45648312018-03-18 18:03:36 -0700958 return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500959
960 # See if we're being called as @dataclass or @dataclass().
961 if _cls is None:
962 # We're called with parens.
963 return wrap
964
965 # We're called as @dataclass without parens.
966 return wrap(_cls)
967
968
969def fields(class_or_instance):
970 """Return a tuple describing the fields of this dataclass.
971
972 Accepts a dataclass or an instance of one. Tuple elements are of
973 type Field.
974 """
975
976 # Might it be worth caching this, per class?
977 try:
Miss Islington (bot)c73268a2018-05-15 21:22:13 -0700978 fields = getattr(class_or_instance, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500979 except AttributeError:
980 raise TypeError('must be called with a dataclass type or instance')
981
Eric V. Smithd1388922018-01-07 14:30:17 -0500982 # Exclude pseudo-fields. Note that fields is sorted by insertion
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -0700983 # order, so the order of the tuple is as the fields were defined.
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500984 return tuple(f for f in fields.values() if f._field_type is _FIELD)
985
986
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500987def _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500988 """Returns True if obj is an instance of a dataclass."""
Miss Islington (bot)45648312018-03-18 18:03:36 -0700989 return not isinstance(obj, type) and hasattr(obj, _FIELDS)
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500990
991
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500992def is_dataclass(obj):
993 """Returns True if obj is a dataclass or an instance of a
994 dataclass."""
Miss Islington (bot)45648312018-03-18 18:03:36 -0700995 return hasattr(obj, _FIELDS)
Eric V. Smithe7ba0132018-01-06 12:41:53 -0500996
997
Eric V. Smithf0db54a2017-12-04 16:58:55 -0500998def asdict(obj, *, dict_factory=dict):
999 """Return the fields of a dataclass instance as a new dictionary mapping
1000 field names to field values.
1001
1002 Example usage:
1003
1004 @dataclass
1005 class C:
1006 x: int
1007 y: int
1008
1009 c = C(1, 2)
1010 assert asdict(c) == {'x': 1, 'y': 2}
1011
1012 If given, 'dict_factory' will be used instead of built-in dict.
1013 The function applies recursively to field values that are
1014 dataclass instances. This will also look into built-in containers:
1015 tuples, lists, and dicts.
1016 """
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001017 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001018 raise TypeError("asdict() should be called on dataclass instances")
1019 return _asdict_inner(obj, dict_factory)
1020
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -08001021
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001022def _asdict_inner(obj, dict_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001023 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001024 result = []
1025 for f in fields(obj):
1026 value = _asdict_inner(getattr(obj, f.name), dict_factory)
1027 result.append((f.name, value))
1028 return dict_factory(result)
1029 elif isinstance(obj, (list, tuple)):
1030 return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
1031 elif isinstance(obj, dict):
1032 return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
1033 for k, v in obj.items())
1034 else:
Miss Islington (bot)02c19a62018-03-24 14:42:28 -07001035 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001036
1037
1038def astuple(obj, *, tuple_factory=tuple):
1039 """Return the fields of a dataclass instance as a new tuple of field values.
1040
1041 Example usage::
1042
1043 @dataclass
1044 class C:
1045 x: int
1046 y: int
1047
1048 c = C(1, 2)
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001049 assert astuple(c) == (1, 2)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001050
1051 If given, 'tuple_factory' will be used instead of built-in tuple.
1052 The function applies recursively to field values that are
1053 dataclass instances. This will also look into built-in containers:
1054 tuples, lists, and dicts.
1055 """
1056
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001057 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001058 raise TypeError("astuple() should be called on dataclass instances")
1059 return _astuple_inner(obj, tuple_factory)
1060
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -08001061
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001062def _astuple_inner(obj, tuple_factory):
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001063 if _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001064 result = []
1065 for f in fields(obj):
1066 value = _astuple_inner(getattr(obj, f.name), tuple_factory)
1067 result.append(value)
1068 return tuple_factory(result)
1069 elif isinstance(obj, (list, tuple)):
1070 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj)
1071 elif isinstance(obj, dict):
1072 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory))
1073 for k, v in obj.items())
1074 else:
Miss Islington (bot)02c19a62018-03-24 14:42:28 -07001075 return copy.deepcopy(obj)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001076
1077
Eric V. Smithd80b4432018-01-06 17:09:58 -05001078def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
Miss Islington (bot)398242a2018-03-01 05:30:13 -08001079 repr=True, eq=True, order=False, unsafe_hash=False,
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -08001080 frozen=False):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001081 """Return a new dynamically created dataclass.
1082
Eric V. Smithed7d4292018-01-06 16:14:03 -05001083 The dataclass name will be 'cls_name'. 'fields' is an iterable
1084 of either (name), (name, type) or (name, type, Field) objects. If type is
1085 omitted, use the string 'typing.Any'. Field objects are created by
Eric V. Smithd327ae62018-01-07 08:19:45 -05001086 the equivalent of calling 'field(name, type [, Field-info])'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001087
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001088 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,))
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001089
1090 is equivalent to:
1091
1092 @dataclass
1093 class C(Base):
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001094 x: 'typing.Any'
1095 y: int
1096 z: int = field(init=False)
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001097
Raymond Hettingerd55209d2018-01-10 20:56:41 -08001098 For the bases and namespace parameters, see the builtin type() function.
Eric V. Smithd80b4432018-01-06 17:09:58 -05001099
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -08001100 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to
Eric V. Smithd80b4432018-01-06 17:09:58 -05001101 dataclass().
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001102 """
1103
1104 if namespace is None:
1105 namespace = {}
1106 else:
1107 # Copy namespace since we're going to mutate it.
1108 namespace = namespace.copy()
1109
Miss Islington (bot)6409e752018-05-16 09:28:22 -07001110 # While we're looking through the field names, validate that they
1111 # are identifiers, are not keywords, and not duplicates.
1112 seen = set()
Eric V. Smithd1388922018-01-07 14:30:17 -05001113 anns = {}
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001114 for item in fields:
Eric V. Smithed7d4292018-01-06 16:14:03 -05001115 if isinstance(item, str):
1116 name = item
1117 tp = 'typing.Any'
1118 elif len(item) == 2:
1119 name, tp, = item
1120 elif len(item) == 3:
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001121 name, tp, spec = item
1122 namespace[name] = spec
Miss Islington (bot)6409e752018-05-16 09:28:22 -07001123 else:
1124 raise TypeError(f'Invalid field: {item!r}')
1125
1126 if not isinstance(name, str) or not name.isidentifier():
1127 raise TypeError(f'Field names must be valid identifers: {name!r}')
1128 if keyword.iskeyword(name):
1129 raise TypeError(f'Field names must not be keywords: {name!r}')
1130 if name in seen:
1131 raise TypeError(f'Field name duplicated: {name!r}')
1132
1133 seen.add(name)
Eric V. Smithed7d4292018-01-06 16:14:03 -05001134 anns[name] = tp
1135
1136 namespace['__annotations__'] = anns
Miss Islington (bot)d063ad82018-04-01 04:33:13 -07001137 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1138 # of generic dataclassses.
1139 cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace))
Eric V. Smithd80b4432018-01-06 17:09:58 -05001140 return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
Miss Islington (bot)4cffe2f2018-02-26 01:43:35 -08001141 unsafe_hash=unsafe_hash, frozen=frozen)
1142
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001143
1144def replace(obj, **changes):
1145 """Return a new object replacing specified fields with new values.
1146
1147 This is especially useful for frozen classes. Example usage:
1148
1149 @dataclass(frozen=True)
1150 class C:
1151 x: int
1152 y: int
1153
1154 c = C(1, 2)
1155 c1 = replace(c, x=3)
1156 assert c1.x == 3 and c1.y == 2
1157 """
1158
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -07001159 # We're going to mutate 'changes', but that's okay because it's a
1160 # new dict, even if called with 'replace(obj, **my_changes)'.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001161
Eric V. Smithe7ba0132018-01-06 12:41:53 -05001162 if not _is_dataclass_instance(obj):
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001163 raise TypeError("replace() should be called on dataclass instances")
1164
1165 # It's an error to have init=False fields in 'changes'.
1166 # If a field is not in 'changes', read its value from the provided obj.
1167
Miss Islington (bot)45648312018-03-18 18:03:36 -07001168 for f in getattr(obj, _FIELDS).values():
Miss Islington (bot)0aee3be2018-06-07 13:15:23 -07001169 # Only consider normal fields or InitVars.
1170 if f._field_type is _FIELD_CLASSVAR:
1171 continue
1172
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001173 if not f.init:
1174 # Error if this field is specified in changes.
1175 if f.name in changes:
1176 raise ValueError(f'field {f.name} is declared with '
1177 'init=False, it cannot be specified with '
1178 'replace()')
1179 continue
1180
1181 if f.name not in changes:
Miss Islington (bot)bbef7ab2018-06-23 08:04:01 -07001182 if f._field_type is _FIELD_INITVAR:
1183 raise ValueError(f"InitVar {f.name!r} "
1184 'must be specified with replace()')
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001185 changes[f.name] = getattr(obj, f.name)
1186
Miss Islington (bot)02c19a62018-03-24 14:42:28 -07001187 # Create the new object, which calls __init__() and
Miss Islington (bot)8d486fb2018-05-16 02:49:29 -07001188 # __post_init__() (if defined), using all of the init fields we've
1189 # added and/or left in 'changes'. If there are values supplied in
1190 # changes that aren't fields, this will correctly raise a
1191 # TypeError.
Eric V. Smithf0db54a2017-12-04 16:58:55 -05001192 return obj.__class__(**changes)