docs: style improvements

This commit is contained in:
Hynek Schlawack 2024-03-16 16:22:58 +01:00
parent d4e98b1b8a
commit f590f44cfd
No known key found for this signature in database
15 changed files with 101 additions and 101 deletions

View File

@ -66,7 +66,7 @@ See https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md#chan
[#1068](https://github.com/python-attrs/attrs/issues/1068)
- `attrs.has()` and `attrs.fields()` now handle generic classes correctly.
[#1079](https://github.com/python-attrs/attrs/issues/1079)
- Fix frozen exception classes when raised within e.g. `contextlib.contextmanager`, which mutates their `__traceback__` attributes.
- Fix frozen exception classes when raised within, for example, `contextlib.contextmanager`, which mutates their `__traceback__` attributes.
[#1081](https://github.com/python-attrs/attrs/issues/1081)
- `@frozen` now works with type checkers that implement [PEP-681](https://peps.python.org/pep-0681/) (ex. [pyright](https://github.com/microsoft/pyright/)).
[#1084](https://github.com/python-attrs/attrs/issues/1084)
@ -113,7 +113,7 @@ See https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md#chan
Get `__init__` signatures matching any taste, peculiar or plain!
The [PEP 681 compatible](https://peps.python.org/pep-0681/#field-specifier-parameters) *alias* option can be use to override private attribute name mangling, or add other arbitrary field argument name overrides.
[#950](https://github.com/python-attrs/attrs/issues/950)
- `attrs.NOTHING` is now an enum value, making it possible to use with e.g. [`typing.Literal`](https://docs.python.org/3/library/typing.html#typing.Literal).
- `attrs.NOTHING` is now an enum value, making it possible to use with, for example, [`typing.Literal`](https://docs.python.org/3/library/typing.html#typing.Literal).
[#983](https://github.com/python-attrs/attrs/issues/983)
- Added missing re-import of `attr.AttrsInstance` to the `attrs` namespace.
[#987](https://github.com/python-attrs/attrs/issues/987)
@ -195,7 +195,7 @@ See https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md#chan
### Backward-incompatible Changes
- When using `@define`, converters are now run by default when setting an attribute on an instance -- additionally to validators.
I.e. the new default is `on_setattr=[attrs.setters.convert, attrs.setters.validate]`.
Meaning: the new default is `on_setattr=[attrs.setters.convert, attrs.setters.validate]`.
This is unfortunately a breaking change, but it was an oversight, impossible to raise a `DeprecationWarning` about, and it's better to fix it now while the APIs are very fresh with few users.
[#835](https://github.com/python-attrs/attrs/issues/835),
@ -494,7 +494,7 @@ See https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md#chan
- `attrs` can now automatically detect your own implementations and infer `init=False`, `repr=False`, `eq=False`, `order=False`, and `hash=False` if you set `@attr.s(auto_detect=True)`.
`attrs` will ignore inherited methods.
If the argument implies more than one method (e.g. `eq=True` creates both `__eq__` and `__ne__`), it's enough for *one* of them to exist and `attrs` will create *neither*.
If the argument implies more than one method (for example, `eq=True` creates both `__eq__` and `__ne__`), it's enough for *one* of them to exist and `attrs` will create *neither*.
This feature requires Python 3.
[#607](https://github.com/python-attrs/attrs/issues/607)
@ -727,7 +727,7 @@ See https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md#chan
[#290](https://github.com/python-attrs/attrs/issues/290),
[#349](https://github.com/python-attrs/attrs/issues/349)
- The order of attributes that are passed into `attr.make_class()` or the *these* argument of `@attr.s()` is now retained if the dictionary is ordered (i.e. `dict` on Python 3.6 and later, `collections.OrderedDict` otherwise).
- The order of attributes that are passed into `attr.make_class()` or the *these* argument of `@attr.s()` is now retained if the dictionary is ordered (in other words: `dict` on Python 3.6 and later, `collections.OrderedDict` otherwise).
Before, the order was always determined by the order in which the attributes have been defined which may not be desirable when creating classes programmatically.
@ -1105,7 +1105,7 @@ To encourage more participation, the project has also been moved into a [dedicat
### Changes:
- Added a `convert` argument to `attr.ib`, which allows specifying a function to run on arguments.
This allows for simple type conversions, e.g. with `attr.ib(convert=int)`.
This allows for simple type conversions, for example, with `attr.ib(convert=int)`.
[#26](https://github.com/python-attrs/attrs/issues/26)
- Speed up object creation when attribute validators are used.
[#28](https://github.com/python-attrs/attrs/issues/28)

View File

@ -6,7 +6,7 @@ import pytest
from hypothesis import HealthCheck, settings
from attr._compat import PY310
from attr._compat import PY_3_10_PLUS
@pytest.fixture(name="slots", params=(True, False))
@ -32,5 +32,5 @@ def pytest_configure(config):
collect_ignore = []
if not PY310:
if not PY_3_10_PLUS:
collect_ignore.extend(["tests/test_pattern_matching.py"])

View File

@ -11,7 +11,7 @@ If you're confused by the many names, please check out `names` for clarification
- The classic ``attr`` that powers the venerable `attr.s` and `attr.ib`.
- The newer ``attrs`` that only contains most modern APIs and relies on `attrs.define` and `attrs.field` to define your classes.
Additionally it offers some ``attr`` APIs with nicer defaults (e.g. `attrs.asdict`).
Additionally it offers some ``attr`` APIs with nicer defaults (for example, `attrs.asdict`).
The ``attrs`` namespace is built *on top of* ``attr`` -- which will *never* go away -- and is just as stable, since it doesn't constitute a rewrite.
To keep repetition low and this document at a reasonable size, the ``attr`` namespace is `documented on a separate page <api-attr>`, though.

View File

@ -569,7 +569,7 @@ AutoC(l=[], x=1, foo='every attrib needs a type if auto_attribs=True', bar=None)
The generated `__init__` method will have an attribute called `__annotations__` that contains this type information.
If your annotations contain strings (e.g. forward references),
If your annotations contain strings (for example, forward references),
you can resolve these after all references have been defined by using {func}`attrs.resolve_types`.
This will replace the *type* attribute in the respective fields.

View File

@ -214,7 +214,7 @@ For example, let's assume that you really don't like floats:
Data(a=42, c='spam')
```
A more realistic example would be to automatically convert data that you, e.g., load from JSON:
A more realistic example would be to automatically convert data that you, for example, load from JSON:
```{doctest}
>>> from datetime import datetime

View File

@ -64,7 +64,7 @@ Once constructed, frozen instances don't differ in any way from regular ones exc
### Dict Classes
Dict classes -- i.e. regular classes -- simply assign the value directly into the class' eponymous `__dict__` (and there's nothing we can do to stop the user to do the same).
Dict classes -- that is: regular classes -- simply assign the value directly into the class' eponymous `__dict__` (and there's nothing we can do to stop the user to do the same).
The performance impact is negligible.
@ -95,9 +95,9 @@ Pick what's more important to you.
### Summary
You should avoid instantiating lots of frozen slotted classes (i.e. `@frozen`) in performance-critical code.
You should avoid instantiating lots of frozen slotted classes (meaning: `@frozen`) in performance-critical code.
Frozen dict classes have barely a performance impact, unfrozen slotted classes are even *faster* than unfrozen dict classes (i.e. regular classes).
Frozen dict classes have barely a performance impact, unfrozen slotted classes are even *faster* than unfrozen dict classes (meaning: regular classes).
(how-slotted-cached_property)=

View File

@ -370,7 +370,7 @@ For that purpose, *attrs* offers the following options:
- `__attrs_post_init__` is automatically detected and run *after* *attrs* is done initializing your instance.
This is useful if you want to derive some attribute from others or perform some kind of validation over the whole instance.
- `__attrs_init__` is written and attached to your class *instead* of `__init__`, if *attrs* is told to not write one (i.e. `init=False` or a combination of `auto_detect=True` and a custom `__init__`).
- `__attrs_init__` is written and attached to your class *instead* of `__init__`, if *attrs* is told to not write one (when `init=False` or a by a combination of `auto_detect=True` and a custom `__init__`).
This is useful if you want full control over the initialization process, but don't want to set the attributes by hand.

View File

@ -26,21 +26,21 @@ 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 Optional[callable] eq: `callable` used to evaluate equality of two
:param typing.Callable | None eq: `Callable` used to evaluate equality of two
objects.
:param Optional[callable] lt: `callable` used to evaluate whether one
:param typing.Callable | None lt: `Callable` used to evaluate whether one
object is less than another object.
:param Optional[callable] le: `callable` used to evaluate whether one
:param typing.Callable | None le: `Callable` used to evaluate whether one
object is less than or equal to another object.
:param Optional[callable] gt: `callable` used to evaluate whether one
:param typing.Callable | None gt: `Callable` used to evaluate whether one
object is greater than another object.
:param Optional[callable] ge: `callable` used to evaluate whether one
:param typing.Callable | None ge: `Callable` used to evaluate whether one
object is greater than or equal to another object.
:param bool require_same_type: When `True`, equality and ordering methods
will return `NotImplemented` if objects are not of the same type.
:param Optional[str] class_name: Name of class. Defaults to 'Comparable'.
:param str | None class_name: Name of class. Defaults to "Comparable".
See `comparison` for more details.

View File

@ -12,7 +12,7 @@ from typing import _GenericAlias
PYPY = platform.python_implementation() == "PyPy"
PY_3_8_PLUS = sys.version_info[:2] >= (3, 8)
PY_3_9_PLUS = sys.version_info[:2] >= (3, 9)
PY310 = sys.version_info[:2] >= (3, 10)
PY_3_10_PLUS = sys.version_info[:2] >= (3, 10)
PY_3_12_PLUS = sys.version_info[:2] >= (3, 12)
PY_3_13_PLUS = sys.version_info[:2] >= (3, 13)

View File

@ -432,25 +432,25 @@ def resolve_types(
Resolve any strings and forward annotations in type annotations.
This is only required if you need concrete types in `Attribute`'s *type*
field. In other words, you don't need to resolve your types if you only
use them for static type checking.
field. In other words, you don't need to resolve your types if you only use
them for static type checking.
With no arguments, names will be looked up in the module in which the class
was created. If this is not what you want, e.g. if the name only exists
inside a method, you may pass *globalns* or *localns* to specify other
dictionaries in which to look up these names. See the docs of
was created. If this is not what you want, for example, if the name only
exists inside a method, you may pass *globalns* or *localns* to specify
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 Optional[dict] globalns: Dictionary containing global variables.
:param Optional[dict] localns: Dictionary containing local variables.
:param Optional[list] 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.
: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.
:raise TypeError: If *cls* is not a class.
:raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs*
@ -464,7 +464,6 @@ def resolve_types(
.. versionadded:: 20.1.0
.. versionadded:: 21.1.0 *attribs*
.. versionadded:: 23.1.0 *include_extras*
"""
# Since calling get_type_hints is expensive we cache whether we've
# done it already.

View File

@ -17,8 +17,8 @@ from operator import itemgetter
# having the thread-local in the globals here.
from . import _compat, _config, setters
from ._compat import (
PY310,
PY_3_8_PLUS,
PY_3_10_PLUS,
_AnnotationExtractor,
get_generic_base,
)
@ -166,8 +166,9 @@ def attrib(
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, i.e. it
will be used directly *instead* of calling ``repr()`` (the default).
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).
:type repr: a `bool` or a `callable` to use a custom function.
:param eq: If ``True`` (default), include this attribute in the generated
@ -312,7 +313,8 @@ def attrib(
def _compile_and_eval(script, globs, locs=None, filename=""):
"""
"Exec" the script with the given global (globs) and local (locs) variables.
Evaluate the script with the given global (globs) and local (locs)
variables.
"""
bytecode = compile(script, filename, "exec")
eval(bytecode, globs, locs)
@ -499,8 +501,8 @@ def _transform_attrs(
If *these* is passed, use that and don't look for them on the class.
*collect_by_mro* is True, collect them in the correct MRO order, otherwise
use the old -- incorrect -- order. See #428.
If *collect_by_mro* is True, collect them in the correct MRO order,
otherwise use the old -- incorrect -- order. See #428.
Return an `_Attributes`.
"""
@ -600,11 +602,7 @@ def _transform_attrs(
return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map))
def _make_cached_property_getattr(
cached_properties,
original_getattr,
cls,
):
def _make_cached_property_getattr(cached_properties, original_getattr, cls):
lines = [
# Wrapped to get `__class__` into closure cell for super()
# (It will be replaced with the newly constructed class after construction).
@ -801,7 +799,7 @@ class _ClassBuilder:
def __repr__(self):
return f"<_ClassBuilder(cls={self._cls.__name__})>"
if PY310:
if PY_3_10_PLUS:
import abc
def build_class(self):
@ -1339,13 +1337,13 @@ def attrs(
A class decorator that adds :term:`dunder methods` according to the
specified attributes using `attr.ib` or the *these* argument.
Please consider using `attrs.define` / `attrs.frozen` in new code
(``attr.s`` will *never* go away, though).
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 (e.g. if you want to add ``__repr__`` methods to
Django models) or don't want to.
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.
@ -1354,16 +1352,16 @@ def attrs(
:type these: `dict` of `str` to `attr.ib`
:param str repr_ns: When using nested classes, there's no way in Python 2
to automatically detect that. Therefore it's possible to set the
namespace explicitly for a more meaningful ``repr`` output.
: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.
: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 (i.e. it is *not*
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*
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
@ -1372,10 +1370,9 @@ def attrs(
.. warning::
If you prevent *attrs* from creating the ordering methods for you
(``order=False``, e.g. 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.
(``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.
@ -1412,26 +1409,26 @@ def attrs(
``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 (e.g. 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.
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.
- and the `GitHub issue that led to the default \ behavior
<https://github.com/python-attrs/attrs/issues/136>`_ for more
details.
: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. 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.
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.
If ``init`` is ``False``, an ``__attrs_init__`` method will be injected
instead. This allows you to define a custom ``__init__`` method that
@ -1472,29 +1469,28 @@ def attrs(
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
`attr.exceptions.UnannotatedAttributeError` is raised. Use
`attrs.exceptions.UnannotatedAttributeError` is raised. Use
``field_name: typing.Any = attr.ib(...)`` if you don't want to set a
type.
If you assign a value to those attributes (e.g. ``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).
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).
Attributes annotated as `typing.ClassVar`, and attributes that are
neither annotated nor set to an `attr.ib` are **ignored**.
.. warning::
For features that use the attribute name to create decorators (e.g.
: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 e.g. ``validator`` on it.
These errors can be quite confusing and probably the most common bug
report on our bug tracker.
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 bool kw_only: Make all attributes keyword-only in the generated
``__init__`` (if ``init`` is ``False``, this parameter is ignored).
``__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
@ -1517,7 +1513,7 @@ def attrs(
: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 backward-compatibility.
default, but is kept off for backwards-compatibility.
.. seealso::
Issue `#428 <https://github.com/python-attrs/attrs/issues/428>`_
@ -1530,12 +1526,12 @@ def attrs(
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.
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 (i.e. not inherited), it is set to `False` (this is usually
what you want).
the class (meaning: not inherited), it is set to `False` (this is
usually what you want).
: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
@ -1553,15 +1549,15 @@ def attrs(
:param 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, e.g., to
automatically add converters or validators to fields based on their
types.
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`
: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
: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.
@ -1705,7 +1701,7 @@ def attrs(
raise TypeError(msg)
if (
PY310
PY_3_10_PLUS
and match_args
and not _has_own_attribute(cls, "__match_args__")
):

View File

@ -104,7 +104,8 @@ def default_if_none(default=NOTHING, factory=None):
def to_bool(val):
"""
Convert "boolean" strings (e.g., from env. vars.) to real booleans.
Convert "boolean" strings (for example, from environment variables) to real
booleans.
Values mapping to :code:`True`:

View File

@ -145,7 +145,7 @@ def simple_classes(
be generated, and if `slots=False` is passed in, no slotted classes will be
generated. The same applies to `frozen` and `weakref_slot`.
By default, some attributes will be private (i.e. prefixed with an
By default, some attributes will be private (those prefixed with an
underscore). If `private_attrs=True` is passed in, all attributes will be
private, and if `private_attrs=False`, no attributes will be private.
"""

View File

@ -7,10 +7,12 @@ import pytest
import attrs
from attr._compat import PY310, PY_3_12_PLUS
from attr._compat import PY_3_10_PLUS, PY_3_12_PLUS
@pytest.mark.skipif(not PY310, reason="abc.update_abstractmethods is 3.10+")
@pytest.mark.skipif(
not PY_3_10_PLUS, reason="abc.update_abstractmethods is 3.10+"
)
class TestUpdateAbstractMethods:
def test_abc_implementation(self, slots):
"""

View File

@ -21,7 +21,7 @@ from hypothesis.strategies import booleans, integers, lists, sampled_from, text
import attr
from attr import _config
from attr._compat import PY310, PY_3_8_PLUS
from attr._compat import PY_3_8_PLUS, PY_3_10_PLUS
from attr._make import (
Attribute,
Factory,
@ -2492,7 +2492,7 @@ class TestAutoDetect:
C, "__getstate__", None
)
@pytest.mark.skipif(PY310, reason="Pre-3.10 only.")
@pytest.mark.skipif(PY_3_10_PLUS, reason="Pre-3.10 only.")
def test_match_args_pre_310(self):
"""
__match_args__ is not created on Python versions older than 3.10.
@ -2505,7 +2505,9 @@ class TestAutoDetect:
assert None is getattr(C, "__match_args__", None)
@pytest.mark.skipif(not PY310, reason="Structural pattern matching is 3.10+")
@pytest.mark.skipif(
not PY_3_10_PLUS, reason="Structural pattern matching is 3.10+"
)
class TestMatchArgs:
"""
Tests for match_args and __match_args__ generation.