@@ -6,7 +6,7 @@ Type: Standards Track
6
6
Content-Type: text/x-rst
7
7
Created: 02-Jun-2017
8
8
Python-Version: 3.7
9
- Post-History: 08-Sep-2017, 25-Nov-2017
9
+ Post-History: 08-Sep-2017, 25-Nov-2017, 30-Nov-2017
10
10
11
11
Notice for Reviewers
12
12
====================
@@ -57,7 +57,7 @@ to the InventoryItem class::
57
57
self.unit_price = unit_price
58
58
self.quantity_on_hand = quantity_on_hand
59
59
def __repr__(self):
60
- return f'InventoryItem(name={self.name!r},unit_price={self.unit_price!r},quantity_on_hand={self.quantity_on_hand!r})'
60
+ return f'InventoryItem(name={self.name!r}, unit_price={self.unit_price!r}, quantity_on_hand={self.quantity_on_hand!r})'
61
61
def __eq__(self, other):
62
62
if other.__class__ is self.__class__:
63
63
return (self.name, self.unit_price, self.quantity_on_hand) == (other.name, other.unit_price, other.quantity_on_hand)
@@ -83,7 +83,7 @@ to the InventoryItem class::
83
83
return (self.name, self.unit_price, self.quantity_on_hand) >= (other.name, other.unit_price, other.quantity_on_hand)
84
84
return NotImplemented
85
85
86
- Data Classes saves you from writing and maintaining these functions .
86
+ Data Classes saves you from writing and maintaining these methods .
87
87
88
88
Rationale
89
89
=========
@@ -157,11 +157,16 @@ Note that ``__annotations__`` is guaranteed to be an ordered mapping,
157
157
in class declaration order. The order of the fields in all of the
158
158
generated methods is the order in which they appear in the class.
159
159
160
+ The ``dataclass `` decorator will add various "dunder" methods to the
161
+ class, described below. If any of the added methods already exist on the
162
+ class, a ``TypeError `` will be raised. The decorator returns the same
163
+ class that is called on: no new class is created.
164
+
160
165
The ``dataclass `` decorator is typically used with no parameters and
161
166
no parentheses. However, it also supports the following logical
162
167
signature::
163
168
164
- def dataclass(*, init=True, repr=True, eq=True, compare =True, hash=None, frozen=False)
169
+ def dataclass(*, init=True, repr=True, eq=True, order =True, hash=None, frozen=False)
165
170
166
171
If ``dataclass `` is used just as a simple decorator with no
167
172
parameters, it acts as if it has the default values documented in this
@@ -175,7 +180,7 @@ signature. That is, these three uses of ``@dataclass`` are equivalent::
175
180
class C:
176
181
...
177
182
178
- @dataclass(init=True, repr=True, eq=True, compare =True, hash=None, frozen=False)
183
+ @dataclass(init=True, repr=True, eq=True, order =True, hash=None, frozen=False)
179
184
class C:
180
185
...
181
186
@@ -184,24 +189,23 @@ The parameters to ``dataclass`` are:
184
189
- ``init ``: If true (the default), a ``__init__ `` method will be
185
190
generated.
186
191
187
- - ``repr ``: If true (the default), a ``__repr__ `` function will be
192
+ - ``repr ``: If true (the default), a ``__repr__ `` method will be
188
193
generated. The generated repr string will have the class name and
189
194
the name and repr of each field, in the order they are defined in
190
195
the class. Fields that are marked as being excluded from the repr
191
196
are not included. For example:
192
- ``InventoryItem(name='widget',unit_price=3.0,quantity_on_hand=10) ``.
197
+ ``InventoryItem(name='widget', unit_price=3.0, quantity_on_hand=10) ``.
193
198
194
199
- ``eq ``: If true (the default), ``__eq__ `` and ``__ne__ `` methods
195
200
will be generated. These compare the class as if it were a tuple of
196
201
its fields, in order. Both instances in the comparison must be of
197
202
the identical type.
198
203
199
- - ``compare ``: If true (the default), ``__lt__ ``, ``__le__ ``,
204
+ - ``order ``: If true (the default), ``__lt__ ``, ``__le__ ``,
200
205
``__gt__ ``, and ``__ge__ `` methods will be generated. These compare
201
206
the class as if it were a tuple of its fields, in order. Both
202
207
instances in the comparison must be of the identical type. If
203
- ``compare `` is True, then ``eq `` is ignored, and ``__eq__ `` and
204
- ``__ne__ `` will be automatically generated.
208
+ ``order `` is true and ``eq `` is false, a ``ValueError `` is raised.
205
209
206
210
- ``hash ``: Either a bool or ``None ``. If ``None `` (the default), the
207
211
``__hash__ `` method is generated according to how ``eq `` and
@@ -235,10 +239,14 @@ Python syntax::
235
239
b: int = 0 # assign a default value for 'b'
236
240
237
241
In this example, both ``a `` and ``b `` will be included in the added
238
- ``__init__ `` function , which will be defined as::
242
+ ``__init__ `` method , which will be defined as::
239
243
240
244
def __init__(self, a: int, b: int = 0):
241
245
246
+ ``TypeError `` will be raised if a field without a default value
247
+ follows a field with a default value. This is true either when this
248
+ occurs in a single class, or as a result of class inheritance.
249
+
242
250
For common and simple use cases, no other functionality is required.
243
251
There are, however, some Data Class features that require additional
244
252
per-field information. To satisfy this need for additional
@@ -266,10 +274,10 @@ The parameters to ``field()`` are:
266
274
specify both ``default `` and ``default_factory ``.
267
275
268
276
- ``init ``: If true (the default), this field is included as a
269
- parameter to the generated ``__init__ `` function .
277
+ parameter to the generated ``__init__ `` method .
270
278
271
279
- ``repr ``: If true (the default), this field is included in the
272
- string returned by the generated ``__repr__ `` function .
280
+ string returned by the generated ``__repr__ `` method .
273
281
274
282
- ``compare ``: If True (the default), this field is included in the
275
283
generated equality and comparison methods (``__eq__ ``, ``__gt__ ``,
@@ -278,10 +286,16 @@ The parameters to ``field()`` are:
278
286
- ``hash ``: This can be a bool or ``None ``. If True, this field is
279
287
included in the generated ``__hash__ `` method. If ``None `` (the
280
288
default), use the value of ``compare ``: this would normally be the
281
- expected behavior. A field needs to be considered in the hash if
289
+ expected behavior. A field should be considered in the hash if
282
290
it's used for comparisons. Setting this value to anything other
283
291
than ``None `` is discouraged.
284
292
293
+ One possible reason to set ``hash=False `` but ``compare=True `` would
294
+ be if a field is expensive to compute a hash value for, that field
295
+ is needed for equality testing, and there are other fields that
296
+ contribute to the type's hash value. Even if a field is excluded
297
+ from the hash, it will still be used for comparisons.
298
+
285
299
- ``metadata ``: This can be a mapping or None. None is treated as an
286
300
empty dict. This value is wrapped in ``types.MappingProxyType `` to
287
301
make it read-only, and exposed on the Field object. It is not used
@@ -291,12 +305,11 @@ The parameters to ``field()`` are:
291
305
292
306
If the default value of a field is specified by a call to ``field() ``,
293
307
then the class attribute for this field will be replaced by the
294
- specified ``default `` value, if one is provided in the call to
295
- ``field() ``. If no ``default `` is provided, then the class attribute
296
- will be deleted. The intent is that after the ``dataclass `` decorator
297
- runs, the class attributes will all contain the default values for the
298
- fields, just as if the default value itself were specified. For
299
- example, after::
308
+ specified ``default `` value. If no ``default `` is provided, then the
309
+ class attribute will be deleted. The intent is that after the
310
+ ``dataclass `` decorator runs, the class attributes will all contain
311
+ the default values for the fields, just as if the default value itself
312
+ were specified. For example, after::
300
313
301
314
@dataclass
302
315
class C:
@@ -322,17 +335,19 @@ object directly. Its documented attributes are:
322
335
- ``type ``: The type of the field.
323
336
324
337
- ``default ``, ``default_factory ``, ``init ``, ``repr ``, ``hash ``,
325
- ``compare``, and ``metadata `` have the identical meaning as they do
326
- in the ``field() `` declaration.
338
+ ``compare ``, and ``metadata `` have the identical meaning and values
339
+ as they do in the ``field() `` declaration.
327
340
328
- Other attributes may exist, but they are private.
341
+ Other attributes may exist, but they are private and must not be
342
+ inspected or relied on.
329
343
330
344
post-init processing
331
345
--------------------
332
346
333
347
The generated ``__init__ `` code will call a method named
334
- ``__post_init__ ``, if it is defined on the class. It will
335
- be called as ``self.__post_init__() ``.
348
+ ``__post_init__ ``, if it is defined on the class. It will be called
349
+ as ``self.__post_init__() ``. If not ``__init__ `` method is generated,
350
+ then ``__post_init__ `` will not automatically be called.
336
351
337
352
Among other uses, this allows for initializing field values that
338
353
depend on one or more other fields. For example::
@@ -355,12 +370,11 @@ Class variables
355
370
356
371
One place where ``dataclass `` actually inspects the type of a field is
357
372
to determine if a field is a class variable as defined in PEP 526. It
358
- does this by checking if the type of the field is of type
359
- ``typing.ClassVar ``. If a field is a ``ClassVar ``, it is excluded
360
- from consideration as a field and is ignored by the Data Class
361
- mechanisms. For more discussion, see [# ]_. Such ``ClassVar ``
362
- pseudo-fields are not returned by the module-level ``fields() ``
363
- function.
373
+ does this by checking if the type of the field is ``typing.ClassVar ``.
374
+ If a field is a ``ClassVar ``, it is excluded from consideration as a
375
+ field and is ignored by the Data Class mechanisms. For more
376
+ discussion, see [# ]_. Such ``ClassVar `` pseudo-fields are not
377
+ returned by the module-level ``fields() `` function.
364
378
365
379
Init-only variables
366
380
-------------------
@@ -375,7 +389,7 @@ parameters to the generated ``__init__`` method, and are passed to
375
389
the optional ``__post_init__ `` method. They are not otherwise used
376
390
by Data Classes.
377
391
378
- For example, suppose a field will be initialized from a database, if a
392
+ For example, suppose a field will be initialzed from a database, if a
379
393
value is not provided when creating the class::
380
394
381
395
@dataclass
@@ -730,12 +744,16 @@ parameters. They are passed first to ``__init__`` which passes them
730
744
to ``__post_init__ `` where user code can use them as needed.
731
745
732
746
The only real difference between alternate classmethod constructors
733
- and ``InitVar `` pseudo-fields is in object creation. With
734
- ``InitVar``s, using ``__init__ `` and the module-level ``replace() ``
735
- function ``InitVar ``'s must always be specified. With alternate
736
- classmethod constructors the additional initialization parameters are
737
- always optional. Which approach is more appropriate will be
738
- application-specific, but both approaches are supported.
747
+ and ``InitVar `` pseudo-fields is in regards to required non-field
748
+ parameters during object creation. With ``InitVar``s, using
749
+ ``__init__ `` and the module-level ``replace() `` function ``InitVar ``'s
750
+ must always be specified. Consider the case where a ``context ``
751
+ object is needed to create an instance, but isn't stored as a field.
752
+ With alternate classmethod constructors the ``context `` parameter is
753
+ always optional, because you could still create the object by going
754
+ through ``__init__ `` (unless you suppress its creation). Which
755
+ approach is more appropriate will be application-specific, but both
756
+ approaches are supported.
739
757
740
758
Rejected ideas
741
759
==============
@@ -783,6 +801,24 @@ see [#]_.
783
801
Examples
784
802
========
785
803
804
+ Custom __init__ method
805
+ ----------------------
806
+
807
+ Sometimes the generated ``__init__ `` method does not suffice. For
808
+ example, suppose you wanted to have an object to store ``*args `` and
809
+ ``**kwargs ``::
810
+
811
+ @dataclass(init=False)
812
+ class ArgHolder:
813
+ args: List[Any]
814
+ kwargs: Mapping[Any, Any]
815
+
816
+ def __init__(self, *args, **kwargs):
817
+ self.args = args
818
+ self.kwargs = kwargs
819
+
820
+ a = ArgHolder(1, 2, three=3)
821
+
786
822
A complicated example
787
823
---------------------
788
824
0 commit comments