aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/attr/_next_gen.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/attr/_next_gen.py')
-rw-r--r--.venv/lib/python3.12/site-packages/attr/_next_gen.py623
1 files changed, 623 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/attr/_next_gen.py b/.venv/lib/python3.12/site-packages/attr/_next_gen.py
new file mode 100644
index 00000000..9290664b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/attr/_next_gen.py
@@ -0,0 +1,623 @@
+# SPDX-License-Identifier: MIT
+
+"""
+These are keyword-only APIs that call `attr.s` and `attr.ib` with different
+default values.
+"""
+
+from functools import partial
+
+from . import setters
+from ._funcs import asdict as _asdict
+from ._funcs import astuple as _astuple
+from ._make import (
+ _DEFAULT_ON_SETATTR,
+ NOTHING,
+ _frozen_setattrs,
+ attrib,
+ attrs,
+)
+from .exceptions import UnannotatedAttributeError
+
+
+def define(
+ maybe_cls=None,
+ *,
+ these=None,
+ repr=None,
+ unsafe_hash=None,
+ hash=None,
+ init=None,
+ slots=True,
+ frozen=False,
+ weakref_slot=True,
+ str=False,
+ auto_attribs=None,
+ kw_only=False,
+ cache_hash=False,
+ auto_exc=True,
+ eq=None,
+ order=False,
+ auto_detect=True,
+ getstate_setstate=None,
+ on_setattr=None,
+ field_transformer=None,
+ match_args=True,
+):
+ r"""
+ A class decorator that adds :term:`dunder methods` according to
+ :term:`fields <field>` specified using :doc:`type annotations <types>`,
+ `field()` calls, or the *these* argument.
+
+ Since *attrs* patches or replaces an existing class, you cannot use
+ `object.__init_subclass__` with *attrs* classes, because it runs too early.
+ As a replacement, you can define ``__attrs_init_subclass__`` on your class.
+ It will be called by *attrs* classes that subclass it after they're
+ created. See also :ref:`init-subclass`.
+
+ Args:
+ slots (bool):
+ Create a :term:`slotted class <slotted classes>` that's more
+ memory-efficient. Slotted classes are generally superior to the
+ default dict classes, but have some gotchas you should know about,
+ so we encourage you to read the :term:`glossary entry <slotted
+ classes>`.
+
+ auto_detect (bool):
+ Instead of setting the *init*, *repr*, *eq*, and *hash* arguments
+ explicitly, assume they are set to True **unless any** of the
+ involved methods for one of the arguments is implemented in the
+ *current* class (meaning, it is *not* inherited from some base
+ class).
+
+ So, for example by implementing ``__eq__`` on a class yourself,
+ *attrs* will deduce ``eq=False`` and will create *neither*
+ ``__eq__`` *nor* ``__ne__`` (but Python classes come with a
+ sensible ``__ne__`` by default, so it *should* be enough to only
+ implement ``__eq__`` in most cases).
+
+ Passing True or False` to *init*, *repr*, *eq*, or *hash*
+ overrides whatever *auto_detect* would determine.
+
+ auto_exc (bool):
+ If the class subclasses `BaseException` (which implicitly includes
+ any subclass of any exception), the following happens to behave
+ like a well-behaved Python exception class:
+
+ - the values for *eq*, *order*, and *hash* are ignored and the
+ instances compare and hash by the instance's ids [#]_ ,
+ - all attributes that are either passed into ``__init__`` or have a
+ default value are additionally available as a tuple in the
+ ``args`` attribute,
+ - the value of *str* is ignored leaving ``__str__`` to base
+ classes.
+
+ .. [#]
+ Note that *attrs* will *not* remove existing implementations of
+ ``__hash__`` or the equality methods. It just won't add own
+ ones.
+
+ on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
+ A callable that is run whenever the user attempts to set an
+ attribute (either by assignment like ``i.x = 42`` or by using
+ `setattr` like ``setattr(i, "x", 42)``). It receives the same
+ arguments as validators: the instance, the attribute that is being
+ modified, and the new value.
+
+ If no exception is raised, the attribute is set to the return value
+ of the callable.
+
+ If a list of callables is passed, they're automatically wrapped in
+ an `attrs.setters.pipe`.
+
+ If left None, the default behavior is to run converters and
+ validators whenever an attribute is set.
+
+ init (bool):
+ Create a ``__init__`` method that initializes the *attrs*
+ attributes. Leading underscores are stripped for the argument name,
+ unless an alias is set on the attribute.
+
+ .. seealso::
+ `init` shows advanced ways to customize the generated
+ ``__init__`` method, including executing code before and after.
+
+ repr(bool):
+ Create a ``__repr__`` method with a human readable representation
+ of *attrs* attributes.
+
+ str (bool):
+ Create a ``__str__`` method that is identical to ``__repr__``. This
+ is usually not necessary except for `Exception`\ s.
+
+ eq (bool | None):
+ If True or None (default), add ``__eq__`` and ``__ne__`` methods
+ that check two instances for equality.
+
+ .. seealso::
+ `comparison` describes how to customize the comparison behavior
+ going as far comparing NumPy arrays.
+
+ order (bool | None):
+ If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``
+ methods that behave like *eq* above and allow instances to be
+ ordered.
+
+ They compare the instances as if they were tuples of their *attrs*
+ attributes if and only if the types of both classes are
+ *identical*.
+
+ If `None` mirror value of *eq*.
+
+ .. seealso:: `comparison`
+
+ unsafe_hash (bool | None):
+ If None (default), the ``__hash__`` method is generated according
+ how *eq* and *frozen* are set.
+
+ 1. If *both* are True, *attrs* will generate a ``__hash__`` for
+ you.
+ 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set
+ to None, marking it unhashable (which it is).
+ 3. If *eq* is False, ``__hash__`` will be left untouched meaning
+ the ``__hash__`` method of the base class will be used. If the
+ base class is `object`, this means it will fall back to id-based
+ hashing.
+
+ Although not recommended, you can decide for yourself and force
+ *attrs* to create one (for example, if the class is immutable even
+ though you didn't freeze it programmatically) by passing True or
+ not. Both of these cases are rather special and should be used
+ carefully.
+
+ .. seealso::
+
+ - Our documentation on `hashing`,
+ - Python's documentation on `object.__hash__`,
+ - and the `GitHub issue that led to the default \ behavior
+ <https://github.com/python-attrs/attrs/issues/136>`_ for more
+ details.
+
+ hash (bool | None):
+ Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence.
+
+ cache_hash (bool):
+ Ensure that the object's hash code is computed only once and stored
+ on the object. If this is set to True, hashing must be either
+ explicitly or implicitly enabled for this class. If the hash code
+ is cached, avoid any reassignments of fields involved in hash code
+ computation or mutations of the objects those fields point to after
+ object creation. If such changes occur, the behavior of the
+ object's hash code is undefined.
+
+ frozen (bool):
+ Make instances immutable after initialization. If someone attempts
+ to modify a frozen instance, `attrs.exceptions.FrozenInstanceError`
+ is raised.
+
+ .. note::
+
+ 1. This is achieved by installing a custom ``__setattr__``
+ method on your class, so you can't implement your own.
+
+ 2. True immutability is impossible in Python.
+
+ 3. This *does* have a minor a runtime performance `impact
+ <how-frozen>` when initializing new instances. In other
+ words: ``__init__`` is slightly slower with ``frozen=True``.
+
+ 4. If a class is frozen, you cannot modify ``self`` in
+ ``__attrs_post_init__`` or a self-written ``__init__``. You
+ can circumvent that limitation by using
+ ``object.__setattr__(self, "attribute_name", value)``.
+
+ 5. Subclasses of a frozen class are frozen too.
+
+ kw_only (bool):
+ Make all attributes keyword-only in the generated ``__init__`` (if
+ *init* is False, this parameter is ignored).
+
+ weakref_slot (bool):
+ Make instances weak-referenceable. This has no effect unless
+ *slots* is True.
+
+ field_transformer (~typing.Callable | None):
+ A function that is called with the original class object and all
+ fields right before *attrs* finalizes the class. You can use this,
+ for example, to automatically add converters or validators to
+ fields based on their types.
+
+ .. seealso:: `transform-fields`
+
+ match_args (bool):
+ If True (default), set ``__match_args__`` on the class to support
+ :pep:`634` (*Structural Pattern Matching*). It is a tuple of all
+ non-keyword-only ``__init__`` parameter names on Python 3.10 and
+ later. Ignored on older Python versions.
+
+ collect_by_mro (bool):
+ If True, *attrs* collects attributes from base classes correctly
+ according to the `method resolution order
+ <https://docs.python.org/3/howto/mro.html>`_. If False, *attrs*
+ will mimic the (wrong) behavior of `dataclasses` and :pep:`681`.
+
+ See also `issue #428
+ <https://github.com/python-attrs/attrs/issues/428>`_.
+
+ getstate_setstate (bool | None):
+ .. note::
+
+ This is usually only interesting for slotted classes and you
+ should probably just set *auto_detect* to True.
+
+ If True, ``__getstate__`` and ``__setstate__`` are generated and
+ attached to the class. This is necessary for slotted classes to be
+ pickleable. If left None, it's True by default for slotted classes
+ and False for dict classes.
+
+ If *auto_detect* is True, and *getstate_setstate* is left None, and
+ **either** ``__getstate__`` or ``__setstate__`` is detected
+ directly on the class (meaning: not inherited), it is set to False
+ (this is usually what you want).
+
+ auto_attribs (bool | None):
+ If True, look at type annotations to determine which attributes to
+ use, like `dataclasses`. If False, it will only look for explicit
+ :func:`field` class attributes, like classic *attrs*.
+
+ If left None, it will guess:
+
+ 1. If any attributes are annotated and no unannotated
+ `attrs.field`\ s are found, it assumes *auto_attribs=True*.
+ 2. Otherwise it assumes *auto_attribs=False* and tries to collect
+ `attrs.field`\ s.
+
+ If *attrs* decides to look at type annotations, **all** fields
+ **must** be annotated. If *attrs* encounters a field that is set to
+ a :func:`field` / `attr.ib` but lacks a type annotation, an
+ `attrs.exceptions.UnannotatedAttributeError` is raised. Use
+ ``field_name: typing.Any = field(...)`` if you don't want to set a
+ type.
+
+ .. warning::
+
+ For features that use the attribute name to create decorators
+ (for example, :ref:`validators <validators>`), you still *must*
+ assign :func:`field` / `attr.ib` to them. Otherwise Python will
+ either not find the name or try to use the default value to
+ call, for example, ``validator`` on it.
+
+ Attributes annotated as `typing.ClassVar`, and attributes that are
+ neither annotated nor set to an `field()` are **ignored**.
+
+ these (dict[str, object]):
+ A dictionary of name to the (private) return value of `field()`
+ mappings. This is useful to avoid the definition of your attributes
+ within the class body because you can't (for example, if you want
+ to add ``__repr__`` methods to Django models) or don't want to.
+
+ If *these* is not `None`, *attrs* will *not* search the class body
+ for attributes and will *not* remove any attributes from it.
+
+ The order is deduced from the order of the attributes inside
+ *these*.
+
+ Arguably, this is a rather obscure feature.
+
+ .. versionadded:: 20.1.0
+ .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
+ .. versionadded:: 22.2.0
+ *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
+ .. versionchanged:: 24.1.0
+ Instances are not compared as tuples of attributes anymore, but using a
+ big ``and`` condition. This is faster and has more correct behavior for
+ uncomparable values like `math.nan`.
+ .. versionadded:: 24.1.0
+ If a class has an *inherited* classmethod called
+ ``__attrs_init_subclass__``, it is executed after the class is created.
+ .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
+ .. versionadded:: 24.3.0
+ Unless already present, a ``__replace__`` method is automatically
+ created for `copy.replace` (Python 3.13+ only).
+
+ .. note::
+
+ The main differences to the classic `attr.s` are:
+
+ - Automatically detect whether or not *auto_attribs* should be `True`
+ (c.f. *auto_attribs* parameter).
+ - Converters and validators run when attributes are set by default --
+ if *frozen* is `False`.
+ - *slots=True*
+
+ Usually, this has only upsides and few visible effects in everyday
+ programming. But it *can* lead to some surprising behaviors, so
+ please make sure to read :term:`slotted classes`.
+
+ - *auto_exc=True*
+ - *auto_detect=True*
+ - *order=False*
+ - Some options that were only relevant on Python 2 or were kept around
+ for backwards-compatibility have been removed.
+
+ """
+
+ def do_it(cls, auto_attribs):
+ return attrs(
+ maybe_cls=cls,
+ these=these,
+ repr=repr,
+ hash=hash,
+ unsafe_hash=unsafe_hash,
+ init=init,
+ slots=slots,
+ frozen=frozen,
+ weakref_slot=weakref_slot,
+ str=str,
+ auto_attribs=auto_attribs,
+ kw_only=kw_only,
+ cache_hash=cache_hash,
+ auto_exc=auto_exc,
+ eq=eq,
+ order=order,
+ auto_detect=auto_detect,
+ collect_by_mro=True,
+ getstate_setstate=getstate_setstate,
+ on_setattr=on_setattr,
+ field_transformer=field_transformer,
+ match_args=match_args,
+ )
+
+ def wrap(cls):
+ """
+ Making this a wrapper ensures this code runs during class creation.
+
+ We also ensure that frozen-ness of classes is inherited.
+ """
+ nonlocal frozen, on_setattr
+
+ had_on_setattr = on_setattr not in (None, setters.NO_OP)
+
+ # By default, mutable classes convert & validate on setattr.
+ if frozen is False and on_setattr is None:
+ on_setattr = _DEFAULT_ON_SETATTR
+
+ # However, if we subclass a frozen class, we inherit the immutability
+ # and disable on_setattr.
+ for base_cls in cls.__bases__:
+ if base_cls.__setattr__ is _frozen_setattrs:
+ if had_on_setattr:
+ msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)."
+ raise ValueError(msg)
+
+ on_setattr = setters.NO_OP
+ break
+
+ if auto_attribs is not None:
+ return do_it(cls, auto_attribs)
+
+ try:
+ return do_it(cls, True)
+ except UnannotatedAttributeError:
+ return do_it(cls, False)
+
+ # maybe_cls's type depends on the usage of the decorator. It's a class
+ # if it's used as `@attrs` but `None` if used as `@attrs()`.
+ if maybe_cls is None:
+ return wrap
+
+ return wrap(maybe_cls)
+
+
+mutable = define
+frozen = partial(define, frozen=True, on_setattr=None)
+
+
+def field(
+ *,
+ default=NOTHING,
+ validator=None,
+ repr=True,
+ hash=None,
+ init=True,
+ metadata=None,
+ type=None,
+ converter=None,
+ factory=None,
+ kw_only=False,
+ eq=None,
+ order=None,
+ on_setattr=None,
+ alias=None,
+):
+ """
+ Create a new :term:`field` / :term:`attribute` on a class.
+
+ .. warning::
+
+ Does **nothing** unless the class is also decorated with
+ `attrs.define` (or similar)!
+
+ Args:
+ default:
+ A value that is used if an *attrs*-generated ``__init__`` is used
+ and no value is passed while instantiating or the attribute is
+ excluded using ``init=False``.
+
+ If the value is an instance of `attrs.Factory`, its callable will
+ be used to construct a new value (useful for mutable data types
+ like lists or dicts).
+
+ If a default is not set (or set manually to `attrs.NOTHING`), a
+ value *must* be supplied when instantiating; otherwise a
+ `TypeError` will be raised.
+
+ .. seealso:: `defaults`
+
+ factory (~typing.Callable):
+ Syntactic sugar for ``default=attr.Factory(factory)``.
+
+ validator (~typing.Callable | list[~typing.Callable]):
+ Callable that is called by *attrs*-generated ``__init__`` methods
+ after the instance has been initialized. They receive the
+ initialized instance, the :func:`~attrs.Attribute`, and the passed
+ value.
+
+ The return value is *not* inspected so the validator has to throw
+ an exception itself.
+
+ If a `list` is passed, its items are treated as validators and must
+ all pass.
+
+ Validators can be globally disabled and re-enabled using
+ `attrs.validators.get_disabled` / `attrs.validators.set_disabled`.
+
+ The validator can also be set using decorator notation as shown
+ below.
+
+ .. seealso:: :ref:`validators`
+
+ repr (bool | ~typing.Callable):
+ Include this attribute in the generated ``__repr__`` method. If
+ True, include the attribute; if False, omit it. By default, the
+ built-in ``repr()`` function is used. To override how the attribute
+ value is formatted, pass a ``callable`` that takes a single value
+ and returns a string. Note that the resulting string is used as-is,
+ which means it will be used directly *instead* of calling
+ ``repr()`` (the default).
+
+ eq (bool | ~typing.Callable):
+ If True (default), include this attribute in the generated
+ ``__eq__`` and ``__ne__`` methods that check two instances for
+ equality. To override how the attribute value is compared, pass a
+ callable that takes a single value and returns the value to be
+ compared.
+
+ .. seealso:: `comparison`
+
+ order (bool | ~typing.Callable):
+ If True (default), include this attributes in the generated
+ ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To
+ override how the attribute value is ordered, pass a callable that
+ takes a single value and returns the value to be ordered.
+
+ .. seealso:: `comparison`
+
+ hash (bool | None):
+ Include this attribute in the generated ``__hash__`` method. If
+ None (default), mirror *eq*'s value. This is the correct behavior
+ according the Python spec. Setting this value to anything else
+ than None is *discouraged*.
+
+ .. seealso:: `hashing`
+
+ init (bool):
+ Include this attribute in the generated ``__init__`` method.
+
+ It is possible to set this to False and set a default value. In
+ that case this attributed is unconditionally initialized with the
+ specified default value or factory.
+
+ .. seealso:: `init`
+
+ converter (typing.Callable | Converter):
+ A callable that is called by *attrs*-generated ``__init__`` methods
+ to convert attribute's value to the desired format.
+
+ If a vanilla callable is passed, it is given the passed-in value as
+ the only positional argument. It is possible to receive additional
+ arguments by wrapping the callable in a `Converter`.
+
+ Either way, the returned value will be used as the new value of the
+ attribute. The value is converted before being passed to the
+ validator, if any.
+
+ .. seealso:: :ref:`converters`
+
+ metadata (dict | None):
+ An arbitrary mapping, to be used by third-party code.
+
+ .. seealso:: `extending-metadata`.
+
+ type (type):
+ The type of the attribute. Nowadays, the preferred method to
+ specify the type is using a variable annotation (see :pep:`526`).
+ This argument is provided for backwards-compatibility and for usage
+ with `make_class`. Regardless of the approach used, the type will
+ be stored on ``Attribute.type``.
+
+ Please note that *attrs* doesn't do anything with this metadata by
+ itself. You can use it as part of your own code or for `static type
+ checking <types>`.
+
+ kw_only (bool):
+ Make this attribute keyword-only in the generated ``__init__`` (if
+ ``init`` is False, this parameter is ignored).
+
+ on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]):
+ Allows to overwrite the *on_setattr* setting from `attr.s`. If left
+ None, the *on_setattr* value from `attr.s` is used. Set to
+ `attrs.setters.NO_OP` to run **no** `setattr` hooks for this
+ attribute -- regardless of the setting in `define()`.
+
+ alias (str | None):
+ Override this attribute's parameter name in the generated
+ ``__init__`` method. If left None, default to ``name`` stripped
+ of leading underscores. See `private-attributes`.
+
+ .. versionadded:: 20.1.0
+ .. versionchanged:: 21.1.0
+ *eq*, *order*, and *cmp* also accept a custom callable
+ .. versionadded:: 22.2.0 *alias*
+ .. versionadded:: 23.1.0
+ The *type* parameter has been re-added; mostly for `attrs.make_class`.
+ Please note that type checkers ignore this metadata.
+
+ .. seealso::
+
+ `attr.ib`
+ """
+ return attrib(
+ default=default,
+ validator=validator,
+ repr=repr,
+ hash=hash,
+ init=init,
+ metadata=metadata,
+ type=type,
+ converter=converter,
+ factory=factory,
+ kw_only=kw_only,
+ eq=eq,
+ order=order,
+ on_setattr=on_setattr,
+ alias=alias,
+ )
+
+
+def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
+ """
+ Same as `attr.asdict`, except that collections types are always retained
+ and dict is always used as *dict_factory*.
+
+ .. versionadded:: 21.3.0
+ """
+ return _asdict(
+ inst=inst,
+ recurse=recurse,
+ filter=filter,
+ value_serializer=value_serializer,
+ retain_collection_types=True,
+ )
+
+
+def astuple(inst, *, recurse=True, filter=None):
+ """
+ Same as `attr.astuple`, except that collections types are always retained
+ and `tuple` is always used as the *tuple_factory*.
+
+ .. versionadded:: 21.3.0
+ """
+ return _astuple(
+ inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
+ )