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 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 force_kw_only (bool):
244 A back-compat flag for restoring pre-25.4.0 behavior. If True and
245 ``kw_only=True``, all attributes are made keyword-only, including
246 base class attributes, and those set to ``kw_only=False`` at the
247 attribute level. Defaults to False.
249 See also `issue #980
250 <https://github.com/python-attrs/attrs/issues/980>`_.
252 getstate_setstate (bool | None):
253 .. note::
255 This is usually only interesting for slotted classes and you
256 should probably just set *auto_detect* to True.
258 If True, ``__getstate__`` and ``__setstate__`` are generated and
259 attached to the class. This is necessary for slotted classes to be
260 pickleable. If left None, it's True by default for slotted classes
261 and False for dict classes.
263 If *auto_detect* is True, and *getstate_setstate* is left None, and
264 **either** ``__getstate__`` or ``__setstate__`` is detected
265 directly on the class (meaning: not inherited), it is set to False
266 (this is usually what you want).
268 auto_attribs (bool | None):
269 If True, look at type annotations to determine which attributes to
270 use, like `dataclasses`. If False, it will only look for explicit
271 :func:`field` class attributes, like classic *attrs*.
273 If left None, it will guess:
275 1. If any attributes are annotated and no unannotated
276 `attrs.field`\ s are found, it assumes *auto_attribs=True*.
277 2. Otherwise it assumes *auto_attribs=False* and tries to collect
278 `attrs.field`\ s.
280 If *attrs* decides to look at type annotations, **all** fields
281 **must** be annotated. If *attrs* encounters a field that is set to
282 a :func:`field` / `attr.ib` but lacks a type annotation, an
283 `attrs.exceptions.UnannotatedAttributeError` is raised. Use
284 ``field_name: typing.Any = field(...)`` if you don't want to set a
285 type.
287 .. warning::
289 For features that use the attribute name to create decorators
290 (for example, :ref:`validators <validators>`), you still *must*
291 assign :func:`field` / `attr.ib` to them. Otherwise Python will
292 either not find the name or try to use the default value to
293 call, for example, ``validator`` on it.
295 Attributes annotated as `typing.ClassVar`, and attributes that are
296 neither annotated nor set to an `field()` are **ignored**.
298 these (dict[str, object]):
299 A dictionary of name to the (private) return value of `field()`
300 mappings. This is useful to avoid the definition of your attributes
301 within the class body because you can't (for example, if you want
302 to add ``__repr__`` methods to Django models) or don't want to.
304 If *these* is not `None`, *attrs* will *not* search the class body
305 for attributes and will *not* remove any attributes from it.
307 The order is deduced from the order of the attributes inside
308 *these*.
310 Arguably, this is a rather obscure feature.
312 .. versionadded:: 20.1.0
313 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
314 .. versionadded:: 22.2.0
315 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
316 .. versionchanged:: 24.1.0
317 Instances are not compared as tuples of attributes anymore, but using a
318 big ``and`` condition. This is faster and has more correct behavior for
319 uncomparable values like `math.nan`.
320 .. versionadded:: 24.1.0
321 If a class has an *inherited* classmethod called
322 ``__attrs_init_subclass__``, it is executed after the class is created.
323 .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
324 .. versionadded:: 24.3.0
325 Unless already present, a ``__replace__`` method is automatically
326 created for `copy.replace` (Python 3.13+ only).
327 .. versionchanged:: 25.4.0
328 *kw_only* now only applies to attributes defined in the current class,
329 and respects attribute-level ``kw_only=False`` settings.
330 .. versionadded:: 25.4.0
331 Added *force_kw_only* to go back to the previous *kw_only* behavior.
333 .. note::
335 The main differences to the classic `attr.s` are:
337 - Automatically detect whether or not *auto_attribs* should be `True`
338 (c.f. *auto_attribs* parameter).
339 - Converters and validators run when attributes are set by default --
340 if *frozen* is `False`.
341 - *slots=True*
343 Usually, this has only upsides and few visible effects in everyday
344 programming. But it *can* lead to some surprising behaviors, so
345 please make sure to read :term:`slotted classes`.
347 - *auto_exc=True*
348 - *auto_detect=True*
349 - *order=False*
350 - *force_kw_only=False*
351 - Some options that were only relevant on Python 2 or were kept around
352 for backwards-compatibility have been removed.
354 """
356 def do_it(cls, auto_attribs):
357 return attrs(
358 maybe_cls=cls,
359 these=these,
360 repr=repr,
361 hash=hash,
362 unsafe_hash=unsafe_hash,
363 init=init,
364 slots=slots,
365 frozen=frozen,
366 weakref_slot=weakref_slot,
367 str=str,
368 auto_attribs=auto_attribs,
369 kw_only=kw_only,
370 cache_hash=cache_hash,
371 auto_exc=auto_exc,
372 eq=eq,
373 order=order,
374 auto_detect=auto_detect,
375 collect_by_mro=True,
376 getstate_setstate=getstate_setstate,
377 on_setattr=on_setattr,
378 field_transformer=field_transformer,
379 match_args=match_args,
380 force_kw_only=force_kw_only,
381 )
383 def wrap(cls):
384 """
385 Making this a wrapper ensures this code runs during class creation.
387 We also ensure that frozen-ness of classes is inherited.
388 """
389 nonlocal frozen, on_setattr
391 had_on_setattr = on_setattr not in (None, setters.NO_OP)
393 # By default, mutable classes convert & validate on setattr.
394 if frozen is False and on_setattr is None:
395 on_setattr = _DEFAULT_ON_SETATTR
397 # However, if we subclass a frozen class, we inherit the immutability
398 # and disable on_setattr.
399 for base_cls in cls.__bases__:
400 if base_cls.__setattr__ is _frozen_setattrs:
401 if had_on_setattr:
402 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)."
403 raise ValueError(msg)
405 on_setattr = setters.NO_OP
406 break
408 if auto_attribs is not None:
409 return do_it(cls, auto_attribs)
411 try:
412 return do_it(cls, True)
413 except UnannotatedAttributeError:
414 return do_it(cls, False)
416 # maybe_cls's type depends on the usage of the decorator. It's a class
417 # if it's used as `@attrs` but `None` if used as `@attrs()`.
418 if maybe_cls is None:
419 return wrap
421 return wrap(maybe_cls)
424mutable = define
425frozen = partial(define, frozen=True, on_setattr=None)
428def field(
429 *,
430 default=NOTHING,
431 validator=None,
432 repr=True,
433 hash=None,
434 init=True,
435 metadata=None,
436 type=None,
437 converter=None,
438 factory=None,
439 kw_only=None,
440 eq=None,
441 order=None,
442 on_setattr=None,
443 alias=None,
444):
445 """
446 Create a new :term:`field` / :term:`attribute` on a class.
448 .. warning::
450 Does **nothing** unless the class is also decorated with
451 `attrs.define` (or similar)!
453 Args:
454 default:
455 A value that is used if an *attrs*-generated ``__init__`` is used
456 and no value is passed while instantiating or the attribute is
457 excluded using ``init=False``.
459 If the value is an instance of `attrs.Factory`, its callable will
460 be used to construct a new value (useful for mutable data types
461 like lists or dicts).
463 If a default is not set (or set manually to `attrs.NOTHING`), a
464 value *must* be supplied when instantiating; otherwise a
465 `TypeError` will be raised.
467 .. seealso:: `defaults`
469 factory (~typing.Callable):
470 Syntactic sugar for ``default=attr.Factory(factory)``.
472 validator (~typing.Callable | list[~typing.Callable]):
473 Callable that is called by *attrs*-generated ``__init__`` methods
474 after the instance has been initialized. They receive the
475 initialized instance, the :func:`~attrs.Attribute`, and the passed
476 value.
478 The return value is *not* inspected so the validator has to throw
479 an exception itself.
481 If a `list` is passed, its items are treated as validators and must
482 all pass.
484 Validators can be globally disabled and re-enabled using
485 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`.
487 The validator can also be set using decorator notation as shown
488 below.
490 .. seealso:: :ref:`validators`
492 repr (bool | ~typing.Callable):
493 Include this attribute in the generated ``__repr__`` method. If
494 True, include the attribute; if False, omit it. By default, the
495 built-in ``repr()`` function is used. To override how the attribute
496 value is formatted, pass a ``callable`` that takes a single value
497 and returns a string. Note that the resulting string is used as-is,
498 which means it will be used directly *instead* of calling
499 ``repr()`` (the default).
501 eq (bool | ~typing.Callable):
502 If True (default), include this attribute in the generated
503 ``__eq__`` and ``__ne__`` methods that check two instances for
504 equality. To override how the attribute value is compared, pass a
505 callable that takes a single value and returns the value to be
506 compared.
508 .. seealso:: `comparison`
510 order (bool | ~typing.Callable):
511 If True (default), include this attributes in the generated
512 ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To
513 override how the attribute value is ordered, pass a callable that
514 takes a single value and returns the value to be ordered.
516 .. seealso:: `comparison`
518 hash (bool | None):
519 Include this attribute in the generated ``__hash__`` method. If
520 None (default), mirror *eq*'s value. This is the correct behavior
521 according the Python spec. Setting this value to anything else
522 than None is *discouraged*.
524 .. seealso:: `hashing`
526 init (bool):
527 Include this attribute in the generated ``__init__`` method.
529 It is possible to set this to False and set a default value. In
530 that case this attributed is unconditionally initialized with the
531 specified default value or factory.
533 .. seealso:: `init`
535 converter (typing.Callable | Converter):
536 A callable that is called by *attrs*-generated ``__init__`` methods
537 to convert attribute's value to the desired format.
539 If a vanilla callable is passed, it is given the passed-in value as
540 the only positional argument. It is possible to receive additional
541 arguments by wrapping the callable in a `Converter`.
543 Either way, the returned value will be used as the new value of the
544 attribute. The value is converted before being passed to the
545 validator, if any.
547 .. seealso:: :ref:`converters`
549 metadata (dict | None):
550 An arbitrary mapping, to be used by third-party code.
552 .. seealso:: `extending-metadata`.
554 type (type):
555 The type of the attribute. Nowadays, the preferred method to
556 specify the type is using a variable annotation (see :pep:`526`).
557 This argument is provided for backwards-compatibility and for usage
558 with `make_class`. Regardless of the approach used, the type will
559 be stored on ``Attribute.type``.
561 Please note that *attrs* doesn't do anything with this metadata by
562 itself. You can use it as part of your own code or for `static type
563 checking <types>`.
565 kw_only (bool | None):
566 Make this attribute keyword-only in the generated ``__init__`` (if
567 *init* is False, this parameter is ignored). If None (default),
568 mirror the setting from `attrs.define`.
570 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
571 Allows to overwrite the *on_setattr* setting from `attr.s`. If left
572 None, the *on_setattr* value from `attr.s` is used. Set to
573 `attrs.setters.NO_OP` to run **no** `setattr` hooks for this
574 attribute -- regardless of the setting in `define()`.
576 alias (str | None):
577 Override this attribute's parameter name in the generated
578 ``__init__`` method. If left None, default to ``name`` stripped
579 of leading underscores. See `private-attributes`.
581 .. versionadded:: 20.1.0
582 .. versionchanged:: 21.1.0
583 *eq*, *order*, and *cmp* also accept a custom callable
584 .. versionadded:: 22.2.0 *alias*
585 .. versionadded:: 23.1.0
586 The *type* parameter has been re-added; mostly for `attrs.make_class`.
587 Please note that type checkers ignore this metadata.
588 .. versionchanged:: 25.4.0
589 *kw_only* can now be None, and its default is also changed from False to
590 None.
592 .. seealso::
594 `attr.ib`
595 """
596 return attrib(
597 default=default,
598 validator=validator,
599 repr=repr,
600 hash=hash,
601 init=init,
602 metadata=metadata,
603 type=type,
604 converter=converter,
605 factory=factory,
606 kw_only=kw_only,
607 eq=eq,
608 order=order,
609 on_setattr=on_setattr,
610 alias=alias,
611 )
614def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
615 """
616 Same as `attr.asdict`, except that collections types are always retained
617 and dict is always used as *dict_factory*.
619 .. versionadded:: 21.3.0
620 """
621 return _asdict(
622 inst=inst,
623 recurse=recurse,
624 filter=filter,
625 value_serializer=value_serializer,
626 retain_collection_types=True,
627 )
630def astuple(inst, *, recurse=True, filter=None):
631 """
632 Same as `attr.astuple`, except that collections types are always retained
633 and `tuple` is always used as the *tuple_factory*.
635 .. versionadded:: 21.3.0
636 """
637 return _astuple(
638 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
639 )
642def inspect(cls):
643 """
644 Inspect the class and return its effective build parameters.
646 Warning:
647 This feature is currently **experimental** and is not covered by our
648 strict backwards-compatibility guarantees.
650 Args:
651 cls: The *attrs*-decorated class to inspect.
653 Returns:
654 The effective build parameters of the class.
656 Raises:
657 NotAnAttrsClassError: If the class is not an *attrs*-decorated class.
659 .. versionadded:: 25.4.0
660 """
661 try:
662 return cls.__dict__["__attrs_props__"]
663 except KeyError:
664 msg = f"{cls!r} is not an attrs-decorated class."
665 raise NotAnAttrsClassError(msg) from None