Skip to content

Commit f06ceaa

Browse files
committed
docs: update why
1 parent 358dec2 commit f06ceaa

1 file changed

Lines changed: 11 additions & 10 deletions

File tree

docs/why.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,43 @@ It predates type annotations and hence Data Classes, but it masterfully illustra
99
{pep}`557` added Data Classes to [Python 3.7](https://docs.python.org/3.7/whatsnew/3.7.html#dataclasses).
1010
They resemble *attrs* in many ways.
1111

12-
They are the result of the Python community's [wish](https://mail.python.org/pipermail/python-ideas/2017-May/045618.html) to have an easier way to write classes in the standard library without the problems of `namedtuple`s.
12+
They are the result of the Python community's [wish](https://mail.python.org/pipermail/python-ideas/2017-May/045618.html) to have an easier way to write classes in the standard library without the [problems of `namedtuple`s](namedtuples).
1313
To that end, *attrs* and its developers were involved in the PEP process, and while we may disagree with some minor decisions that have been made, it's a fine library.
14-
If it stops you from abusing `namedtuple`s, it is a huge win.
14+
If it stops you from abusing `namedtuple`s, it's a huge win.
1515

1616
Nevertheless, there are still reasons to prefer *attrs* over Data Classes.
1717
Whether they're relevant to *you* depends on your circumstances:
1818

1919
- Data Classes are *intentionally* less powerful than *attrs*.
20-
There is a long list of features that were sacrificed for the sake of simplicity and while the most obvious ones are validators, converters, [equality customization](custom-comparison), a solution to the [`__init_subclass__` problem](init-subclass), or {doc}`extensibility <extending>` in general -- it permeates throughout all APIs.
20+
There is a long list of features that were sacrificed for the sake of simplicity and while the most obvious ones are validators, converters, [equality customization](custom-comparison), a solution to the [`__init_subclass__` problem](init-subclass), or {doc}`extensibility <extending>` in general it permeates throughout all APIs.
2121

2222
On the other hand, Data Classes do not currently offer any significant features that *attrs* doesn't already have.
2323

2424
- We are more likely to commit crimes against nature to make things work that one would expect to work, but that are quite complicated.
2525

2626
This includes stepping through generated methods using a debugger, cell rewriting to make bare `super()` calls work, or making {func}`functools.cached_property` work on slotted classes.
2727

28-
Our obsession with developer experience and quality-of-life features is what *attrs* users report missing most when forced to use Data Classes.
29-
30-
- *attrs* supports all mainstream Python versions, including PyPy.
28+
Our obsession with **developer experience** and quality-of-life features is what *attrs* users report missing most when forced to use Data Classes.
3129

3230
- *attrs* doesn't force type annotations on you if you don't like them.
3331

3432
- But since it **also** supports typing, it's the best way to embrace type hints *gradually*, too.
3533

3634
- While Data Classes implement features from *attrs* every now and then, their presence is dependent on the Python version, not the package version.
37-
For example, support for `__slots__` was only added in Python 3.10, but it doesn’t do cell rewriting, and therefore doesn’t support bare calls to `super()`.
3835

39-
This may or may not be fixed in later Python releases, but handling all these differences is especially painful for PyPI packages that support multiple Python versions.
36+
Handling all these differences is especially painful for PyPI packages that support multiple Python versions.
4037
And of course, this includes possible implementation bugs.
4138

4239
- *attrs* can and will move faster.
4340
We are not bound to any release schedules, and we have a clear deprecation policy.
4441

4542
One of the [reasons](https://peps.python.org/pep-0557/#why-not-just-use-attrs) to not vendor *attrs* in the standard library was to not impede *attrs*'s future development.
4643

47-
One way to think about *attrs* vs Data Classes is that *attrs* is a fully-fledged toolkit to write powerful classes while Data Classes are an easy way to get a class with some attributes.
48-
Basically what *attrs* was in 2015.
44+
One way to think about *attrs* vs Data Classes is that *attrs* is a **fully-fledged toolkit to write powerful classes** while Data Classes are an easy way to get a class with some attributes – basically what *attrs* was in 2015.
45+
46+
But many missing features make Data Classes **not fit for public APIs** beyond pure data containers.
47+
For example, unless you build Rube-Goldberg machines around `InitVar`s and custom `__post_init__` methods, you either can't have private field names, or you have to tolerate a public `__init__` method with underscore-prefixed argument names.
48+
With *attrs*, you get automatic private field name → public argument name mapping for free – because that's how an idiomatic Python class behaves.
4949

5050

5151
## … Pydantic?
@@ -66,6 +66,7 @@ If you'd like a powerful library for structuring, unstructuring, and validating
6666
One of its core tenets is that it doesn't couple your classes to external factors.
6767

6868

69+
(namedtuples)=
6970
## … namedtuples?
7071

7172
{obj}`collections.namedtuple`s are tuples with names, not classes.[^history]

0 commit comments

Comments
 (0)