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 force_kw_only=False,
47):
48 r"""
49 A class decorator that adds :term:`dunder methods` according to
50 :term:`fields <field>` specified using :doc:`type annotations <types>`,
51 `field()` calls, or the *these* argument.
53 Since *attrs* patches or replaces an existing class, you cannot use
54 `object.__init_subclass__` with *attrs* classes, because it runs too early.
55 As a replacement, you can define ``__attrs_init_subclass__`` on your class.
56 It will be called by *attrs* classes that subclass it after they're
57 created. See also :ref:`init-subclass`.
59 Args:
60 slots (bool):
61 Create a :term:`slotted class <slotted classes>` that's more
62 memory-efficient. Slotted classes are generally superior to the
63 default dict classes, but have some gotchas you should know about,
64 so we encourage you to read the :term:`glossary entry <slotted
65 classes>`.
67 auto_detect (bool):
68 Instead of setting the *init*, *repr*, *eq*, and *hash* arguments
69 explicitly, assume they are set to True **unless any** of the
70 involved methods for one of the arguments is implemented in the
71 *current* class (meaning, it is *not* inherited from some base
72 class).
74 So, for example by implementing ``__eq__`` on a class yourself,
75 *attrs* will deduce ``eq=False`` and will create *neither*
76 ``__eq__`` *nor* ``__ne__`` (but Python classes come with a
77 sensible ``__ne__`` by default, so it *should* be enough to only
78 implement ``__eq__`` in most cases).
80 Passing :data:`True` or :data:`False` to *init*, *repr*, *eq*, or *hash*
81 overrides whatever *auto_detect* would determine.
83 auto_exc (bool):
84 If the class subclasses `BaseException` (which implicitly includes
85 any subclass of any exception), the following happens to behave
86 like a well-behaved Python exception class:
88 - the values for *eq*, *order*, and *hash* are ignored and the
89 instances compare and hash by the instance's ids [#]_ ,
90 - all attributes that are either passed into ``__init__`` or have a
91 default value are additionally available as a tuple in the
92 ``args`` attribute,
93 - the value of *str* is ignored leaving ``__str__`` to base
94 classes.
96 .. [#]
97 Note that *attrs* will *not* remove existing implementations of
98 ``__hash__`` or the equality methods. It just won't add own
99 ones.
101 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
102 A callable that is run whenever the user attempts to set an
103 attribute (either by assignment like ``i.x = 42`` or by using
104 `setattr` like ``setattr(i, "x", 42)``). It receives the same
105 arguments as validators: the instance, the attribute that is being
106 modified, and the new value.
108 If no exception is raised, the attribute is set to the return value
109 of the callable.
111 If a list of callables is passed, they're automatically wrapped in
112 an `attrs.setters.pipe`.
114 If left None, the default behavior is to run converters and
115 validators whenever an attribute is set.
117 init (bool):
118 Create a ``__init__`` method that initializes the *attrs*
119 attributes. Leading underscores are stripped for the argument name,
120 unless an alias is set on the attribute.
122 .. seealso::
123 `init` shows advanced ways to customize the generated
124 ``__init__`` method, including executing code before and after.
126 repr(bool):
127 Create a ``__repr__`` method with a human readable representation
128 of *attrs* attributes.
130 str (bool):
131 Create a ``__str__`` method that is identical to ``__repr__``. This
132 is usually not necessary except for `Exception`\ s.
134 eq (bool | None):
135 If True or None (default), add ``__eq__`` and ``__ne__`` methods
136 that check two instances for equality.
138 .. seealso::
139 `comparison` describes how to customize the comparison behavior
140 going as far comparing NumPy arrays.
142 order (bool | None):
143 If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``
144 methods that behave like *eq* above and allow instances to be
145 ordered.
147 They compare the instances as if they were tuples of their *attrs*
148 attributes if and only if the types of both classes are
149 *identical*.
151 If `None` mirror value of *eq*.
153 .. seealso:: `comparison`
155 unsafe_hash (bool | None):
156 If None (default), the ``__hash__`` method is generated according
157 how *eq* and *frozen* are set.
159 1. If *both* are True, *attrs* will generate a ``__hash__`` for
160 you.
161 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set
162 to None, marking it unhashable (which it is).
163 3. If *eq* is False, ``__hash__`` will be left untouched meaning
164 the ``__hash__`` method of the base class will be used. If the
165 base class is `object`, this means it will fall back to id-based
166 hashing.
168 Although not recommended, you can decide for yourself and force
169 *attrs* to create one (for example, if the class is immutable even
170 though you didn't freeze it programmatically) by passing True or
171 not. Both of these cases are rather special and should be used
172 carefully.
174 .. seealso::
176 - Our documentation on `hashing`,
177 - Python's documentation on `object.__hash__`,
178 - and the `GitHub issue that led to the default \ behavior
179 <https://github.com/python-attrs/attrs/issues/136>`_ for more
180 details.
182 hash (bool | None):
183 Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence.
185 cache_hash (bool):
186 Ensure that the object's hash code is computed only once and stored
187 on the object. If this is set to True, hashing must be either
188 explicitly or implicitly enabled for this class. If the hash code
189 is cached, avoid any reassignments of fields involved in hash code
190 computation or mutations of the objects those fields point to after
191 object creation. If such changes occur, the behavior of the
192 object's hash code is undefined.
194 frozen (bool):
195 Make instances immutable after initialization. If someone attempts
196 to modify a frozen instance, `attrs.exceptions.FrozenInstanceError`
197 is raised.
199 .. note::
201 1. This is achieved by installing a custom ``__setattr__``
202 method on your class, so you can't implement your own.
204 2. True immutability is impossible in Python.
206 3. This *does* have a minor a runtime performance `impact
207 <how-frozen>` when initializing new instances. In other
208 words: ``__init__`` is slightly slower with ``frozen=True``.
210 4. If a class is frozen, you cannot modify ``self`` in
211 ``__attrs_post_init__`` or a self-written ``__init__``. You
212 can circumvent that limitation by using
213 ``object.__setattr__(self, "attribute_name", value)``.
215 5. Subclasses of a frozen class are frozen too.
217 kw_only (bool):
218 Make attributes keyword-only in the generated ``__init__`` (if
219 *init* is False, this parameter is ignored). Attributes that
220 explicitly set ``kw_only=False`` are not affected; base class
221 attributes are also not affected.
223 Also see *force_kw_only*.
225 weakref_slot (bool):
226 Make instances weak-referenceable. This has no effect unless
227 *slots* is True.
229 field_transformer (~typing.Callable | None):
230 A function that is called with the original class object and all
231 fields right before *attrs* finalizes the class. You can use this,
232 for example, to automatically add converters or validators to
233 fields based on their types.
235 .. seealso:: `transform-fields`
237 match_args (bool):
238 If True (default), set ``__match_args__`` on the class to support
239 :pep:`634` (*Structural Pattern Matching*). It is a tuple of all
240 non-keyword-only ``__init__`` parameter names on Python 3.10 and
241 later. Ignored on older Python versions.
243 collect_by_mro (bool):
244 If True, *attrs* collects attributes from base classes correctly
245 according to the `method resolution order
246 <https://docs.python.org/3/howto/mro.html>`_. If False, *attrs*
247 will mimic the (wrong) behavior of `dataclasses` and :pep:`681`.
249 See also `issue #428
250 <https://github.com/python-attrs/attrs/issues/428>`_.
252 force_kw_only (bool):
253 A back-compat flag for restoring pre-25.4.0 behavior. If True and
254 ``kw_only=True``, all attributes are made keyword-only, including
255 base class attributes, and those set to ``kw_only=False`` at the
256 attribute level. Defaults to False.
258 See also `issue #980
259 <https://github.com/python-attrs/attrs/issues/980>`_.
261 getstate_setstate (bool | None):
262 .. note::
264 This is usually only interesting for slotted classes and you
265 should probably just set *auto_detect* to True.
267 If True, ``__getstate__`` and ``__setstate__`` are generated and
268 attached to the class. This is necessary for slotted classes to be
269 pickleable. If left None, it's True by default for slotted classes
270 and False for dict classes.
272 If *auto_detect* is True, and *getstate_setstate* is left None, and
273 **either** ``__getstate__`` or ``__setstate__`` is detected
274 directly on the class (meaning: not inherited), it is set to False
275 (this is usually what you want).
277 auto_attribs (bool | None):
278 If True, look at type annotations to determine which attributes to
279 use, like `dataclasses`. If False, it will only look for explicit
280 :func:`field` class attributes, like classic *attrs*.
282 If left None, it will guess:
284 1. If any attributes are annotated and no unannotated
285 `attrs.field`\ s are found, it assumes *auto_attribs=True*.
286 2. Otherwise it assumes *auto_attribs=False* and tries to collect
287 `attrs.field`\ s.
289 If *attrs* decides to look at type annotations, **all** fields
290 **must** be annotated. If *attrs* encounters a field that is set to
291 a :func:`field` / `attr.ib` but lacks a type annotation, an
292 `attrs.exceptions.UnannotatedAttributeError` is raised. Use
293 ``field_name: typing.Any = field(...)`` if you don't want to set a
294 type.
296 .. warning::
298 For features that use the attribute name to create decorators
299 (for example, :ref:`validators <validators>`), you still *must*
300 assign :func:`field` / `attr.ib` to them. Otherwise Python will
301 either not find the name or try to use the default value to
302 call, for example, ``validator`` on it.
304 Attributes annotated as `typing.ClassVar`, and attributes that are
305 neither annotated nor set to an `field()` are **ignored**.
307 these (dict[str, object]):
308 A dictionary of name to the (private) return value of `field()`
309 mappings. This is useful to avoid the definition of your attributes
310 within the class body because you can't (for example, if you want
311 to add ``__repr__`` methods to Django models) or don't want to.
313 If *these* is not `None`, *attrs* will *not* search the class body
314 for attributes and will *not* remove any attributes from it.
316 The order is deduced from the order of the attributes inside
317 *these*.
319 Arguably, this is a rather obscure feature.
321 .. versionadded:: 20.1.0
322 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
323 .. versionadded:: 22.2.0
324 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
325 .. versionchanged:: 24.1.0
326 Instances are not compared as tuples of attributes anymore, but using a
327 big ``and`` condition. This is faster and has more correct behavior for
328 uncomparable values like `math.nan`.
329 .. versionadded:: 24.1.0
330 If a class has an *inherited* classmethod called
331 ``__attrs_init_subclass__``, it is executed after the class is created.
332 .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
333 .. versionadded:: 24.3.0
334 Unless already present, a ``__replace__`` method is automatically
335 created for `copy.replace` (Python 3.13+ only).
336 .. versionchanged:: 25.4.0
337 *kw_only* now only applies to attributes defined in the current class,
338 and respects attribute-level ``kw_only=False`` settings.
339 .. versionadded:: 25.4.0
340 Added *force_kw_only* to go back to the previous *kw_only* behavior.
342 .. note::
344 The main differences to the classic `attr.s` are:
346 - Automatically detect whether or not *auto_attribs* should be `True`
347 (c.f. *auto_attribs* parameter).
348 - Converters and validators run when attributes are set by default --
349 if *frozen* is `False`.
350 - *slots=True*
352 Usually, this has only upsides and few visible effects in everyday
353 programming. But it *can* lead to some surprising behaviors, so
354 please make sure to read :term:`slotted classes`.
356 - *auto_exc=True*
357 - *auto_detect=True*
358 - *order=False*
359 - *force_kw_only=False*
360 - Some options that were only relevant on Python 2 or were kept around
361 for backwards-compatibility have been removed.
363 """
365 def do_it(cls, auto_attribs):
366 return attrs(
367 maybe_cls=cls,
368 these=these,
369 repr=repr,
370 hash=hash,
371 unsafe_hash=unsafe_hash,
372 init=init,
373 slots=slots,
374 frozen=frozen,
375 weakref_slot=weakref_slot,
376 str=str,
377 auto_attribs=auto_attribs,
378 kw_only=kw_only,
379 cache_hash=cache_hash,
380 auto_exc=auto_exc,
381 eq=eq,
382 order=order,
383 auto_detect=auto_detect,
384 collect_by_mro=True,
385 getstate_setstate=getstate_setstate,
386 on_setattr=on_setattr,
387 field_transformer=field_transformer,
388 match_args=match_args,
389 force_kw_only=force_kw_only,
390 )
392 def wrap(cls):
393 """
394 Making this a wrapper ensures this code runs during class creation.
396 We also ensure that frozen-ness of classes is inherited.
397 """
398 nonlocal frozen, on_setattr
400 had_on_setattr = on_setattr not in (None, setters.NO_OP)
402 # By default, mutable classes convert & validate on setattr.
403 if frozen is False and on_setattr is None:
404 on_setattr = _DEFAULT_ON_SETATTR
406 # However, if we subclass a frozen class, we inherit the immutability
407 # and disable on_setattr.
408 for base_cls in cls.__bases__:
409 if base_cls.__setattr__ is _frozen_setattrs:
410 if had_on_setattr:
411 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)."
412 raise ValueError(msg)
414 on_setattr = setters.NO_OP
415 break
417 if auto_attribs is not None:
418 return do_it(cls, auto_attribs)
420 try:
421 return do_it(cls, True)
422 except UnannotatedAttributeError:
423 return do_it(cls, False)
425 # maybe_cls's type depends on the usage of the decorator. It's a class
426 # if it's used as `@attrs` but `None` if used as `@attrs()`.
427 if maybe_cls is None:
428 return wrap
430 return wrap(maybe_cls)
433mutable = define
434frozen = partial(define, frozen=True, on_setattr=None)
437def field(
438 *,
439 default=NOTHING,
440 validator=None,
441 repr=True,
442 hash=None,
443 init=True,
444 metadata=None,
445 type=None,
446 converter=None,
447 factory=None,
448 kw_only=None,
449 eq=None,
450 order=None,
451 on_setattr=None,
452 alias=None,
453):
454 """
455 Create a new :term:`field` / :term:`attribute` on a class.
457 .. warning::
459 Does **nothing** unless the class is also decorated with
460 `attrs.define` (or similar)!
462 Args:
463 default:
464 A value that is used if an *attrs*-generated ``__init__`` is used
465 and no value is passed while instantiating or the attribute is
466 excluded using ``init=False``.
468 If the value is an instance of `attrs.Factory`, its callable will
469 be used to construct a new value (useful for mutable data types
470 like lists or dicts).
472 If a default is not set (or set manually to `attrs.NOTHING`), a
473 value *must* be supplied when instantiating; otherwise a
474 `TypeError` will be raised.
476 .. seealso:: `defaults`
478 factory (~typing.Callable):
479 Syntactic sugar for ``default=attr.Factory(factory)``.
481 validator (~typing.Callable | list[~typing.Callable]):
482 Callable that is called by *attrs*-generated ``__init__`` methods
483 after the instance has been initialized. They receive the
484 initialized instance, the :func:`~attrs.Attribute`, and the passed
485 value.
487 The return value is *not* inspected so the validator has to throw
488 an exception itself.
490 If a `list` is passed, its items are treated as validators and must
491 all pass.
493 Validators can be globally disabled and re-enabled using
494 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`.
496 The validator can also be set using decorator notation as shown
497 below.
499 .. seealso:: :ref:`validators`
501 repr (bool | ~typing.Callable):
502 Include this attribute in the generated ``__repr__`` method. If
503 True, include the attribute; if False, omit it. By default, the
504 built-in ``repr()`` function is used. To override how the attribute
505 value is formatted, pass a ``callable`` that takes a single value
506 and returns a string. Note that the resulting string is used as-is,
507 which means it will be used directly *instead* of calling
508 ``repr()`` (the default).
510 eq (bool | ~typing.Callable):
511 If True (default), include this attribute in the generated
512 ``__eq__`` and ``__ne__`` methods that check two instances for
513 equality. To override how the attribute value is compared, pass a
514 callable that takes a single value and returns the value to be
515 compared.
517 .. seealso:: `comparison`
519 order (bool | ~typing.Callable):
520 If True (default), include this attributes in the generated
521 ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To
522 override how the attribute value is ordered, pass a callable that
523 takes a single value and returns the value to be ordered.
525 .. seealso:: `comparison`
527 hash (bool | None):
528 Include this attribute in the generated ``__hash__`` method. If
529 None (default), mirror *eq*'s value. This is the correct behavior
530 according the Python spec. Setting this value to anything else
531 than None is *discouraged*.
533 .. seealso:: `hashing`
535 init (bool):
536 Include this attribute in the generated ``__init__`` method.
538 It is possible to set this to False and set a default value. In
539 that case this attributed is unconditionally initialized with the
540 specified default value or factory.
542 .. seealso:: `init`
544 converter (typing.Callable | Converter):
545 A callable that is called by *attrs*-generated ``__init__`` methods
546 to convert attribute's value to the desired format.
548 If a vanilla callable is passed, it is given the passed-in value as
549 the only positional argument. It is possible to receive additional
550 arguments by wrapping the callable in a `Converter`.
552 Either way, the returned value will be used as the new value of the
553 attribute. The value is converted before being passed to the
554 validator, if any.
556 .. seealso:: :ref:`converters`
558 metadata (dict | None):
559 An arbitrary mapping, to be used by third-party code.
561 .. seealso:: `extending-metadata`.
563 type (type):
564 The type of the attribute. Nowadays, the preferred method to
565 specify the type is using a variable annotation (see :pep:`526`).
566 This argument is provided for backwards-compatibility and for usage
567 with `make_class`. Regardless of the approach used, the type will
568 be stored on ``Attribute.type``.
570 Please note that *attrs* doesn't do anything with this metadata by
571 itself. You can use it as part of your own code or for `static type
572 checking <types>`.
574 kw_only (bool | None):
575 Make this attribute keyword-only in the generated ``__init__`` (if
576 *init* is False, this parameter is ignored). If None (default),
577 mirror the setting from `attrs.define`.
579 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
580 Allows to overwrite the *on_setattr* setting from `attr.s`. If left
581 None, the *on_setattr* value from `attr.s` is used. Set to
582 `attrs.setters.NO_OP` to run **no** `setattr` hooks for this
583 attribute -- regardless of the setting in `define()`.
585 alias (str | None):
586 Override this attribute's parameter name in the generated
587 ``__init__`` method. If left None, default to ``name`` stripped
588 of leading underscores. See `private-attributes`.
590 .. versionadded:: 20.1.0
591 .. versionchanged:: 21.1.0
592 *eq*, *order*, and *cmp* also accept a custom callable
593 .. versionadded:: 22.2.0 *alias*
594 .. versionadded:: 23.1.0
595 The *type* parameter has been re-added; mostly for `attrs.make_class`.
596 Please note that type checkers ignore this metadata.
597 .. versionchanged:: 25.4.0
598 *kw_only* can now be None, and its default is also changed from False to
599 None.
601 .. seealso::
603 `attr.ib`
604 """
605 return attrib(
606 default=default,
607 validator=validator,
608 repr=repr,
609 hash=hash,
610 init=init,
611 metadata=metadata,
612 type=type,
613 converter=converter,
614 factory=factory,
615 kw_only=kw_only,
616 eq=eq,
617 order=order,
618 on_setattr=on_setattr,
619 alias=alias,
620 )
623def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
624 """
625 Same as `attr.asdict`, except that collections types are always retained
626 and dict is always used as *dict_factory*.
628 .. versionadded:: 21.3.0
629 """
630 return _asdict(
631 inst=inst,
632 recurse=recurse,
633 filter=filter,
634 value_serializer=value_serializer,
635 retain_collection_types=True,
636 )
639def astuple(inst, *, recurse=True, filter=None):
640 """
641 Same as `attr.astuple`, except that collections types are always retained
642 and `tuple` is always used as the *tuple_factory*.
644 .. versionadded:: 21.3.0
645 """
646 return _astuple(
647 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
648 )