Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/attr/_next_gen.py: 69%
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 NotAnAttrsClassError, 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 the callable is a generator, it may yield exactly once and runs
112 before and after the assignment and its yield value is used as the
113 new value.
115 If a list of callables is passed, they're automatically wrapped in
116 an `attrs.setters.pipe`.
118 If left None, the default behavior is to run converters and
119 validators whenever an attribute is set.
121 init (bool):
122 Create a ``__init__`` method that initializes the *attrs*
123 attributes. Leading underscores are stripped for the argument name,
124 unless an alias is set on the attribute.
126 .. seealso::
127 `init` shows advanced ways to customize the generated
128 ``__init__`` method, including executing code before and after.
130 repr(bool):
131 Create a ``__repr__`` method with a human readable representation
132 of *attrs* attributes.
134 str (bool):
135 Create a ``__str__`` method that is identical to ``__repr__``. This
136 is usually not necessary except for `Exception`\ s.
138 eq (bool | None):
139 If True or None (default), add ``__eq__`` and ``__ne__`` methods
140 that check two instances for equality.
142 .. seealso::
143 `comparison` describes how to customize the comparison behavior
144 going as far comparing NumPy arrays.
146 order (bool | None):
147 If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``
148 methods that behave like *eq* above and allow instances to be
149 ordered.
151 They compare the instances as if they were tuples of their *attrs*
152 attributes if and only if the types of both classes are
153 *identical*.
155 If `None` mirror value of *eq*.
157 .. seealso:: `comparison`
159 unsafe_hash (bool | None):
160 If None (default), the ``__hash__`` method is generated according
161 how *eq* and *frozen* are set.
163 1. If *both* are True, *attrs* will generate a ``__hash__`` for
164 you.
165 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set
166 to None, marking it unhashable (which it is).
167 3. If *eq* is False, ``__hash__`` will be left untouched meaning
168 the ``__hash__`` method of the base class will be used. If the
169 base class is `object`, this means it will fall back to id-based
170 hashing.
172 Although not recommended, you can decide for yourself and force
173 *attrs* to create one (for example, if the class is immutable even
174 though you didn't freeze it programmatically) by passing True or
175 not. Both of these cases are rather special and should be used
176 carefully.
178 .. seealso::
180 - Our documentation on `hashing`,
181 - Python's documentation on `object.__hash__`,
182 - and the `GitHub issue that led to the default \ behavior
183 <https://github.com/python-attrs/attrs/issues/136>`_ for more
184 details.
186 hash (bool | None):
187 Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence.
189 cache_hash (bool):
190 Ensure that the object's hash code is computed only once and stored
191 on the object. If this is set to True, hashing must be either
192 explicitly or implicitly enabled for this class. If the hash code
193 is cached, avoid any reassignments of fields involved in hash code
194 computation or mutations of the objects those fields point to after
195 object creation. If such changes occur, the behavior of the
196 object's hash code is undefined.
198 frozen (bool):
199 Make instances immutable after initialization. If someone attempts
200 to modify a frozen instance, `attrs.exceptions.FrozenInstanceError`
201 is raised.
203 .. note::
205 1. This is achieved by installing a custom ``__setattr__``
206 method on your class, so you can't implement your own.
208 2. True immutability is impossible in Python.
210 3. This *does* have a minor a runtime performance `impact
211 <how-frozen>` when initializing new instances. In other
212 words: ``__init__`` is slightly slower with ``frozen=True``.
214 4. If a class is frozen, you cannot modify ``self`` in
215 ``__attrs_post_init__`` or a self-written ``__init__``. You
216 can circumvent that limitation by using
217 ``object.__setattr__(self, "attribute_name", value)``.
219 5. Subclasses of a frozen class are frozen too.
221 kw_only (bool):
222 Make attributes keyword-only in the generated ``__init__`` (if
223 *init* is False, this parameter is ignored). Attributes that
224 explicitly set ``kw_only=False`` are not affected; base class
225 attributes are also not affected.
227 Also see *force_kw_only*.
229 weakref_slot (bool):
230 Make instances weak-referenceable. This has no effect unless
231 *slots* is True.
233 field_transformer (~typing.Callable | None):
234 A function that is called with the original class object and all
235 fields right before *attrs* finalizes the class. You can use this,
236 for example, to automatically add converters or validators to
237 fields based on their types.
239 .. seealso:: `transform-fields`
241 match_args (bool):
242 If True (default), set ``__match_args__`` on the class to support
243 :pep:`634` (*Structural Pattern Matching*). It is a tuple of all
244 non-keyword-only ``__init__`` parameter names.
246 force_kw_only (bool):
247 A back-compat flag for restoring pre-25.4.0 behavior. If True and
248 ``kw_only=True``, all attributes are made keyword-only, including
249 base class attributes, and those set to ``kw_only=False`` at the
250 attribute level. Defaults to False.
252 See also `issue #980
253 <https://github.com/python-attrs/attrs/issues/980>`_.
255 getstate_setstate (bool | None):
256 .. note::
258 This is usually only interesting for slotted classes and you
259 should probably just set *auto_detect* to True.
261 If True, ``__getstate__`` and ``__setstate__`` are generated and
262 attached to the class. This is necessary for slotted classes to be
263 pickleable. If left None, it's True by default for slotted classes
264 and False for dict classes.
266 If *auto_detect* is True, and *getstate_setstate* is left None, and
267 **either** ``__getstate__`` or ``__setstate__`` is detected
268 directly on the class (meaning: not inherited), it is set to False
269 (this is usually what you want).
271 auto_attribs (bool | None):
272 If True, look at type annotations to determine which attributes to
273 use, like `dataclasses`. If False, it will only look for explicit
274 :func:`field` class attributes, like classic *attrs*.
276 If left None, it will guess:
278 1. If any attributes are annotated and no unannotated
279 `attrs.field`\ s are found, it assumes *auto_attribs=True*.
280 2. Otherwise it assumes *auto_attribs=False* and tries to collect
281 `attrs.field`\ s.
283 If *attrs* decides to look at type annotations, **all** fields
284 **must** be annotated. If *attrs* encounters a field that is set to
285 a :func:`field` / `attr.ib` but lacks a type annotation, an
286 `attrs.exceptions.UnannotatedAttributeError` is raised. Use
287 ``field_name: typing.Any = field(...)`` if you don't want to set a
288 type.
290 .. warning::
292 For features that use the attribute name to create decorators
293 (for example, :ref:`validators <validators>`), you still *must*
294 assign :func:`field` / `attr.ib` to them. Otherwise Python will
295 either not find the name or try to use the default value to
296 call, for example, ``validator`` on it.
298 Attributes annotated as `typing.ClassVar`, and attributes that are
299 neither annotated nor set to an `field()` are **ignored**.
301 these (dict[str, object]):
302 A dictionary of name to the (private) return value of `field()`
303 mappings. This is useful to avoid the definition of your attributes
304 within the class body because you can't (for example, if you want
305 to add ``__repr__`` methods to Django models) or don't want to.
307 If *these* is not `None`, *attrs* will *not* search the class body
308 for attributes and will *not* remove any attributes from it.
310 The order is deduced from the order of the attributes inside
311 *these*.
313 Arguably, this is a rather obscure feature.
315 .. versionadded:: 20.1.0
316 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
317 .. versionadded:: 22.2.0
318 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
319 .. versionchanged:: 24.1.0
320 Instances are not compared as tuples of attributes anymore, but using a
321 big ``and`` condition. This is faster and has more correct behavior for
322 uncomparable values like `math.nan`.
323 .. versionadded:: 24.1.0
324 If a class has an *inherited* classmethod called
325 ``__attrs_init_subclass__``, it is executed after the class is created.
326 .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
327 .. versionadded:: 24.3.0
328 Unless already present, a ``__replace__`` method is automatically
329 created for `copy.replace` (Python 3.13+ only).
330 .. versionchanged:: 25.4.0
331 *kw_only* now only applies to attributes defined in the current class,
332 and respects attribute-level ``kw_only=False`` settings.
333 .. versionadded:: 25.4.0
334 Added *force_kw_only* to go back to the previous *kw_only* behavior.
335 .. versionchanged:: 26.2.0
336 *on_setattr* hooks can now be generator functions that yield exactly
337 once.
339 .. note::
341 The main differences to the classic `attr.s` are:
343 - Automatically detect whether or not *auto_attribs* should be `True`
344 (c.f. *auto_attribs* parameter).
345 - Converters and validators run when attributes are set by default --
346 if *frozen* is `False`.
347 - *slots=True*
349 Usually, this has only upsides and few visible effects in everyday
350 programming. But it *can* lead to some surprising behaviors, so
351 please make sure to read :term:`slotted classes`.
353 - *auto_exc=True*
354 - *auto_detect=True*
355 - *order=False*
356 - *force_kw_only=False*
357 - Some options that were only relevant on Python 2 or were kept around
358 for backwards-compatibility have been removed.
360 """
362 def do_it(cls, auto_attribs):
363 return attrs(
364 maybe_cls=cls,
365 these=these,
366 repr=repr,
367 hash=hash,
368 unsafe_hash=unsafe_hash,
369 init=init,
370 slots=slots,
371 frozen=frozen,
372 weakref_slot=weakref_slot,
373 str=str,
374 auto_attribs=auto_attribs,
375 kw_only=kw_only,
376 cache_hash=cache_hash,
377 auto_exc=auto_exc,
378 eq=eq,
379 order=order,
380 auto_detect=auto_detect,
381 collect_by_mro=True,
382 getstate_setstate=getstate_setstate,
383 on_setattr=on_setattr,
384 field_transformer=field_transformer,
385 match_args=match_args,
386 force_kw_only=force_kw_only,
387 )
389 def wrap(cls):
390 """
391 Making this a wrapper ensures this code runs during class creation.
393 We also ensure that frozen-ness of classes is inherited.
394 """
395 nonlocal frozen, on_setattr
397 had_on_setattr = on_setattr not in (None, setters.NO_OP)
399 # By default, mutable classes convert & validate on setattr.
400 if frozen is False and on_setattr is None:
401 on_setattr = _DEFAULT_ON_SETATTR
403 # However, if we subclass a frozen class, we inherit the immutability
404 # and disable on_setattr.
405 for base_cls in cls.__bases__:
406 if base_cls.__setattr__ is _frozen_setattrs:
407 if had_on_setattr:
408 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)."
409 raise ValueError(msg)
411 on_setattr = setters.NO_OP
412 break
414 if auto_attribs is not None:
415 return do_it(cls, auto_attribs)
417 try:
418 return do_it(cls, True)
419 except UnannotatedAttributeError:
420 return do_it(cls, False)
422 # maybe_cls's type depends on the usage of the decorator. It's a class
423 # if it's used as `@attrs` but `None` if used as `@attrs()`.
424 if maybe_cls is None:
425 return wrap
427 return wrap(maybe_cls)
430mutable = define
431frozen = partial(define, frozen=True, on_setattr=None)
434def field(
435 *,
436 default=NOTHING,
437 validator=None,
438 repr=True,
439 hash=None,
440 init=True,
441 metadata=None,
442 type=None,
443 converter=None,
444 factory=None,
445 kw_only=None,
446 eq=None,
447 order=None,
448 on_setattr=None,
449 alias=None,
450):
451 """
452 Create a new :term:`field` / :term:`attribute` on a class.
454 .. warning::
456 Does **nothing** unless the class is also decorated with
457 `attrs.define` (or similar)!
459 Args:
460 default:
461 A value that is used if an *attrs*-generated ``__init__`` is used
462 and no value is passed while instantiating or the attribute is
463 excluded using ``init=False``.
465 If the value is an instance of `attrs.Factory`, its callable will
466 be used to construct a new value (useful for mutable data types
467 like lists or dicts).
469 If a default is not set (or set manually to `attrs.NOTHING`), a
470 value *must* be supplied when instantiating; otherwise a
471 `TypeError` will be raised.
473 .. seealso:: `defaults`
475 factory (~typing.Callable):
476 Syntactic sugar for ``default=attr.Factory(factory)``.
478 validator (~typing.Callable | list[~typing.Callable]):
479 Callable that is called by *attrs*-generated ``__init__`` methods
480 after the instance has been initialized. They receive the
481 initialized instance, the :func:`~attrs.Attribute`, and the passed
482 value.
484 The return value is *not* inspected so the validator has to throw
485 an exception itself.
487 If a `list` is passed, its items are treated as validators and must
488 all pass.
490 Validators can be globally disabled and re-enabled using
491 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`.
493 The validator can also be set using decorator notation as shown
494 below.
496 .. seealso:: :ref:`validators`
498 repr (bool | ~typing.Callable):
499 Include this attribute in the generated ``__repr__`` method. If
500 True, include the attribute; if False, omit it. By default, the
501 built-in ``repr()`` function is used. To override how the attribute
502 value is formatted, pass a ``callable`` that takes a single value
503 and returns a string. Note that the resulting string is used as-is,
504 which means it will be used directly *instead* of calling
505 ``repr()`` (the default).
507 eq (bool | ~typing.Callable):
508 If True (default), include this attribute in the generated
509 ``__eq__`` and ``__ne__`` methods that check two instances for
510 equality. To override how the attribute value is compared, pass a
511 callable that takes a single value and returns the value to be
512 compared.
514 .. seealso:: `comparison`
516 order (bool | ~typing.Callable):
517 If True (default), include this attributes in the generated
518 ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To
519 override how the attribute value is ordered, pass a callable that
520 takes a single value and returns the value to be ordered.
522 .. seealso:: `comparison`
524 hash (bool | None):
525 Include this attribute in the generated ``__hash__`` method. If
526 None (default), mirror *eq*'s value. This is the correct behavior
527 according the Python spec. Setting this value to anything else
528 than None is *discouraged*.
530 .. seealso:: `hashing`
532 init (bool):
533 Include this attribute in the generated ``__init__`` method.
535 It is possible to set this to False and set a default value. In
536 that case this attributed is unconditionally initialized with the
537 specified default value or factory.
539 .. seealso:: `init`
541 converter (typing.Callable | Converter):
542 A callable that is called by *attrs*-generated ``__init__`` methods
543 to convert attribute's value to the desired format.
545 If a vanilla callable is passed, it is given the passed-in value as
546 the only positional argument. It is possible to receive additional
547 arguments by wrapping the callable in a `Converter`.
549 Either way, the returned value will be used as the new value of the
550 attribute. The value is converted before being passed to the
551 validator, if any.
553 .. seealso:: :ref:`converters`
555 metadata (dict | None):
556 An arbitrary mapping, to be used by third-party code.
558 .. seealso:: `extending-metadata`.
560 type (type):
561 The type of the attribute. Nowadays, the preferred method to
562 specify the type is using a variable annotation (see :pep:`526`).
563 This argument is provided for backwards-compatibility and for usage
564 with `make_class`. Regardless of the approach used, the type will
565 be stored on ``Attribute.type``.
567 Please note that *attrs* doesn't do anything with this metadata by
568 itself. You can use it as part of your own code or for `static type
569 checking <types>`.
571 kw_only (bool | None):
572 Make this attribute keyword-only in the generated ``__init__`` (if
573 *init* is False, this parameter is ignored). If None (default),
574 mirror the setting from `attrs.define`.
576 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
577 Allows to overwrite the *on_setattr* setting from `attr.s`. If left
578 None, the *on_setattr* value from `attrs.define` is used. Set to
579 `attrs.setters.NO_OP` to run **no** `setattr` hooks for this
580 attribute -- regardless of the setting in `define()`.
582 May be a generator function that yields exactly once and runs
583 before and after the assignment and its yield value is used as the
584 new value.
586 alias (str | None):
587 Override this attribute's parameter name in the generated
588 ``__init__`` method. If left None, default to ``name`` stripped
589 of leading underscores. See `private-attributes`.
591 .. versionadded:: 20.1.0
592 .. versionchanged:: 21.1.0
593 *eq*, *order*, and *cmp* also accept a custom callable
594 .. versionadded:: 22.2.0 *alias*
595 .. versionadded:: 23.1.0
596 The *type* parameter has been re-added; mostly for `attrs.make_class`.
597 Please note that type checkers ignore this metadata.
598 .. versionchanged:: 25.4.0
599 *kw_only* can now be None, and its default is also changed from False to
600 None.
601 .. versionchanged:: 26.2.0
602 *on_setattr* hooks can now be generator functions that yield exactly
603 once.
605 .. seealso::
607 `attr.ib`
608 """
609 return attrib(
610 default=default,
611 validator=validator,
612 repr=repr,
613 hash=hash,
614 init=init,
615 metadata=metadata,
616 type=type,
617 converter=converter,
618 factory=factory,
619 kw_only=kw_only,
620 eq=eq,
621 order=order,
622 on_setattr=on_setattr,
623 alias=alias,
624 )
627def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
628 """
629 Same as `attr.asdict`, except that collections types are always retained
630 and dict is always used as *dict_factory*.
632 .. versionadded:: 21.3.0
633 """
634 return _asdict(
635 inst=inst,
636 recurse=recurse,
637 filter=filter,
638 value_serializer=value_serializer,
639 retain_collection_types=True,
640 )
643def astuple(inst, *, recurse=True, filter=None):
644 """
645 Same as `attr.astuple`, except that collections types are always retained
646 and `tuple` is always used as the *tuple_factory*.
648 .. versionadded:: 21.3.0
649 """
650 return _astuple(
651 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
652 )
655def inspect(cls):
656 """
657 Inspect the class and return its effective build parameters.
659 Warning:
660 This feature is currently **experimental** and is not covered by our
661 strict backwards-compatibility guarantees.
663 Args:
664 cls: The *attrs*-decorated class to inspect.
666 Returns:
667 The effective build parameters of the class.
669 Raises:
670 NotAnAttrsClassError: If the class is not an *attrs*-decorated class.
672 .. versionadded:: 25.4.0
673 """
674 try:
675 return cls.__dict__["__attrs_props__"]
676 except KeyError:
677 msg = f"{cls!r} is not an attrs-decorated class."
678 raise NotAnAttrsClassError(msg) from None