Classes Without Boilerplate
raw JSON → 26.1.0 verified Tue May 12 auth: no en install: verified quickstart: verified
attrs is a Python package designed to simplify class creation by automatically generating boilerplate like `__init__`, `__repr__`, and comparison methods. It aims to make writing classes more enjoyable and concise without sacrificing runtime performance. The current version is 26.1.0, and it follows a CalVer (Calendar Versioning) release strategy, typically releasing new major versions yearly with interim updates.
pip install attrs Warnings
breaking As of `attrs` version 21.3.0, when using the modern `@define` decorator, converters are now run by default when an attribute is set on an instance, in addition to validators. This changes the default behavior of `on_setattr` to `[attrs.setters.convert, attrs.setters.validate]`. ↓
fix If this change in behavior is undesirable, explicitly set `on_setattr=None` or define a custom `on_setattr` callable for your attributes or class.
gotcha attrs provides two main API namespaces: the classic `attr` (e.g., `attr.s`, `attr.ib`) and the newer `attrs` (e.g., `attrs.define`, `attrs.field`). While the `attr` namespace is supported indefinitely, the `attrs` namespace offers more modern APIs and better defaults, especially since version 20.1.0 and the introduction of `import attrs` in 21.3.0. New development should favor the `attrs` namespace. ↓
fix For new projects or modernizing existing code, use `from attrs import define, field` instead of `import attr` and `attr.s`/`attr.ib`.
gotcha The internal structure of the `attrs.Attribute` class is subject to change in future versions and is not considered part of the stable public API for extensions. While it can be read, relying on its internal structure for building complex extensions is discouraged. ↓
fix Treat `attrs.Attribute` as a read-only data structure. If building extensions, be prepared for potential adjustments to your code if it depends on the precise internal layout of `attrs.Attribute`.
deprecated The `attr.s(collect_by_mro=False)` argument, which controls how attributes are collected from base classes in inheritance hierarchies, will have its default value changed to `True` in a future release. This could alter behavior for certain multiple-inheritance scenarios. ↓
fix If your code relies on the current `collect_by_mro=False` behavior (where attributes are not collected by MRO by default), explicitly set `collect_by_mro=False` to maintain current behavior. Consider testing with `collect_by_mro=True` to understand potential future impacts.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.07s 18.3M
3.10 alpine (musl) - - 0.07s 18.3M
3.10 slim (glibc) - - 0.04s 19M
3.10 slim (glibc) - - 0.05s 19M
3.11 alpine (musl) - - 0.11s 20.2M
3.11 alpine (musl) - - 0.10s 20.2M
3.11 slim (glibc) - - 0.08s 21M
3.11 slim (glibc) - - 0.09s 21M
3.12 alpine (musl) - - 0.09s 12.0M
3.12 alpine (musl) - - 0.08s 12.0M
3.12 slim (glibc) - - 0.08s 13M
3.12 slim (glibc) - - 0.09s 13M
3.13 alpine (musl) - - 0.09s 11.7M
3.13 alpine (musl) - - 0.08s 11.8M
3.13 slim (glibc) - - 0.09s 12M
3.13 slim (glibc) - - 0.08s 12M
3.9 alpine (musl) - - 0.07s 17.8M
3.9 alpine (musl) - - 0.06s 17.8M
3.9 slim (glibc) - - 0.05s 18M
3.9 slim (glibc) - - 0.05s 18M
Imports
- define
from attrs import define - field
from attrs import field - s wrong
from attr import scorrectimport attr; attr.s - ib wrong
from attr import ibcorrectimport attr; attr.ib
Quickstart verified last tested: 2026-04-23
from attrs import define, field
@define
class User:
id: int = field()
name: str = field()
email: str = field(default='no-email@example.com')
# Create instances
user1 = User(id=1, name='Alice')
user2 = User(id=2, name='Bob', email='bob@example.com')
print(user1)
print(user2)
print(user1 == User(id=1, name='Alice')) # Automatically generated equality