Switch docstrings to Napoleon style (#1308)

* Switch docstrings to Napoleon style

This makes them much more readable while editing.

c.f. https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html

* Add example for Raises
This commit is contained in:
Hynek Schlawack 2024-07-21 12:06:19 +02:00 committed by GitHub
parent a8808a2b3e
commit 8a8cd91bdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 701 additions and 497 deletions

View File

@ -164,16 +164,26 @@ You will find the built documentation in `docs/_build/html`.
- If you add a new feature, demonstrate its awesomeness on the [examples page](https://github.com/python-attrs/attrs/blob/main/docs/examples.md)!
- For docstrings, we follow [PEP 257](https://peps.python.org/pep-0257/) and use the `"""`-on-separate-lines style:
- For docstrings, we follow [PEP 257](https://peps.python.org/pep-0257/), use the `"""`-on-separate-lines style, and [Napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html)-style API documentation:
```python
def func(x):
def func(x: str, y: int) -> str:
"""
Do something.
:param str x: A very important parameter.
Args:
x: A very important argument.
:rtype: str
y:
Another very important argument, but its description is so long
that it doesn't fit on one line. So, we start the whole block on a
fresh new line to keep the block together.
Returns:
str: The result of doing something.
Raises:
ValueError: When an invalid value is passed.
"""
```

View File

@ -46,6 +46,7 @@ nitpick_ignore = [
# ones.
extensions = [
"myst_parser",
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",

View File

@ -26,21 +26,31 @@ def cmp_using(
The resulting class will have a full set of ordering methods if at least
one of ``{lt, le, gt, ge}`` and ``eq`` are provided.
:param typing.Callable | None eq: Callable used to evaluate equality of two
objects.
:param typing.Callable | None lt: Callable used to evaluate whether one
object is less than another object.
:param typing.Callable | None le: Callable used to evaluate whether one
object is less than or equal to another object.
:param typing.Callable | None gt: Callable used to evaluate whether one
object is greater than another object.
:param typing.Callable | None ge: Callable used to evaluate whether one
object is greater than or equal to another object.
Args:
eq (typing.Callable | None):
Callable used to evaluate equality of two objects.
:param bool require_same_type: When `True`, equality and ordering methods
will return `NotImplemented` if objects are not of the same type.
lt (typing.Callable | None):
Callable used to evaluate whether one object is less than another
object.
:param str | None class_name: Name of class. Defaults to "Comparable".
le (typing.Callable | None):
Callable used to evaluate whether one object is less than or equal
to another object.
gt (typing.Callable | None):
Callable used to evaluate whether one object is greater than
another object.
ge (typing.Callable | None):
Callable used to evaluate whether one object is greater than or
equal to another object.
require_same_type (bool):
When `True`, equality and ordering methods will return
`NotImplemented` if objects are not of the same type.
class_name (str | None): Name of class. Defaults to "Comparable".
See `comparison` for more details.

View File

@ -21,33 +21,44 @@ def asdict(
Optionally recurse into other *attrs*-decorated classes.
:param inst: Instance of an *attrs*-decorated class.
:param bool recurse: Recurse into classes that are also *attrs*-decorated.
:param ~typing.Callable filter: A callable whose return code determines
whether an attribute or element is included (`True`) or dropped
(`False`). Is called with the `attrs.Attribute` as the first argument
and the value as the second argument.
:param ~typing.Callable dict_factory: A callable to produce dictionaries
from. For example, to produce ordered dictionaries instead of normal
Python dictionaries, pass in ``collections.OrderedDict``.
:param bool retain_collection_types: Do not convert to `list` when
encountering an attribute whose type is `tuple` or `set`. Only
meaningful if *recurse* is `True`.
:param typing.Callable | None value_serializer: A hook that is called for
every attribute or dict key/value. It receives the current instance,
field and value and must return the (updated) value. The hook is run
*after* the optional *filter* has been applied.
Args:
inst: Instance of an *attrs*-decorated class.
:rtype: return type of *dict_factory*
recurse (bool): Recurse into classes that are also *attrs*-decorated.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class.
filter (~typing.Callable):
A callable whose return code determines whether an attribute or
element is included (`True`) or dropped (`False`). Is called with
the `attrs.Attribute` as the first argument and the value as the
second argument.
dict_factory (~typing.Callable):
A callable to produce dictionaries from. For example, to produce
ordered dictionaries instead of normal Python dictionaries, pass in
``collections.OrderedDict``.
retain_collection_types (bool):
Do not convert to `list` when encountering an attribute whose type
is `tuple` or `set`. Only meaningful if *recurse* is `True`.
value_serializer (typing.Callable | None):
A hook that is called for every attribute or dict key/value. It
receives the current instance, field and value and must return the
(updated) value. The hook is run *after* the optional *filter* has
been applied.
Returns:
Return type of *dict_factory*.
Raises:
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class.
.. versionadded:: 16.0.0 *dict_factory*
.. versionadded:: 16.1.0 *retain_collection_types*
.. versionadded:: 20.3.0 *value_serializer*
.. versionadded:: 21.3.0 If a dict has a collection for a key, it is
serialized as a tuple.
.. versionadded:: 21.3.0
If a dict has a collection for a key, it is serialized as a tuple.
"""
attrs = fields(inst.__class__)
rv = dict_factory()
@ -205,22 +216,33 @@ def astuple(
Optionally recurse into other *attrs*-decorated classes.
:param inst: Instance of an *attrs*-decorated class.
:param bool recurse: Recurse into classes that are also *attrs*-decorated.
:param ~typing.Callable filter: A callable whose return code determines
whether an attribute or element is included (`True`) or dropped
(`False`). Is called with the `attrs.Attribute` as the first argument
and the value as the second argument.
:param ~typing.Callable tuple_factory: A callable to produce tuples from.
For example, to produce lists instead of tuples.
:param bool retain_collection_types: Do not convert to `list` or `dict`
when encountering an attribute which type is `tuple`, `dict` or `set`.
Only meaningful if *recurse* is `True`.
Args:
inst: Instance of an *attrs*-decorated class.
:rtype: return type of *tuple_factory*
recurse (bool):
Recurse into classes that are also *attrs*-decorated.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class.
filter (~typing.Callable):
A callable whose return code determines whether an attribute or
element is included (`True`) or dropped (`False`). Is called with
the `attrs.Attribute` as the first argument and the value as the
second argument.
tuple_factory (~typing.Callable):
A callable to produce tuples from. For example, to produce lists
instead of tuples.
retain_collection_types (bool):
Do not convert to `list` or `dict` when encountering an attribute
which type is `tuple`, `dict` or `set`. Only meaningful if
*recurse* is `True`.
Returns:
Return type of *tuple_factory*
Raises:
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class.
.. versionadded:: 16.2.0
"""
@ -305,10 +327,14 @@ def has(cls):
"""
Check whether *cls* is a class with *attrs* attributes.
:param type cls: Class to introspect.
:raise TypeError: If *cls* is not a class.
Args:
cls (type): Class to introspect.
:rtype: bool
Raises:
TypeError: If *cls* is not a class.
Returns:
bool:
"""
attrs = getattr(cls, "__attrs_attrs__", None)
if attrs is not None:
@ -337,20 +363,25 @@ def assoc(inst, **changes):
.. _`edge cases`: https://github.com/python-attrs/attrs/issues/251
:param inst: Instance of a class with *attrs* attributes.
:param changes: Keyword changes in the new copy.
Args:
inst: Instance of a class with *attrs* attributes.
:return: A copy of inst with *changes* incorporated.
changes: Keyword changes in the new copy.
:raise attrs.exceptions.AttrsAttributeNotFoundError: If *attr_name*
couldn't be found on *cls*.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class.
Returns:
A copy of inst with *changes* incorporated.
Raises:
attrs.exceptions.AttrsAttributeNotFoundError:
If *attr_name* couldn't be found on *cls*.
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class.
.. deprecated:: 17.1.0
Use `attrs.evolve` instead if you can.
This function will not be removed du to the slightly different approach
compared to `attrs.evolve`.
Use `attrs.evolve` instead if you can. This function will not be
removed du to the slightly different approach compared to
`attrs.evolve`, though.
"""
new = copy.copy(inst)
attrs = fields(inst.__class__)
@ -368,16 +399,24 @@ def evolve(*args, **changes):
Create a new instance, based on the first positional argument with
*changes* applied.
:param inst: Instance of a class with *attrs* attributes. *inst* must be
passed as a positional argument.
:param changes: Keyword changes in the new copy.
Args:
:return: A copy of inst with *changes* incorporated.
inst:
Instance of a class with *attrs* attributes. *inst* must be passed
as a positional argument.
:raise TypeError: If *attr_name* couldn't be found in the class
``__init__``.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class.
changes:
Keyword changes in the new copy.
Returns:
A copy of inst with *changes* incorporated.
Raises:
TypeError:
If *attr_name* couldn't be found in the class ``__init__``.
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class.
.. versionadded:: 17.1.0
.. deprecated:: 23.1.0
@ -425,25 +464,36 @@ def resolve_types(
other dictionaries in which to look up these names. See the docs of
`typing.get_type_hints` for more details.
:param type cls: Class to resolve.
:param dict | None globalns: Dictionary containing global variables.
:param dict | None localns: Dictionary containing local variables.
:param list | None attribs: List of attribs for the given class. This is
necessary when calling from inside a ``field_transformer`` since *cls*
is not an *attrs* class yet.
:param bool include_extras: Resolve more accurately, if possible. Pass
``include_extras`` to ``typing.get_hints``, if supported by the typing
module. On supported Python versions (3.9+), this resolves the types
more accurately.
Args:
cls (type): Class to resolve.
:raise TypeError: If *cls* is not a class.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class and you didn't pass any attribs.
:raise NameError: If types cannot be resolved because of missing variables.
globalns (dict | None): Dictionary containing global variables.
:returns: *cls* so you can use this function also as a class decorator.
Please note that you have to apply it **after** `attrs.define`. That
means the decorator has to come in the line **before** `attrs.define`.
localns (dict | None): Dictionary containing local variables.
attribs (list | None):
List of attribs for the given class. This is necessary when calling
from inside a ``field_transformer`` since *cls* is not an *attrs*
class yet.
include_extras (bool):
Resolve more accurately, if possible. Pass ``include_extras`` to
``typing.get_hints``, if supported by the typing module. On
supported Python versions (3.9+), this resolves the types more
accurately.
Raises:
TypeError: If *cls* is not a class.
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class and you didn't pass any attribs.
NameError: If types cannot be resolved because of missing variables.
Returns:
*cls* so you can use this function also as a class decorator. Please
note that you have to apply it **after** `attrs.define`. That means the
decorator has to come in the line **before** `attrs.define`.
.. versionadded:: 20.1.0
.. versionadded:: 21.1.0 *attribs*

View File

@ -123,114 +123,134 @@ def attrib(
Please consider using `attrs.field` in new code (``attr.ib`` will *never*
go away, though).
:param 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``.
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 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.
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.
The default can also be set using decorator notation as shown below.
The default can also be set using decorator notation as shown
below.
.. seealso:: `defaults`
.. seealso:: `defaults`
:param ~typing.Callable factory: Syntactic sugar for
``default=attr.Factory(factory)``.
factory (~typing.Callable):
Syntactic sugar for ``default=attr.Factory(factory)``.
:param ~typing.Callable | list[~typing.Callable] validator: 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.
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.
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.
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`.
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.
The validator can also be set using decorator notation as shown
below.
.. seealso:: :ref:`validators`
.. seealso:: :ref:`validators`
:param bool | ~typing.Callable repr: 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).
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).
:param bool | ~typing.Callable eq: 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.
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`
.. seealso:: `comparison`
:param bool | ~typing.Callable order: 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.
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`
.. seealso:: `comparison`
:param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the
same value. Must not be mixed with *eq* or *order*.
cmp(bool | ~typing.Callable):
Setting *cmp* is equivalent to setting *eq* and *order* to the same
value. Must not be mixed with *eq* or *order*.
.. seealso:: `comparison`
:type cmp: a `bool` or a `callable`.
.. seealso:: `comparison`
:param bool | None hash: 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*.
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`
:param bool init: 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:: `hashing`
.. seealso:: `init`
:param typing.Callable converter: `callable` that is called by
*attrs*-generated ``__init__`` methods to convert attribute's value to
the desired format. It is given the passed-in value, and 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.
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:: :ref:`converters`
:param dict | None metadata: An arbitrary mapping, to be used by
third-party components. See `extending-metadata`.
.. seealso:: `init`
:param 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 backward compatibility. Regardless of the
approach used, the type will be stored on ``Attribute.type``.
converter (typing.Callable(): `callable` that is called by
*attrs*-generated ``__init__`` methods to convert attribute's value
to the desired format. It is given the passed-in value, and 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.
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>`.
:param bool kw_only: Make this attribute keyword-only in the generated
``__init__`` (if ``init`` is `False`, this parameter is ignored).
:param on_setattr: 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 `attr.s`.
:type on_setattr: ~typing.Callable | list[~typing.Callable] | None |
typing.Literal[attrs.setters.NO_OP]
:param str | None alias: Override this attribute's parameter name in the
generated ``__init__`` method. If left `None`, default to ``name``
stripped of leading underscores. See `private-attributes`.
.. seealso:: :ref:`converters`
metadata (dict | None):
An arbitrary mapping, to be used by third-party components.
.. 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 `attr.s`.
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:: 15.2.0 *convert*
.. versionadded:: 16.3.0 *metadata*
@ -239,8 +259,9 @@ def attrib(
*hash* is `None` and therefore mirrors *eq* by default.
.. versionadded:: 17.3.0 *type*
.. deprecated:: 17.4.0 *convert*
.. versionadded:: 17.4.0 *converter* as a replacement for the deprecated
*convert* to achieve consistency with other noun-based arguments.
.. versionadded:: 17.4.0
*converter* as a replacement for the deprecated *convert* to achieve
consistency with other noun-based arguments.
.. versionadded:: 18.1.0
``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``.
.. versionadded:: 18.2.0 *kw_only*
@ -1334,227 +1355,266 @@ def attrs(
Consider using `attrs.define` / `attrs.frozen` in new code (``attr.s`` will
*never* go away, though).
:param these: A dictionary of name to `attr.ib` 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.
Args:
these (dict[str, object]):
A dictionary of name to the (private) return value of `attr.ib`
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.
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*.
The order is deduced from the order of the attributes inside
*these*.
:type these: `dict` of `str` to `attr.ib`
repr_ns (str):
When using nested classes, there was no way in Python 2 to
automatically detect that. This argument allows to set a custom
name for a more meaningful ``repr`` output. This argument is
pointless in Python 3 and is therefore deprecated.
:param str repr_ns: When using nested classes, there was no way in Python 2
to automatically detect that. This argument allows to set a custom
name for a more meaningful ``repr`` output. This argument
is pointless in Python 3 and is therefore deprecated.
:param bool auto_detect: Instead of setting the *init*, *repr*, *eq*,
*order*, 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).
auto_detect (bool):
Instead of setting the *init*, *repr*, *eq*, *order*, 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).
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).
.. warning::
.. warning::
If you prevent *attrs* from creating the ordering methods for you
(``order=False``, for example, by implementing ``__le__``), it
becomes *your* responsibility to make sure its ordering is sound.
The best way is to use the `functools.total_ordering` decorator.
If you prevent *attrs* from creating the ordering methods for
you (``order=False``, for example, by implementing ``__le__``),
it becomes *your* responsibility to make sure its ordering is
sound. The best way is to use the `functools.total_ordering`
decorator.
Passing `True` or `False` to *init*, *repr*, *eq*, *order*, *cmp*,
or *hash* overrides whatever *auto_detect* would determine.
Passing `True` or `False` to *init*, *repr*, *eq*, *order*, *cmp*,
or *hash* overrides whatever *auto_detect* would determine.
:param bool repr: Create a ``__repr__`` method with a human readable
representation of *attrs* attributes..
:param bool str: Create a ``__str__`` method that is identical to
``__repr__``. This is usually not necessary except for `Exception`\ s.
:param bool | None eq: If `True` or `None` (default), add ``__eq__``
and ``__ne__`` methods that check two instances for equality.
repr(bool):
Create a ``__repr__`` method with a human readable representation
of *attrs* attributes..
They compare the instances as if they were tuples of their *attrs*
attributes if and only if the types of both classes are *identical*!
str (bool):
Create a ``__str__`` method that is identical to ``__repr__``. This
is usually not necessary except for `Exception`\ s.
.. seealso:: `comparison`
:param bool | None order: If `True`, add ``__lt__``, ``__le__``,
``__gt__``, and ``__ge__`` methods that behave like *eq* above and
allow instances to be ordered. If `None` (default) mirror value of
*eq*.
eq (bool | None):
If `True` or `None` (default), add ``__eq__`` and ``__ne__``
methods that check two instances for equality.
.. seealso:: `comparison`
:param bool | None cmp: Setting *cmp* is equivalent to setting *eq* and
*order* to the same value. Must not be mixed with *eq* or *order*.
They compare the instances as if they were tuples of their *attrs*
attributes if and only if the types of both classes are
*identical*!
.. seealso:: `comparison`
:param bool | None unsafe_hash: If `None` (default), the ``__hash__``
method is generated according how *eq* and *frozen* are set.
.. seealso:: `comparison`
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 base class is
``object``, this means it will fall back to id-based hashing.).
order (bool | None):
If `True`, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``
methods that behave like *eq* above and allow instances to be
ordered. If `None` (default) mirror value of *eq*.
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:: `comparison`
.. seealso::
cmp (bool | None):
Setting *cmp* is equivalent to setting *eq* and *order* to the same
value. Must not be mixed with *eq* or *order*.
- 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.
.. seealso:: `comparison`
:param bool | None hash: Alias for *unsafe_hash*. *unsafe_hash* takes
precedence.
:param bool init: 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). If a ``__attrs_pre_init__``
method exists on the class, it will be called before the class is
initialized. If a ``__attrs_post_init__`` method exists on the class,
it will be called after the class is fully initialized.
unsafe_hash (bool | None):
If `None` (default), the ``__hash__`` method is generated according
how *eq* and *frozen* are set.
If ``init`` is `False`, an ``__attrs_init__`` method will be injected
instead. This allows you to define a custom ``__init__`` method that
can do pre-init work such as ``super().__init__()``, and then call
``__attrs_init__()`` and ``__attrs_post_init__()``.
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 base
class is ``object``, this means it will fall back to id-based
hashing.).
.. seealso:: `init`
:param bool slots: 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>`.
:param bool frozen: Make instances immutable after initialization. If
someone attempts to modify a frozen instance,
`attrs.exceptions.FrozenInstanceError` is raised.
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.
.. note::
.. seealso::
1. This is achieved by installing a custom ``__setattr__`` method
on your class, so you can't implement your own.
- 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.
2. True immutability is impossible in Python.
hash (bool | None):
Alias for *unsafe_hash*. *unsafe_hash* takes precedence.
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``.
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). If a
``__attrs_pre_init__`` method exists on the class, it will be
called before the class is initialized. If a
``__attrs_post_init__`` method exists on the class, it will be
called after the class is fully initialized.
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)``.
If ``init`` is `False`, an ``__attrs_init__`` method will be
injected instead. This allows you to define a custom ``__init__``
method that can do pre-init work such as ``super().__init__()``,
and then call ``__attrs_init__()`` and ``__attrs_post_init__()``.
5. Subclasses of a frozen class are frozen too.
.. seealso:: `init`
:param bool weakref_slot: Make instances weak-referenceable. This has no
effect unless ``slots`` is also enabled.
:param bool auto_attribs: If `True`, collect :pep:`526`-annotated
attributes from the class body.
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>`.
In this case, you **must** annotate every field. If *attrs* encounters
a field that is set to an `attr.ib` but lacks a type annotation, an
`attrs.exceptions.UnannotatedAttributeError` is raised. Use
``field_name: typing.Any = attr.ib(...)`` if you don't want to set a
type.
frozen (bool):
Make instances immutable after initialization. If someone attempts
to modify a frozen instance, `attrs.exceptions.FrozenInstanceError`
is raised.
If you assign a value to those attributes (for example, ``x: int =
42``), that value becomes the default value like if it were passed
using ``attr.ib(default=42)``. Passing an instance of `attrs.Factory`
also works as expected in most cases (see warning below).
.. note::
Attributes annotated as `typing.ClassVar`, and attributes that are
neither annotated nor set to an `attr.ib` are **ignored**.
1. This is achieved by installing a custom ``__setattr__``
method on your class, so you can't implement your own.
.. warning::
2. True immutability is impossible in Python.
For features that use the attribute name to create decorators (for
example, :ref:`validators <validators>`), you still *must* assign
`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.
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``.
:param bool kw_only: Make all attributes keyword-only in the generated
``__init__`` (if *init* is `False`, this parameter is ignored).
:param bool cache_hash: 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.
:param bool auto_exc: If the class subclasses `BaseException` (which
implicitly includes any subclass of any exception), the following
happens to behave like a well-behaved Python exceptions class:
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)``.
- the values for *eq*, *order*, and *hash* are ignored and the
instances compare and hash by the instance's ids (N.B. *attrs* will
*not* remove existing implementations of ``__hash__`` or the equality
methods. It just won't add own ones.),
- 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.
:param bool collect_by_mro: Setting this to `True` fixes the way *attrs*
collects attributes from base classes. The default behavior is
incorrect in certain cases of multiple inheritance. It should be on by
default, but is kept off for backwards-compatibility.
5. Subclasses of a frozen class are frozen too.
.. seealso::
Issue `#428 <https://github.com/python-attrs/attrs/issues/428>`_
weakref_slot (bool):
Make instances weak-referenceable. This has no effect unless
``slots`` is also enabled.
:param bool | None getstate_setstate:
.. note::
This is usually only interesting for slotted classes and you should
probably just set *auto_detect* to `True`.
auto_attribs (bool):
If `True`, collect :pep:`526`-annotated attributes from the class
body.
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.
In this case, you **must** annotate every field. If *attrs*
encounters a field that is set to an `attr.ib` but lacks a type
annotation, an `attrs.exceptions.UnannotatedAttributeError` is
raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't
want to set a type.
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).
If you assign a value to those attributes (for example, ``x: int =
42``), that value becomes the default value like if it were passed
using ``attr.ib(default=42)``. Passing an instance of
`attrs.Factory` also works as expected in most cases (see warning
below).
:param on_setattr: 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.
Attributes annotated as `typing.ClassVar`, and attributes that are
neither annotated nor set to an `attr.ib` are **ignored**.
If no exception is raised, the attribute is set to the return value of
the callable.
.. warning::
If a list of callables is passed, they're automatically wrapped in an
`attrs.setters.pipe`.
:type on_setattr: ~typing.Callable | list[~typing.Callable] | None |
typing.Literal[attrs.setters.NO_OP]
For features that use the attribute name to create decorators
(for example, :ref:`validators <validators>`), you still *must*
assign `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.
:param ~typing.Callable | None field_transformer:
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.
kw_only (bool):
Make all attributes keyword-only in the generated ``__init__`` (if
*init* is `False`, this parameter is ignored).
.. seealso:: `transform-fields`
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.
:param bool match_args:
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.
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 exceptions class:
- the values for *eq*, *order*, and *hash* are ignored and the
instances compare and hash by the instance's ids (N.B. *attrs*
will *not* remove existing implementations of ``__hash__`` or the
equality methods. It just won't add own ones.),
- 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.
collect_by_mro (bool):
Setting this to `True` fixes the way *attrs* collects attributes
from base classes. The default behavior is incorrect in certain
cases of multiple inheritance. It should be on by default, but is
kept off for backwards-compatibility.
.. seealso::
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).
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`.
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.
.. versionadded:: 16.0.0 *slots*
.. versionadded:: 16.1.0 *frozen*
@ -2030,13 +2090,17 @@ def fields(cls):
The tuple also allows accessing the fields by their names (see below for
examples).
:param type cls: Class to introspect.
Args:
cls (type): Class to introspect.
:raise TypeError: If *cls* is not a class.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class.
Raises:
TypeError: If *cls* is not a class.
:rtype: tuple (with name accessors) of `attrs.Attribute`
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class.
Returns:
tuple (with name accessors) of `attrs.Attribute`
.. versionchanged:: 16.2.0 Returned tuple allows accessing the fields
by name.
@ -2067,16 +2131,20 @@ def fields(cls):
def fields_dict(cls):
"""
Return an ordered dictionary of *attrs* attributes for a class, whose
keys are the attribute names.
Return an ordered dictionary of *attrs* attributes for a class, whose keys
are the attribute names.
:param type cls: Class to introspect.
Args:
cls (type): Class to introspect.
:raise TypeError: If *cls* is not a class.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
class.
Raises:
TypeError: If *cls* is not a class.
:rtype: dict
attrs.exceptions.NotAnAttrsClassError:
If *cls* is not an *attrs* class.
Returns:
dict[str, attrs.Attribute]: Dict of attribute name to definition
.. versionadded:: 18.1.0
"""
@ -2096,7 +2164,8 @@ def validate(inst):
Leaves all exceptions through.
:param inst: Instance of a class with *attrs* attributes.
Args:
inst: Instance of a class with *attrs* attributes.
"""
if _config._run_validators is False:
return
@ -2913,7 +2982,8 @@ class _CountingAttr:
Returns *meth* unchanged.
:raises DefaultAlreadySetError: If default has been set before.
Raises:
DefaultAlreadySetError: If default has been set before.
.. versionadded:: 17.1.0
"""
@ -2935,10 +3005,14 @@ class Factory:
If passed as the default value to `attrs.field`, the factory is used to
generate a new value.
:param typing.Callable factory: A callable that takes either none or
exactly one mandatory positional argument depending on *takes_self*.
:param bool takes_self: Pass the partially initialized instance that is
being initialized as a positional argument.
Args:
factory (typing.Callable):
A callable that takes either none or exactly one mandatory
positional argument depending on *takes_self*.
takes_self (bool):
Pass the partially initialized instance that is being initialized
as a positional argument.
.. versionadded:: 17.1.0 *takes_self*
"""
@ -2988,24 +3062,26 @@ def make_class(
r"""
A quick way to create a new class called *name* with *attrs*.
:param str name: The name for the new class.
Args:
name (str): The name for the new class.
:param list | dict attrs: A list of names or a dictionary of mappings of
names to `attr.ib`\ s / `attrs.field`\ s.
attrs( list | dict):
A list of names or a dictionary of mappings of names to `attr.ib`\
s / `attrs.field`\ s.
The order is deduced from the order of the names or attributes inside
*attrs*. Otherwise the order of the definition of the attributes is
used.
The order is deduced from the order of the names or attributes
inside *attrs*. Otherwise the order of the definition of the
attributes is used.
:param tuple bases: Classes that the new class will subclass.
bases (tuple[type, ...]): Classes that the new class will subclass.
:param dict class_body: An optional dictionary of class attributes for the
new class.
class_body (dict):
An optional dictionary of class attributes for the new class.
:param attributes_arguments: Passed unmodified to `attr.s`.
attributes_arguments: Passed unmodified to `attr.s`.
:return: A new class with *attrs*.
:rtype: type
Returns:
type: A new class with *attrs*.
.. versionadded:: 17.1.0 *bases*
.. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained.
@ -3087,8 +3163,9 @@ def and_(*validators):
When called on a value, it runs all wrapped validators.
:param ~collections.abc.Iterable[typing.Callable] validators: Arbitrary
number of validators.
Args:
validators (~collections.abc.Iterable[typing.Callable]):
Arbitrary number of validators.
.. versionadded:: 17.1.0
"""
@ -3113,8 +3190,8 @@ def pipe(*converters):
Type annotations will be inferred from the wrapped converters', if they
have any.
:param ~collections.abc.Iterable[typing.Callable] converters: Arbitrary
number of converters.
converters (~collections.abc.Iterable[typing.Callable]):
Arbitrary number of converters.
.. versionadded:: 20.1.0
"""

View File

@ -70,13 +70,15 @@ def define(
Please note that these are all defaults and you can change them as you
wish.
:param bool | None auto_attribs: If set to `True` or `False`, it behaves
exactly like `attr.s`. If left `None`, `attr.s` will try to guess:
Args:
auto_attribs (bool | None):
If set to `True` or `False`, it behaves exactly like `attr.s`. If
left `None`, `attr.s` will try to guess:
1. If any attributes are annotated and no unannotated `attrs.fields`\ s
are found, it assumes *auto_attribs=True*.
2. Otherwise it assumes *auto_attribs=False* and tries to collect
`attrs.fields`\ s.
1. If any attributes are annotated and no unannotated
`attrs.fields`\ s are found, it assumes *auto_attribs=True*.
2. Otherwise it assumes *auto_attribs=False* and tries to collect
`attrs.fields`\ s.
For now, please refer to `attr.s` for the rest of the parameters.

View File

@ -27,8 +27,9 @@ def optional(converter):
Type annotations will be inferred from the wrapped converter's, if it has
any.
:param typing.Callable converter: the converter that is used for non-`None`
values.
Args:
converter (typing.Callable):
the converter that is used for non-`None` values.
.. versionadded:: 17.1.0
"""
@ -56,16 +57,24 @@ def default_if_none(default=NOTHING, factory=None):
A converter that allows to replace `None` values by *default* or the result
of *factory*.
:param default: Value to be used if `None` is passed. Passing an instance
of `attrs.Factory` is supported, however the ``takes_self`` option is
*not*.
:param typing.Callable factory: A callable that takes no parameters whose
result is used if `None` is passed.
Args:
default:
Value to be used if `None` is passed. Passing an instance of
`attrs.Factory` is supported, however the ``takes_self`` option is
*not*.
:raises TypeError: If **neither** *default* or *factory* is passed.
:raises TypeError: If **both** *default* and *factory* are passed.
:raises ValueError: If an instance of `attrs.Factory` is passed with
``takes_self=True``.
factory (typing.Callable):
A callable that takes no parameters whose result is used if `None`
is passed.
Raises:
TypeError: If **neither** *default* or *factory* is passed.
TypeError: If **both** *default* and *factory* are passed.
ValueError:
If an instance of `attrs.Factory` is passed with
``takes_self=True``.
.. versionadded:: 18.2.0
"""
@ -125,7 +134,8 @@ def to_bool(val):
- ``"0"``
- ``0``
:raises ValueError: for any other value.
Raises:
ValueError: For any other value.
.. versionadded:: 21.3.0
"""

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
"""
Commonly useful filters for `attr.asdict`.
Commonly useful filters for `attrs.asdict` and `attrs.astuple`.
"""
from ._make import Attribute
@ -20,13 +20,16 @@ def _split_what(what):
def include(*what):
"""
Include *what*.
Create a filter that only allows *what*.
:param what: What to include.
:type what: `list` of classes `type`, field names `str` or
`attrs.Attribute`\\ s
Args:
what (list[type, str, attrs.Attribute]):
What to include. Can be a type, a name, or an attribute.
:rtype: `callable`
Returns:
Callable:
A callable that can be passed to `attrs.asdict`'s and
`attrs.astuple`'s *filter* argument.
.. versionchanged:: 23.1.0 Accept strings with field names.
"""
@ -44,13 +47,16 @@ def include(*what):
def exclude(*what):
"""
Exclude *what*.
Create a filters that does **not** allow *what*.
:param what: What to exclude.
:type what: `list` of classes `type`, field names `str` or
`attrs.Attribute`\\ s.
Args:
what (list[type, str, attrs.Attribute]):
What to exclude. Can be a type, a name, or an attribute.
:rtype: `callable`
Returns:
Callable:
A callable that can be passed to `attrs.asdict`'s and
`attrs.astuple`'s *filter* argument.
.. versionchanged:: 23.3.0 Accept field name string as input argument
"""

View File

@ -46,8 +46,8 @@ def set_disabled(disabled):
By default, they are run.
:param disabled: If `True`, disable running all validators.
:type disabled: bool
Args:
disabled (bool): If `True`, disable running all validators.
.. warning::
@ -62,8 +62,8 @@ def get_disabled():
"""
Return a bool indicating whether validators are currently disabled or not.
:return: `True` if validators are currently disabled.
:rtype: bool
Returns:
bool:`True` if validators are currently disabled.
.. versionadded:: 21.3.0
"""
@ -115,10 +115,13 @@ def instance_of(type):
wrong type for this particular attribute (checks are performed using
`isinstance` therefore it's also valid to pass a tuple of types).
:param type | tuple[type] type: The type to check for.
Args:
type (type | tuple[type]): The type to check for.
:raises TypeError: With a human readable error message, the attribute (of
type `attrs.Attribute`), the expected type, and the value it got.
Raises:
TypeError:
With a human readable error message, the attribute (of type
`attrs.Attribute`), the expected type, and the value it got.
"""
return _InstanceOfValidator(type)
@ -150,13 +153,18 @@ def matches_re(regex, flags=0, func=None):
A validator that raises `ValueError` if the initializer is called with a
string that doesn't match *regex*.
:param regex: a regex string or precompiled pattern to match against
:param int flags: flags that will be passed to the underlying re function
(default 0)
:param typing.Callable func: which underlying `re` function to call. Valid
options are `re.fullmatch`, `re.search`, and `re.match`; the default
`None` means `re.fullmatch`. For performance reasons, the pattern is
always precompiled using `re.compile`.
Args:
regex (str, re.Pattern):
A regex string or precompiled pattern to match against
flags (int):
Flags that will be passed to the underlying re function (default 0)
func (typing.Callable):
Which underlying `re` function to call. Valid options are
`re.fullmatch`, `re.search`, and `re.match`; the default `None`
means `re.fullmatch`. For performance reasons, the pattern is
always precompiled using `re.compile`.
.. versionadded:: 19.2.0
.. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern.
@ -208,10 +216,10 @@ def optional(validator):
which can be set to `None` in addition to satisfying the requirements of
the sub-validator.
:param validator: A validator (or validators) that is used for non-`None`
values.
:type validator: typing.Callable | tuple[typing.Callable] |
list[typing.Callable]
Args:
validator
(typing.Callable | tuple[typing.Callable] | list[typing.Callable]):
A validator (or validators) that is used for non-`None` values.
.. versionadded:: 15.1.0
.. versionchanged:: 17.1.0 *validator* can be a list of validators.
@ -248,16 +256,17 @@ class _InValidator:
def in_(options):
"""
A validator that raises a `ValueError` if the initializer is called
with a value that does not belong in the options provided. The check is
performed using ``value in options``.
A validator that raises a `ValueError` if the initializer is called with a
value that does not belong in the options provided. The check is performed
using ``value in options``, so *options* has to support that operation.
:param options: Allowed options.
:type options: list, tuple, `enum.Enum`, ...
Args:
options: Allowed options.
:raises ValueError: With a human readable error message, the attribute (of
type `attrs.Attribute`), the expected options, and the value it
got.
Raises:
ValueError:
With a human readable error message, the attribute (of type
`attrs.Attribute`), the expected options, and the value it got.
.. versionadded:: 17.1.0
.. versionchanged:: 22.1.0
@ -293,14 +302,15 @@ class _IsCallableValidator:
def is_callable():
"""
A validator that raises a `attrs.exceptions.NotCallableError` if the
initializer is called with a value for this particular attribute
that is not callable.
initializer is called with a value for this particular attribute that is
not callable.
.. versionadded:: 19.1.0
:raises attrs.exceptions.NotCallableError: With a human readable error
message containing the attribute (`attrs.Attribute`) name,
and the value it got.
Raises:
attrs.exceptions.NotCallableError:
With a human readable error message containing the attribute
(`attrs.Attribute`) name, and the value it got.
"""
return _IsCallableValidator()
@ -338,13 +348,16 @@ def deep_iterable(member_validator, iterable_validator=None):
"""
A validator that performs deep validation of an iterable.
:param member_validator: Validator(s) to apply to iterable members
:param iterable_validator: Validator to apply to iterable itself
(optional)
Args:
member_validator: Validator to apply to iterable members.
iterable_validator:
Validator to apply to iterable itself (optional).
Raises
TypeError: if any sub-validators fail
.. versionadded:: 19.1.0
:raises TypeError: if any sub-validators fail
"""
if isinstance(member_validator, (list, tuple)):
member_validator = and_(*member_validator)
@ -376,14 +389,18 @@ def deep_mapping(key_validator, value_validator, mapping_validator=None):
"""
A validator that performs deep validation of a dictionary.
:param key_validator: Validator to apply to dictionary keys
:param value_validator: Validator to apply to dictionary values
:param mapping_validator: Validator to apply to top-level mapping
attribute (optional)
Args:
key_validator: Validator to apply to dictionary keys.
value_validator: Validator to apply to dictionary values.
mapping_validator:
Validator to apply to top-level mapping attribute (optional).
.. versionadded:: 19.1.0
:raises TypeError: if any sub-validators fail
Raises:
TypeError: if any sub-validators fail
"""
return _DeepMapping(key_validator, value_validator, mapping_validator)
@ -408,10 +425,13 @@ class _NumberValidator:
def lt(val):
"""
A validator that raises `ValueError` if the initializer is called
with a number larger or equal to *val*.
A validator that raises `ValueError` if the initializer is called with a
number larger or equal to *val*.
:param val: Exclusive upper bound for values
The validator uses `operator.lt` to compare the values.
Args:
val: Exclusive upper bound for values.
.. versionadded:: 21.3.0
"""
@ -420,10 +440,13 @@ def lt(val):
def le(val):
"""
A validator that raises `ValueError` if the initializer is called
with a number greater than *val*.
A validator that raises `ValueError` if the initializer is called with a
number greater than *val*.
:param val: Inclusive upper bound for values
The validator uses `operator.le` to compare the values.
Args:
val: Inclusive upper bound for values.
.. versionadded:: 21.3.0
"""
@ -432,10 +455,13 @@ def le(val):
def ge(val):
"""
A validator that raises `ValueError` if the initializer is called
with a number smaller than *val*.
A validator that raises `ValueError` if the initializer is called with a
number smaller than *val*.
:param val: Inclusive lower bound for values
The validator uses `operator.ge` to compare the values.
Args:
val: Inclusive lower bound for values
.. versionadded:: 21.3.0
"""
@ -444,10 +470,13 @@ def ge(val):
def gt(val):
"""
A validator that raises `ValueError` if the initializer is called
with a number smaller or equal to *val*.
A validator that raises `ValueError` if the initializer is called with a
number smaller or equal to *val*.
:param val: Exclusive lower bound for values
The validator uses `operator.ge` to compare the values.
Args:
val: Exclusive lower bound for values
.. versionadded:: 21.3.0
"""
@ -475,7 +504,8 @@ def max_len(length):
A validator that raises `ValueError` if the initializer is called
with a string or iterable that is longer than *length*.
:param int length: Maximum length of the string or iterable
Args:
length (int): Maximum length of the string or iterable
.. versionadded:: 21.3.0
"""
@ -503,7 +533,8 @@ def min_len(length):
A validator that raises `ValueError` if the initializer is called
with a string or iterable that is shorter than *length*.
:param int length: Minimum length of the string or iterable
Args:
length (int): Minimum length of the string or iterable
.. versionadded:: 22.1.0
"""
@ -533,16 +564,17 @@ class _SubclassOfValidator:
def _subclass_of(type):
"""
A validator that raises a `TypeError` if the initializer is called
with a wrong type for this particular attribute (checks are performed using
A validator that raises a `TypeError` if the initializer is called with a
wrong type for this particular attribute (checks are performed using
`issubclass` therefore it's also valid to pass a tuple of types).
:param type: The type to check for.
:type type: type or tuple of types
Args:
type (type | tuple[type, ...]): The type(s) to check for.
:raises TypeError: With a human readable error message, the attribute
(of type `attrs.Attribute`), the expected type, and the value it
got.
Raises:
TypeError:
With a human readable error message, the attribute (of type
`attrs.Attribute`), the expected type, and the value it got.
"""
return _SubclassOfValidator(type)
@ -594,19 +626,22 @@ def not_(validator, *, msg=None, exc_types=(ValueError, TypeError)):
Intended to be used with existing validators to compose logic without
needing to create inverted variants, for example, ``not_(in_(...))``.
:param validator: A validator to be logically inverted.
:param msg: Message to raise if validator fails.
Formatted with keys ``exc_types`` and ``validator``.
:type msg: str
:param exc_types: Exception type(s) to capture.
Other types raised by child validators will not be intercepted and
pass through.
Args:
validator: A validator to be logically inverted.
:raises ValueError: With a human readable error message,
the attribute (of type `attrs.Attribute`),
the validator that failed to raise an exception,
the value it got,
and the expected exception types.
msg (str):
Message to raise if validator fails. Formatted with keys
``exc_types`` and ``validator``.
exc_types (tuple[type, ...]):
Exception type(s) to capture. Other types raised by child
validators will not be intercepted and pass through.
Raises:
ValueError:
With a human readable error message, the attribute (of type
`attrs.Attribute`), the validator that failed to raise an
exception, the value it got, and the expected exception types.
.. versionadded:: 22.2.0
"""
@ -641,15 +676,18 @@ def or_(*validators):
"""
A validator that composes multiple validators into one.
When called on a value, it runs all wrapped validators until one of them
is satisfied.
When called on a value, it runs all wrapped validators until one of them is
satisfied.
:param ~collections.abc.Iterable[typing.Callable] validators: Arbitrary
number of validators.
Args:
validators (~collections.abc.Iterable[typing.Callable]):
Arbitrary number of validators.
:raises ValueError: If no validator is satisfied. Raised with a
human-readable error message listing all the wrapped validators and
the value that failed all of them.
Raises:
ValueError:
If no validator is satisfied. Raised with a human-readable error
message listing all the wrapped validators and the value that
failed all of them.
.. versionadded:: 24.1.0
"""