diff --git a/docs/examples.rst b/docs/examples.rst index ba5343d4a..08bc52838 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -166,7 +166,7 @@ Keyword-only attributes allow subclasses to add attributes without default value ... TypeError: B() missing 1 required keyword-only argument: 'b' -If you don't set ``kw_only=True``, then there's is no valid attribute ordering and you'll get an error: +If you don't set ``kw_only=True``, then there is no valid attribute ordering, and you'll get an error: .. doctest:: diff --git a/docs/hashing.rst b/docs/hashing.rst index 3e90f8cba..1fe943fc7 100644 --- a/docs/hashing.rst +++ b/docs/hashing.rst @@ -47,7 +47,7 @@ Because according to the definition_ from the official Python docs, the returned The easiest way to reset ``__hash__`` on a class is adding ``__hash__ = object.__hash__`` in the class body. -#. If two object are not equal, their hash **should** be different. +#. If two objects are not equal, their hash **should** be different. While this isn't a requirement from a standpoint of correctness, sets and dicts become less effective if there are a lot of identical hashes. The worst case is when all objects have the same hash which turns a set into a list. @@ -80,7 +80,7 @@ If such objects are to be stored in hash-based collections, it can be useful to To enable caching of hash codes, pass ``cache_hash=True`` to ``@attrs``. This may only be done if ``attrs`` is already generating a hash function for the object. -.. [#fn1] The hash is computed by hashing a tuple that consists of an unique id for the class plus all attribute values. +.. [#fn1] The hash is computed by hashing a tuple that consists of a unique id for the class plus all attribute values. .. _definition: https://docs.python.org/3/glossary.html#term-hashable .. _`Python Hashes and Equality`: https://hynek.me/articles/hashes-and-equality/ diff --git a/docs/init.rst b/docs/init.rst index 0c3f4cd79..231577faf 100644 --- a/docs/init.rst +++ b/docs/init.rst @@ -448,7 +448,7 @@ Derived Attributes One of the most common ``attrs`` questions on *Stack Overflow* is how to have attributes that depend on other attributes. For example if you have an API token and want to instantiate a web client that uses it for authentication. -Based on the previous sections, there's two approaches. +Based on the previous sections, there are two approaches. The simpler one is using ``__attrs_post_init__``:: diff --git a/docs/names.rst b/docs/names.rst index 0fe953e6a..1db82fb42 100644 --- a/docs/names.rst +++ b/docs/names.rst @@ -43,7 +43,7 @@ In the wake of all of that, `glyph `_ and `Hynek `_ in Python 3.6 and Guido felt like it would be a good mechanic to introduce something similar to ``attrs`` to the Python standard library. The result, of course, was `PEP 557 `_\ [#stdlib]_ which eventually became the `dataclasses` module in Python 3.7. -``attrs`` at this point was lucky to have several people on board who were also very excited about type annotations and helped implementing it; including a `Mypy plugin `_. +``attrs`` at this point was lucky to have several people on board who were also very excited about type annotations and helped implement it; including a `Mypy plugin `_. And so it happened that ``attrs`` `shipped `_ the new method of defining classes more than half a year before Python 3.7 -- and thus `dataclasses` -- were released. ----- @@ -90,7 +90,7 @@ We're determined to serve both. ^^^^^^^^^^^^^ Over its existence, ``attrs`` never stood still. -But since we also greatly care about backward compatibility and not breaking our users's code, many features and niceties have to be manually activated. +But since we also greatly care about backward compatibility and not breaking our users' code, many features and niceties have to be manually activated. That is not only annoying, it also leads to the problem that many of ``attrs``'s users don't even know what it can do for them. We've spent years alone explaining that defining attributes using type annotations is in no way unique to `dataclasses`. diff --git a/docs/overview.rst b/docs/overview.rst index b35f66f2d..2d7302c74 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -49,7 +49,7 @@ What ``attrs`` Is Not All ``attrs`` does is: -1. take your declaration, +1. Take your declaration, 2. write :term:`dunder methods` based on that information, 3. and attach them to your class. diff --git a/docs/python-2.rst b/docs/python-2.rst index 7ec9e5112..863c6b034 100644 --- a/docs/python-2.rst +++ b/docs/python-2.rst @@ -12,7 +12,7 @@ Feasibility in this case means: 1. Possibility to run the tests on our development computers, 2. and **free** CI options. -This can mean that we will have to run our tests on PyPy, whose maintainters have unequivocally declared that they do not intend to stop the development and maintenance of their Python 2-compatible line at all. +This can mean that we will have to run our tests on PyPy, whose maintainers have unequivocally declared that they do not intend to stop the development and maintenance of their Python 2-compatible line at all. And this can mean that at some point, a sponsor will have to step up and pay for bespoke CI setups. **However**: there is no promise of new features coming to ``attrs`` running under Python 2. diff --git a/docs/types.rst b/docs/types.rst index fbb90a7e9..20f9f5fd8 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -22,7 +22,7 @@ You can choose freely between the approaches, but please remember that if you ch ---- -Even when going all-in an type annotations, you will need `attr.field` for some advanced features though. +Even when going all-in on type annotations, you will need `attr.field` for some advanced features though. One of those features are the decorator-based features like defaults. It's important to remember that ``attrs`` doesn't do any magic behind your back. @@ -42,7 +42,7 @@ If you need to resolve these to real types, you can call `attrs.resolve_types` w In practice though, types show their biggest usefulness in combination with tools like mypy_, pytype_, or pyright_ that have dedicated support for ``attrs`` classes. -The addition of static types is certainly one of the most exciting features in the Python ecosystem and helps you writing *correct* and *verified self-documenting* code. +The addition of static types is certainly one of the most exciting features in the Python ecosystem and helps you write *correct* and *verified self-documenting* code. If you don't know where to start, Carl Meyer gave a great talk on `Type-checked Python in the Real World `_ at PyCon US 2018 that will help you to get started in no time. diff --git a/docs/why.rst b/docs/why.rst index 2c0ca4cd6..dbfed3d71 100644 --- a/docs/why.rst +++ b/docs/why.rst @@ -39,7 +39,7 @@ Basically what ``attrs`` was in 2015. …pydantic? ---------- -*pydantic* is first an foremost a *data validation library*. +*pydantic* is first and foremost a *data validation library*. As such, it is a capable complement to class building libraries like ``attrs`` (or Data Classes!) for parsing and validating untrusted data. However, as convenient as it might be, using it for your business or data layer `is problematic in several ways `_: @@ -89,7 +89,7 @@ Other often surprising behaviors include: - Iterability also implies that it's easy to accidentally unpack a ``namedtuple`` which leads to hard-to-find bugs. [#iter]_ - ``namedtuple``\ s have their methods *on your instances* whether you like it or not. [#pollution]_ - ``namedtuple``\ s are *always* immutable. - Not only does that mean that you can't decide for yourself whether your instances should be immutable or not, it also means that if you want to influence your class' initialization (validation? default values?), you have to implement :meth:`__new__() ` which is a particularly hacky and error-prone requirement for a very common problem. [#immutable]_ + Not only does that mean that you can't decide for yourself whether your instances should be immutable or not, it also means that if you want to influence your class' initialization (validation? default values?), you have to implement :meth:`__new__() ` which is a particularly hacky and error-prone requirement for a very common problem. [#immutable]_ - To attach methods to a ``namedtuple`` you have to subclass it. And if you follow the standard library documentation's recommendation of::