Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/attr/_next_gen.py: 77%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: MIT
3"""
4These are keyword-only APIs that call `attr.s` and `attr.ib` with different
5default values.
6"""
8from functools import partial
10from . import setters
11from ._funcs import asdict as _asdict
12from ._funcs import astuple as _astuple
13from ._make import (
14 _DEFAULT_ON_SETATTR,
15 NOTHING,
16 _frozen_setattrs,
17 attrib,
18 attrs,
19)
20from .exceptions import UnannotatedAttributeError
23def define(
24 maybe_cls=None,
25 *,
26 these=None,
27 repr=None,
28 unsafe_hash=None,
29 hash=None,
30 init=None,
31 slots=True,
32 frozen=False,
33 weakref_slot=True,
34 str=False,
35 auto_attribs=None,
36 kw_only=False,
37 cache_hash=False,
38 auto_exc=True,
39 eq=None,
40 order=False,
41 auto_detect=True,
42 getstate_setstate=None,
43 on_setattr=None,
44 field_transformer=None,
45 match_args=True,
46):
47 r"""
48 A class decorator that adds :term:`dunder methods` according to
49 :term:`fields <field>` specified using :doc:`type annotations <types>`,
50 `field()` calls, or the *these* argument.
52 Since *attrs* patches or replaces an existing class, you cannot use
53 `object.__init_subclass__` with *attrs* classes, because it runs too early.
54 As a replacement, you can define ``__attrs_init_subclass__`` on your class.
55 It will be called by *attrs* classes that subclass it after they're
56 created. See also :ref:`init-subclass`.
58 Args:
59 slots (bool):
60 Create a :term:`slotted class <slotted classes>` that's more
61 memory-efficient. Slotted classes are generally superior to the
62 default dict classes, but have some gotchas you should know about,
63 so we encourage you to read the :term:`glossary entry <slotted
64 classes>`.
66 auto_detect (bool):
67 Instead of setting the *init*, *repr*, *eq*, and *hash* arguments
68 explicitly, assume they are set to True **unless any** of the
69 involved methods for one of the arguments is implemented in the
70 *current* class (meaning, it is *not* inherited from some base
71 class).
73 So, for example by implementing ``__eq__`` on a class yourself,
74 *attrs* will deduce ``eq=False`` and will create *neither*
75 ``__eq__`` *nor* ``__ne__`` (but Python classes come with a
76 sensible ``__ne__`` by default, so it *should* be enough to only
77 implement ``__eq__`` in most cases).
79 Passing :data:`True` or :data:`False` to *init*, *repr*, *eq*, or *hash*
80 overrides whatever *auto_detect* would determine.
82 auto_exc (bool):
83 If the class subclasses `BaseException` (which implicitly includes
84 any subclass of any exception), the following happens to behave
85 like a well-behaved Python exception class:
87 - the values for *eq*, *order*, and *hash* are ignored and the
88 instances compare and hash by the instance's ids [#]_ ,
89 - all attributes that are either passed into ``__init__`` or have a
90 default value are additionally available as a tuple in the
91 ``args`` attribute,
92 - the value of *str* is ignored leaving ``__str__`` to base
93 classes.
95 .. [#]
96 Note that *attrs* will *not* remove existing implementations of
97 ``__hash__`` or the equality methods. It just won't add own
98 ones.
100 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
101 A callable that is run whenever the user attempts to set an
102 attribute (either by assignment like ``i.x = 42`` or by using
103 `setattr` like ``setattr(i, "x", 42)``). It receives the same
104 arguments as validators: the instance, the attribute that is being
105 modified, and the new value.
107 If no exception is raised, the attribute is set to the return value
108 of the callable.
110 If a list of callables is passed, they're automatically wrapped in
111 an `attrs.setters.pipe`.
113 If left None, the default behavior is to run converters and
114 validators whenever an attribute is set.
116 init (bool):
117 Create a ``__init__`` method that initializes the *attrs*
118 attributes. Leading underscores are stripped for the argument name,
119 unless an alias is set on the attribute.
121 .. seealso::
122 `init` shows advanced ways to customize the generated
123 ``__init__`` method, including executing code before and after.
125 repr(bool):
126 Create a ``__repr__`` method with a human readable representation
127 of *attrs* attributes.
129 str (bool):
130 Create a ``__str__`` method that is identical to ``__repr__``. This
131 is usually not necessary except for `Exception`\ s.
133 eq (bool | None):
134 If True or None (default), add ``__eq__`` and ``__ne__`` methods
135 that check two instances for equality.
137 .. seealso::
138 `comparison` describes how to customize the comparison behavior
139 going as far comparing NumPy arrays.
141 order (bool | None):
142 If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``
143 methods that behave like *eq* above and allow instances to be
144 ordered.
146 They compare the instances as if they were tuples of their *attrs*
147 attributes if and only if the types of both classes are
148 *identical*.
150 If `None` mirror value of *eq*.
152 .. seealso:: `comparison`
154 unsafe_hash (bool | None):
155 If None (default), the ``__hash__`` method is generated according
156 how *eq* and *frozen* are set.
158 1. If *both* are True, *attrs* will generate a ``__hash__`` for
159 you.
160 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set
161 to None, marking it unhashable (which it is).
162 3. If *eq* is False, ``__hash__`` will be left untouched meaning
163 the ``__hash__`` method of the base class will be used. If the
164 base class is `object`, this means it will fall back to id-based
165 hashing.
167 Although not recommended, you can decide for yourself and force
168 *attrs* to create one (for example, if the class is immutable even
169 though you didn't freeze it programmatically) by passing True or
170 not. Both of these cases are rather special and should be used
171 carefully.
173 .. seealso::
175 - Our documentation on `hashing`,
176 - Python's documentation on `object.__hash__`,
177 - and the `GitHub issue that led to the default \ behavior
178 <https://github.com/python-attrs/attrs/issues/136>`_ for more
179 details.
181 hash (bool | None):
182 Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence.
184 cache_hash (bool):
185 Ensure that the object's hash code is computed only once and stored
186 on the object. If this is set to True, hashing must be either
187 explicitly or implicitly enabled for this class. If the hash code
188 is cached, avoid any reassignments of fields involved in hash code
189 computation or mutations of the objects those fields point to after
190 object creation. If such changes occur, the behavior of the
191 object's hash code is undefined.
193 frozen (bool):
194 Make instances immutable after initialization. If someone attempts
195 to modify a frozen instance, `attrs.exceptions.FrozenInstanceError`
196 is raised.
198 .. note::
200 1. This is achieved by installing a custom ``__setattr__``
201 method on your class, so you can't implement your own.
203 2. True immutability is impossible in Python.
205 3. This *does* have a minor a runtime performance `impact
206 <how-frozen>` when initializing new instances. In other
207 words: ``__init__`` is slightly slower with ``frozen=True``.
209 4. If a class is frozen, you cannot modify ``self`` in
210 ``__attrs_post_init__`` or a self-written ``__init__``. You
211 can circumvent that limitation by using
212 ``object.__setattr__(self, "attribute_name", value)``.
214 5. Subclasses of a frozen class are frozen too.
216 kw_only (bool):
217 Make all attributes keyword-only in the generated ``__init__`` (if
218 *init* is False, this parameter is ignored).
220 weakref_slot (bool):
221 Make instances weak-referenceable. This has no effect unless
222 *slots* is True.
224 field_transformer (~typing.Callable | None):
225 A function that is called with the original class object and all
226 fields right before *attrs* finalizes the class. You can use this,
227 for example, to automatically add converters or validators to
228 fields based on their types.
230 .. seealso:: `transform-fields`
232 match_args (bool):
233 If True (default), set ``__match_args__`` on the class to support
234 :pep:`634` (*Structural Pattern Matching*). It is a tuple of all
235 non-keyword-only ``__init__`` parameter names on Python 3.10 and
236 later. Ignored on older Python versions.
238 collect_by_mro (bool):
239 If True, *attrs* collects attributes from base classes correctly
240 according to the `method resolution order
241 <https://docs.python.org/3/howto/mro.html>`_. If False, *attrs*
242 will mimic the (wrong) behavior of `dataclasses` and :pep:`681`.
244 See also `issue #428
245 <https://github.com/python-attrs/attrs/issues/428>`_.
247 getstate_setstate (bool | None):
248 .. note::
250 This is usually only interesting for slotted classes and you
251 should probably just set *auto_detect* to True.
253 If True, ``__getstate__`` and ``__setstate__`` are generated and
254 attached to the class. This is necessary for slotted classes to be
255 pickleable. If left None, it's True by default for slotted classes
256 and False for dict classes.
258 If *auto_detect* is True, and *getstate_setstate* is left None, and
259 **either** ``__getstate__`` or ``__setstate__`` is detected
260 directly on the class (meaning: not inherited), it is set to False
261 (this is usually what you want).
263 auto_attribs (bool | None):
264 If True, look at type annotations to determine which attributes to
265 use, like `dataclasses`. If False, it will only look for explicit
266 :func:`field` class attributes, like classic *attrs*.
268 If left None, it will guess:
270 1. If any attributes are annotated and no unannotated
271 `attrs.field`\ s are found, it assumes *auto_attribs=True*.
272 2. Otherwise it assumes *auto_attribs=False* and tries to collect
273 `attrs.field`\ s.
275 If *attrs* decides to look at type annotations, **all** fields
276 **must** be annotated. If *attrs* encounters a field that is set to
277 a :func:`field` / `attr.ib` but lacks a type annotation, an
278 `attrs.exceptions.UnannotatedAttributeError` is raised. Use
279 ``field_name: typing.Any = field(...)`` if you don't want to set a
280 type.
282 .. warning::
284 For features that use the attribute name to create decorators
285 (for example, :ref:`validators <validators>`), you still *must*
286 assign :func:`field` / `attr.ib` to them. Otherwise Python will
287 either not find the name or try to use the default value to
288 call, for example, ``validator`` on it.
290 Attributes annotated as `typing.ClassVar`, and attributes that are
291 neither annotated nor set to an `field()` are **ignored**.
293 these (dict[str, object]):
294 A dictionary of name to the (private) return value of `field()`
295 mappings. This is useful to avoid the definition of your attributes
296 within the class body because you can't (for example, if you want
297 to add ``__repr__`` methods to Django models) or don't want to.
299 If *these* is not `None`, *attrs* will *not* search the class body
300 for attributes and will *not* remove any attributes from it.
302 The order is deduced from the order of the attributes inside
303 *these*.
305 Arguably, this is a rather obscure feature.
307 .. versionadded:: 20.1.0
308 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
309 .. versionadded:: 22.2.0
310 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
311 .. versionchanged:: 24.1.0
312 Instances are not compared as tuples of attributes anymore, but using a
313 big ``and`` condition. This is faster and has more correct behavior for
314 uncomparable values like `math.nan`.
315 .. versionadded:: 24.1.0
316 If a class has an *inherited* classmethod called
317 ``__attrs_init_subclass__``, it is executed after the class is created.
318 .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
319 .. versionadded:: 24.3.0
320 Unless already present, a ``__replace__`` method is automatically
321 created for `copy.replace` (Python 3.13+ only).
323 .. note::
325 The main differences to the classic `attr.s` are:
327 - Automatically detect whether or not *auto_attribs* should be `True`
328 (c.f. *auto_attribs* parameter).
329 - Converters and validators run when attributes are set by default --
330 if *frozen* is `False`.
331 - *slots=True*
333 Usually, this has only upsides and few visible effects in everyday
334 programming. But it *can* lead to some surprising behaviors, so
335 please make sure to read :term:`slotted classes`.
337 - *auto_exc=True*
338 - *auto_detect=True*
339 - *order=False*
340 - Some options that were only relevant on Python 2 or were kept around
341 for backwards-compatibility have been removed.
343 """
345 def do_it(cls, auto_attribs):
346 return attrs(
347 maybe_cls=cls,
348 these=these,
349 repr=repr,
350 hash=hash,
351 unsafe_hash=unsafe_hash,
352 init=init,
353 slots=slots,
354 frozen=frozen,
355 weakref_slot=weakref_slot,
356 str=str,
357 auto_attribs=auto_attribs,
358 kw_only=kw_only,
359 cache_hash=cache_hash,
360 auto_exc=auto_exc,
361 eq=eq,
362 order=order,
363 auto_detect=auto_detect,
364 collect_by_mro=True,
365 getstate_setstate=getstate_setstate,
366 on_setattr=on_setattr,
367 field_transformer=field_transformer,
368 match_args=match_args,
369 )
371 def wrap(cls):
372 """
373 Making this a wrapper ensures this code runs during class creation.
375 We also ensure that frozen-ness of classes is inherited.
376 """
377 nonlocal frozen, on_setattr
379 had_on_setattr = on_setattr not in (None, setters.NO_OP)
381 # By default, mutable classes convert & validate on setattr.
382 if frozen is False and on_setattr is None:
383 on_setattr = _DEFAULT_ON_SETATTR
385 # However, if we subclass a frozen class, we inherit the immutability
386 # and disable on_setattr.
387 for base_cls in cls.__bases__:
388 if base_cls.__setattr__ is _frozen_setattrs:
389 if had_on_setattr:
390 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)."
391 raise ValueError(msg)
393 on_setattr = setters.NO_OP
394 break
396 if auto_attribs is not None:
397 return do_it(cls, auto_attribs)
399 try:
400 return do_it(cls, True)
401 except UnannotatedAttributeError:
402 return do_it(cls, False)
404 # maybe_cls's type depends on the usage of the decorator. It's a class
405 # if it's used as `@attrs` but `None` if used as `@attrs()`.
406 if maybe_cls is None:
407 return wrap
409 return wrap(maybe_cls)
412mutable = define
413frozen = partial(define, frozen=True, on_setattr=None)
416def field(
417 *,
418 default=NOTHING,
419 validator=None,
420 repr=True,
421 hash=None,
422 init=True,
423 metadata=None,
424 type=None,
425 converter=None,
426 factory=None,
427 kw_only=False,
428 eq=None,
429 order=None,
430 on_setattr=None,
431 alias=None,
432):
433 """
434 Create a new :term:`field` / :term:`attribute` on a class.
436 .. warning::
438 Does **nothing** unless the class is also decorated with
439 `attrs.define` (or similar)!
441 Args:
442 default:
443 A value that is used if an *attrs*-generated ``__init__`` is used
444 and no value is passed while instantiating or the attribute is
445 excluded using ``init=False``.
447 If the value is an instance of `attrs.Factory`, its callable will
448 be used to construct a new value (useful for mutable data types
449 like lists or dicts).
451 If a default is not set (or set manually to `attrs.NOTHING`), a
452 value *must* be supplied when instantiating; otherwise a
453 `TypeError` will be raised.
455 .. seealso:: `defaults`
457 factory (~typing.Callable):
458 Syntactic sugar for ``default=attr.Factory(factory)``.
460 validator (~typing.Callable | list[~typing.Callable]):
461 Callable that is called by *attrs*-generated ``__init__`` methods
462 after the instance has been initialized. They receive the
463 initialized instance, the :func:`~attrs.Attribute`, and the passed
464 value.
466 The return value is *not* inspected so the validator has to throw
467 an exception itself.
469 If a `list` is passed, its items are treated as validators and must
470 all pass.
472 Validators can be globally disabled and re-enabled using
473 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`.
475 The validator can also be set using decorator notation as shown
476 below.
478 .. seealso:: :ref:`validators`
480 repr (bool | ~typing.Callable):
481 Include this attribute in the generated ``__repr__`` method. If
482 True, include the attribute; if False, omit it. By default, the
483 built-in ``repr()`` function is used. To override how the attribute
484 value is formatted, pass a ``callable`` that takes a single value
485 and returns a string. Note that the resulting string is used as-is,
486 which means it will be used directly *instead* of calling
487 ``repr()`` (the default).
489 eq (bool | ~typing.Callable):
490 If True (default), include this attribute in the generated
491 ``__eq__`` and ``__ne__`` methods that check two instances for
492 equality. To override how the attribute value is compared, pass a
493 callable that takes a single value and returns the value to be
494 compared.
496 .. seealso:: `comparison`
498 order (bool | ~typing.Callable):
499 If True (default), include this attributes in the generated
500 ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To
501 override how the attribute value is ordered, pass a callable that
502 takes a single value and returns the value to be ordered.
504 .. seealso:: `comparison`
506 hash (bool | None):
507 Include this attribute in the generated ``__hash__`` method. If
508 None (default), mirror *eq*'s value. This is the correct behavior
509 according the Python spec. Setting this value to anything else
510 than None is *discouraged*.
512 .. seealso:: `hashing`
514 init (bool):
515 Include this attribute in the generated ``__init__`` method.
517 It is possible to set this to False and set a default value. In
518 that case this attributed is unconditionally initialized with the
519 specified default value or factory.
521 .. seealso:: `init`
523 converter (typing.Callable | Converter):
524 A callable that is called by *attrs*-generated ``__init__`` methods
525 to convert attribute's value to the desired format.
527 If a vanilla callable is passed, it is given the passed-in value as
528 the only positional argument. It is possible to receive additional
529 arguments by wrapping the callable in a `Converter`.
531 Either way, the returned value will be used as the new value of the
532 attribute. The value is converted before being passed to the
533 validator, if any.
535 .. seealso:: :ref:`converters`
537 metadata (dict | None):
538 An arbitrary mapping, to be used by third-party code.
540 .. seealso:: `extending-metadata`.
542 type (type):
543 The type of the attribute. Nowadays, the preferred method to
544 specify the type is using a variable annotation (see :pep:`526`).
545 This argument is provided for backwards-compatibility and for usage
546 with `make_class`. Regardless of the approach used, the type will
547 be stored on ``Attribute.type``.
549 Please note that *attrs* doesn't do anything with this metadata by
550 itself. You can use it as part of your own code or for `static type
551 checking <types>`.
553 kw_only (bool):
554 Make this attribute keyword-only in the generated ``__init__`` (if
555 ``init`` is False, this parameter is ignored).
557 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
558 Allows to overwrite the *on_setattr* setting from `attr.s`. If left
559 None, the *on_setattr* value from `attr.s` is used. Set to
560 `attrs.setters.NO_OP` to run **no** `setattr` hooks for this
561 attribute -- regardless of the setting in `define()`.
563 alias (str | None):
564 Override this attribute's parameter name in the generated
565 ``__init__`` method. If left None, default to ``name`` stripped
566 of leading underscores. See `private-attributes`.
568 .. versionadded:: 20.1.0
569 .. versionchanged:: 21.1.0
570 *eq*, *order*, and *cmp* also accept a custom callable
571 .. versionadded:: 22.2.0 *alias*
572 .. versionadded:: 23.1.0
573 The *type* parameter has been re-added; mostly for `attrs.make_class`.
574 Please note that type checkers ignore this metadata.
576 .. seealso::
578 `attr.ib`
579 """
580 return attrib(
581 default=default,
582 validator=validator,
583 repr=repr,
584 hash=hash,
585 init=init,
586 metadata=metadata,
587 type=type,
588 converter=converter,
589 factory=factory,
590 kw_only=kw_only,
591 eq=eq,
592 order=order,
593 on_setattr=on_setattr,
594 alias=alias,
595 )
598def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
599 """
600 Same as `attr.asdict`, except that collections types are always retained
601 and dict is always used as *dict_factory*.
603 .. versionadded:: 21.3.0
604 """
605 return _asdict(
606 inst=inst,
607 recurse=recurse,
608 filter=filter,
609 value_serializer=value_serializer,
610 retain_collection_types=True,
611 )
614def astuple(inst, *, recurse=True, filter=None):
615 """
616 Same as `attr.astuple`, except that collections types are always retained
617 and `tuple` is always used as the *tuple_factory*.
619 .. versionadded:: 21.3.0
620 """
621 return _astuple(
622 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
623 )