{"id":262,"library":"attrs","title":"Classes Without Boilerplate","description":"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.","status":"active","version":"26.1.0","language":"en","source_language":"en","source_url":"https://github.com/python-attrs/attrs","tags":["classes","boilerplate","dataclasses","attributes","code generation"],"install":[{"cmd":"pip install attrs","lang":"bash","label":"Install attrs"}],"dependencies":[],"imports":[{"symbol":"define","correct":"from attrs import define"},{"symbol":"field","correct":"from attrs import field"},{"note":"The `s` decorator is part of the classic `attr` namespace, imported as `attr`. Modern usage prefers `from attrs import define`.","wrong":"from attr import s","symbol":"s","correct":"import attr; attr.s"},{"note":"The `ib` function is part of the classic `attr` namespace, imported as `attr`. Modern usage prefers `from attrs import field`.","wrong":"from attr import ib","symbol":"ib","correct":"import attr; attr.ib"}],"quickstart":{"code":"from attrs import define, field\n\n@define\nclass User:\n    id: int = field()\n    name: str = field()\n    email: str = field(default='no-email@example.com')\n\n# Create instances\nuser1 = User(id=1, name='Alice')\nuser2 = User(id=2, name='Bob', email='bob@example.com')\n\nprint(user1)\nprint(user2)\nprint(user1 == User(id=1, name='Alice')) # Automatically generated equality","lang":"python","description":"This quickstart demonstrates defining a simple `User` class using the modern `attrs.define` decorator and `attrs.field` for attributes. It showcases automatic `__init__`, `__repr__`, and `__eq__` generation."},"warnings":[{"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.","message":"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]`.","severity":"breaking","affected_versions":">=21.3.0"},{"fix":"For new projects or modernizing existing code, use `from attrs import define, field` instead of `import attr` and `attr.s`/`attr.ib`.","message":"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.","severity":"gotcha","affected_versions":"All versions, especially when migrating or starting new projects."},{"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`.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"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.","severity":"deprecated","affected_versions":"All versions prior to the change."}],"env_vars":null,"last_verified":"2026-05-12T12:28:30.517Z","next_check":"2026-07-13T00:00:00.000Z","problems":[],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.7,"disk_size":"18.3M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.7,"disk_size":"18.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.7,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":2.7,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":2.7,"disk_size":"20.2M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":2.7,"disk_size":"20.2M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.7,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.7,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"12.0M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"12.0M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.8,"disk_size":"11.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.8,"disk_size":"11.8M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.5,"disk_size":"17.8M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.5,"disk_size":"17.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":2.5,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":2.5,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}