Recent Releases of attrs
attrs - 25.3.0
Highlights
Quick regression fix for generator-based field_transformers.
Full changelog below!
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), Ecosystems (@ecosyste-ms), Klaviyo (@klaviyo), Privacy Solutions GmbH (@privacy-solutions), FilePreviews (@filepreviews), nate nowack (@zzstoatzz), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Maintenance Sustainers
Buttondown (@buttondown), Christopher Dignam (@chdsbd), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Polar (@polarsource), Mike Fiedler (@miketheman), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), Pieter Swinkels (@swinkels), Nick Libertini (@libertininick), Brian M. Dennis (@crossjam), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), The Westervelt Company (@westerveltco), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Thomas Klinger (@thmsklngr), Andreas Poehlmann (@ap--), August Trapper Bigelow (@atbigelow), Carlton Gibson (@carltongibson), and Roboflow (@roboflow).
Not to forget 14 more amazing humans who chose to be generous but anonymous!
Full Changelog
Changes
- Restore support for generator-based
field_transformers. #1417
This release contains contributions from @ashb, and @hynek.
Artifact Attestations
You can verify this release's artifact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
console
$ gh attestation verify --owner python-attrs attrs-25.3.0.tar.gz
and
console
$ gh attestation verify --owner python-attrs attrs-25.3.0-py3-none-any.whl
- Python
Published by hynek 11 months ago
attrs - 25.2.0
Highlights
Vroom–vroom edition! attrs had always impressive runtime performance because we generate optimal code for your configuration. But now, said code generation is 30–50% faster, too!
This is the last attrs version to support Python 3.8.
Full changelog below!
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), Ecosystems (@ecosyste-ms), Klaviyo (@klaviyo), Privacy Solutions GmbH (@privacy-solutions), FilePreviews (@filepreviews), nate nowack (@zzstoatzz), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Maintenance Sustainers
Buttondown (@buttondown), Christopher Dignam (@chdsbd), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Polar (@polarsource), Mike Fiedler (@miketheman), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), Pieter Swinkels (@swinkels), Nick Libertini (@libertininick), Brian M. Dennis (@crossjam), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), The Westervelt Company (@westerveltco), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Thomas Klinger (@thmsklngr), Andreas Poehlmann (@ap--), August Trapper Bigelow (@atbigelow), Carlton Gibson (@carltongibson), and Roboflow (@roboflow).
Not to forget 14 more amazing humans who chose to be generous but anonymous!
Full Changelog
Changes
- Checking mandatory vs non-mandatory attribute order is now performed after the field transformer, since the field transformer may change attributes and/or their order. #1147
attrs.make_class()now allows for Unicode class names. #1406- Speed up class creation by 30%-50% by compiling methods only once and using a variety of other techniques. #1407
- The error message if an attribute has both an annotation and a type argument will now disclose what attribute seems to be the problem. #1410
This release contains contributions from @frenzymadness, @hynek, @jamesmurphy-mc, @serge-sans-paille, @Tinche, and @webknjaz.
Artifact Attestations
You can verify this release's artifact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
console
$ gh attestation verify --owner python-attrs attrs-25.2.0.tar.gz
and
console
$ gh attestation verify --owner python-attrs attrs-25.2.0-py3-none-any.whl
- Python
Published by hynek 12 months ago
attrs - 25.1.0
Highlights
This release only ensures correct PyPI licensing metadata.
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), Klaviyo (@klaviyo), FilePreviews (@filepreviews), Privacy Solutions GmbH (@privacy-solutions), Gedankenspieler (@Gedankenspieler), Daniel Fortunov (@asqui), Kevin P. Fleming (@kpfleming), and Polar (@polarsource).
Maintenance Sustainers
Buttondown (@buttondown), Christopher Dignam (@chdsbd), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Chris Withers (@cjw296), Mike Fiedler (@miketheman), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), Pieter Swinkels (@swinkels), Nick Libertini (@libertininick), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), The Westervelt Company (@westerveltco), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Thomas Klinger (@thmsklngr), Andreas Poehlmann (@ap--), August Bigelow (@atbigelow), Carlton Gibson (@carltongibson), and Roboflow (@roboflow).
Not to forget 11 more amazing humans who chose to be generous but anonymous!
Full Changelog
Changes
- This release only ensures correct PyPI licensing metadata. #1386
This release contains contributions from @hynek, and @Lx.
Artifact Attestations
You can verify this release's artifact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
console
$ gh attestation verify --owner python-attrs attrs-25.1.0.tar.gz
and
console
$ gh attestation verify --owner python-attrs attrs-25.1.0-py3-none-any.whl
- Python
Published by hynek about 1 year ago
attrs - 24.3.0
Highlights
Mostly bug fixes and adjustments, but also support for Python 3.13's copy.replace(). On the other side we say goodbye to Python 3.7.
Full changelog below!
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), thanks.dev (@thnxdev), Klaviyo (@klaviyo), FilePreviews (@filepreviews), Privacy Solutions GmbH (@privacy-solutions), Daniel Fortunov (@asqui), Kevin P. Fleming (@kpfleming), and Polar (@polarsource).
Maintenance Sustainers
Buttondown (@buttondown), Konstantin Vinogradov (@vinogradovkonst), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Chris Withers (@cjw296), Mike Fiedler (@miketheman), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), Pieter Swinkels (@swinkels), Nick Libertini (@libertininick), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), The Westervelt Company (@westerveltco), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Thomas Klinger (@thmsklngr), Andreas Poehlmann (@ap--), August Bigelow (@atbigelow), Carlton Gibson (@carltongibson), and Roboflow (@roboflow).
Not to forget 9 more amazing humans who chose to be generous but anonymous!
Full Changelog
Backwards-incompatible Changes
- Python 3.7 has been dropped. #1340
Changes
- Introduce
attrs.NothingType, for annotating types consistent withattrs.NOTHING. #1358 - Allow mutating
__suppress_context__and__notes__on frozen exceptions. #1365 attrs.converters.optional()works again when takingattrs.converters.pipe()or another Converter as its argument. #1372- attrs instances now support
copy.replace(). #1383 attrs.validators.instance_of()'s type hints now allow for union types. For example:instance_of(str | int)#1385
This release contains contributions from @dwgrth, @esteevens, @filbranden, @geofft, @graingert, @hynek, @mschoettle, @Tinche, @tjstum, and @webknjaz.
Artifact Attestations
You can verify this release's artifact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
console
$ gh attestation verify --owner python-attrs attrs-24.3.0.tar.gz
and
console
$ gh attestation verify --owner python-attrs attrs-24.3.0-py3-none-any.whl
- Python
Published by hynek about 1 year ago
attrs - 24.2.0
Highlights
Big releases always carry the risk of regressions, but never did I expect to break Python 3.14’s CI! On the plus side, attrs runs on 3.14 now.
Full changelog below!
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Klaviyo (@klaviyo), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Maintenance Sustainers
Adam Hill (@adamghill), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Mike Fiedler (@miketheman), Thomas Klinger (@thmsklngr), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), and Andreas Poehlmann (@ap--).
Not to forget 7 more amazing humans who chose to be generous but anonymous!
Full Changelog
Deprecations
- Given the amount of warnings raised in the broader ecosystem, we've decided to only soft-deprecate the hash argument to
@define/@attr.s. Please don't use it in new code, but we don't intend to remove it anymore. #1330
Changes
attrs.converters.pipe()(and its syntactic sugar of passing a list forattrs.field()'s /attr.ib()'s converter argument) works again when passingattrs.setters.convertto on_setattr (which is default forattrs.define). #1328- Restored support for PEP 649 / 749-implementing Pythons -- currently 3.14-dev. #1329
This release contains contributions from @hynek.
Artifact Attestations
You can verify this release's artififact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
console
$ gh attestation verify --owner python-attrs attrs-24.2.0.tar.gz
and
console
$ gh attestation verify --owner python-attrs attrs-24.2.0-py3-none-any.whl
- Python
Published by hynek over 1 year ago
attrs - 24.1.0
Highlights
This release comes severely delayed, but comes with many exciting new features, bugfixes, and performance optimizations!
The most notable is probably the possibility to receive self and field definitions in your converters by wrapping them into a attrs.Converter.
The other big thing is our own replacement for __init_subclass__ called (you guessed it) __attrs_init_subclass__. Check out the docs, if you're not sure what this is good for.
Finally, we've made more important steps to promote our "new" APIs (can you believe they're 4 years old!?) in the docs. If we missed anything, please let us know.
Full changelog below!
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Klaviyo (@klaviyo), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Maintenance Sustainers
Adam Hill (@adamghill), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Mike Fiedler (@miketheman), Thomas Klinger (@thmsklngr), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), and Andreas Poehlmann (@ap--).
Not to forget 7 more amazing humans who chose to be generous but anonymous!
Full Changelog
Backwards-incompatible Changes
attrs.evolve()doesn't accept the inst argument as a keyword argument anymore. Pass it as the first positional argument instead. #1264attrs.validators.provides()has been removed. The removed code is available as a gist for convenient copy and pasting. #1265All packaging metadata except from
__version__and__version_info__has been removed from theattrandattrsmodules (for example,attrs.__url__).
Please use importlib.metadata or importlib_metadata instead. #1268
- Speed up the generated
__eq__methods significantly by generating a chain of attribute comparisons instead of constructing and comparing tuples. This change arguably makes the behavior more correct, but changes it if an attribute compares equal by identity but not value, likefloat('nan'). #1310
Deprecations
- The repr_ns argument to
attr.sis now deprecated. It was a workaround for nested classes in Python 2 and is pointless in Python 3. #1263 - The hash argument to
@attr.s,@attrs.define, andmake_class()is now deprecated in favor of unsafe_hash, as defined by PEP 681. #1323
Changes
Allow original slotted
functools.cached_propertyclasses to be cleaned by garbage collection. Allowsuper()calls in slotted cached properties. #1221Our type stubs now use modern type notation and are organized such that VS Code's quick-fix prefers the
attrsnamespace. #1234Preserve
AttributeErrorraised by properties of slotted classes withfunctools.cached_properties. #1253It is now possible to wrap a converter into an
attrs.Converterand get the current instance and/or the current field definition passed into the converter callable.
Note that this is not supported by any type checker, yet. #1267
attrs.make_class()now populates the__annotations__dict of the generated class, so thatattrs.resolve_types()can resolve them. #1285Added the
attrs.validators.or_()validator. #1303The combination of a
__attrs_pre_init__that takes arguments, a kw-only field, and a default on that field does not crash anymore. #1319attrs.validators.in_()now transforms certain unhashable options to tuples to keep the field hashable.
This allows fields that use this validator to be used with, for example, attrs.filters.include(). #1320
- If a class has an inherited method called
__attrs_init_subclass__, it is now called once the class is done assembling.
This is a replacement for Python's __init_subclass__ and useful for registering classes, and similar. #1321
This release contains contributions from @bibajz, @carltongibson, @diabolo-dan, @dlax, @econchick, @frenzymadness, @hynek, @koenigdavidmj, @mikejturner, @moto-timo, @my1e5, @richardsheridan, @sscherfke, @tdsmith, and @Tinche.
Artifact Attestations
You can verify this release's artififact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
console
$ gh attestation verify --owner python-attrs attrs-24.1.0.tar.gz
and
console
$ gh attestation verify --owner python-attrs attrs-24.1.0-py3-none-any.whl
- Python
Published by hynek over 1 year ago
attrs -
Highlights
Mostly typing fixes in this release, but I'm excited that we found a workaround to make functools.cached_property work with slotted classes! Also, I'm sure there's gonna be fans of the new behavior of __attrs_pre_init__ where it receives all arguments passed to __init__ if it accepts more than self.
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Maintenance Sustainers
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), and Mike Fiedler (@miketheman).
Not to forget 6 more amazing humans who chose to be generous but anonymous!
Full Changelog
Changes
- The type annotation for
attrs.resolve_types()is now correct. #1141 - Type stubs now use
typing.dataclass_transformto decorate dataclass-like decorators, instead of the non-standard__dataclass_transform__special form, which is only supported by Pyright. #1158 - Fixed serialization of namedtuple fields using
attrs.asdict/astuple()withretain_collection_types=True. #1165 attrs.AttrsInstanceis now atyping.Protocolin both type hints and code. This allows you to subclass it along with anotherProtocol. #1172- If attrs detects that
__attrs_pre_init__accepts more than justself, it will call it with the same arguments as__init__was called. This allows you to, for example, pass arguments tosuper().__init__(). #1187 - Slotted classes now transform
functools.cached_propertydecorated methods to support equivalent semantics. #1200 - Added class_body argument to
attrs.make_class()to provide additional attributes for newly created classes. It is, for example, now possible to attach methods. #1203
- Python
Published by hynek about 2 years ago
attrs - 23.1.0
Highlights
A lot of features and smaller bug fixes! But also with a heavy heart, we're leaving the last dataclass-less Python version (3.6) behind, but don't worry: the old versions aren't going anywhere and thanks to the magic of package metadata, pip install attrs should still work on Python 3.6 as if nothing happened.
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), Sentry (@getsentry), HiredScore (@HiredScore), FilePreviews (@filepreviews), and Daniel Fortunov (@asqui).
Maintenance Sustainers
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), Stein Magnus Jodal (@jodal), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Tom Ballinger (@thomasballinger), @medecau, Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), and Stefan Hagen (@sthagen).
Not to forget 3 more amazing humans who chose to be generous but anonymous!
Full Changelog
Backwards-incompatible Changes
Deprecations
- The support for zope-interface via the
attrs.validators.providesvalidator is now deprecated and will be removed in, or after, April 2024.
The presence of a C-based package in our developement dependencies has caused headaches and we're not under the impression it's used a lot.
Let us know if you're using it and we might publish it as a separate package. #1120
Changes
attrs.filters.exclude()andattrs.filters.include()now support the passing of attribute names as strings. #1068attrs.has()andattrs.fields()now handle generic classes correctly. #1079Fix frozen exception classes when raised within e.g.
contextlib.contextmanager, which mutates their__traceback__attributes. #1081@frozennow works with type checkers that implement PEP-681 (ex. pyright). #1084Restored ability to unpickle instances pickled before 22.2.0. #1085
attrs.asdict()'s andattrs.astuple()'s type stubs now accept theattrs.AttrsInstanceprotocol. #1090Fix slots class cellvar updating closure in CPython 3.8+ even when
__code__introspection is unavailable. #1092attrs.resolve_types()can now passinclude_extrastotyping.get_type_hints()on Python 3.9+, and does so by default. #1099Added instructions for pull request workflow to
CONTRIBUTING.md. #1105Added type parameter to
attrs.field()function for use withattrs.make_class().
Please note that type checkers ignore type metadata passed into make_class(), but it can be useful if you're wrapping attrs. #1107
- It is now possible for
attrs.evolve()(andattr.evolve()) to change fields namedinstif the instance is passed as a positional argument.
Passing the instance using the inst keyword argument is now deprecated and will be removed in, or after, April 2024. #1117
attrs.validators.optional()now also accepts a tuple of validators (in addition to lists of validators). #1122
- Python
Published by hynek almost 3 years ago
attrs - 22.2.0
Highlights
It's been a lot busier than the changelog indicates, but a lot of the work happened under the hood (like some impressive performance improvements). But we've got still one big new feature that's are worthy the holidays:
Fields now have an alias argument that allows you to set the field's name in the generated __init__ method. This is especially useful for those who aren't fans of attrs's behavior of stripping underscores from private attribute names.
Special Thanks
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Above and Beyond
Variomedia AG (@variomedia), Tidelift (@tidelift), Sentry (@getsentry), HiredScore (@HiredScore), FilePreviews (@filepreviews), and Daniel Fortunov (@asqui).
Maintenance Sustainers
@rzijp, Adam Hill (@adamghill), Dan Groshev (@si14), Tamir Bahar (@tmr232), Adi Roiban (@adiroiban), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), Stein Magnus Jodal (@jodal), Iwan Aucamp (@aucampia), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Thomas Ballinger (@thomasballinger), @medecau, Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Jannis Leidel (@jezdez), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), and Christopher Dignam (@chdsbd).
Not to forget 2 more amazing humans who chose to be generous but anonymous!
Full Changelog
Backwards-incompatible Changes
- Python 3.5 is not supported anymore. #988
Deprecations
- Python 3.6 is now deprecated and support will be removed in the next release. #1017
Changes
attrs.field()now supports an alias option for explicit__init__argument names.
Get __init__ signatures matching any taste, peculiar or plain! The PEP 681 compatible alias option can be use to override private attribute name mangling, or add other arbitrary field argument name overrides. #950
attrs.NOTHINGis now an enum value, making it possible to use with e.g.typing.Literal. #983Added missing re-import of
attr.AttrsInstanceto theattrsnamespace. #987Fix slight performance regression in classes with custom
__setattr__and speedup even more. #991Class-creation performance improvements by switching performance-sensitive templating operations to f-strings.
You can expect an improvement of about 5% -- even for very simple classes. #995
attrs.has()is now aTypeGuardforAttrsInstance. That means that type checkers know a class is an instance of anattrsclass if you check it usingattrs.has()(orattr.has()) first. #997Made
attrs.AttrsInstancestub available at runtime and fixed type errors related to the usage ofattrs.AttrsInstancein Pyright. #999On Python 3.10 and later, call
abc.update_abstractmethods()on dict classes after creation. This improves the detection of abstractness. #1001attrs's pickling methods now use dicts instead of tuples. That is safer and more robust across different versions of a class. #1009
Added
attrs.validators.not_(wrapped_validator)to logically invert wrapped_validator by accepting only values where wrapped_validator rejects the value with aValueErrororTypeError(by default, exception types configurable). #1010The type stubs for
attrs.cmp_using()now have default values. #1027To conform with PEP 681,
attr.s()andattrs.define()now accept unsafe_hash in addition to hash. #1065
- Python
Published by hynek about 3 years ago
attrs - 22.1.0
Highlights
The main features of this release are:
- The departure of Python 2.7 (enjoy your retirement!),
- and the arrival of Python 3.11.
We had loftier goals feature-wise, but didn't want to block others embracing Python 3.11.
❤️ Huge thanks to my GitHub sponsors, Tidelift subscribers, and Ko-fi buyers! ❤️
None of my projects would exist in their current form without you!
Full Changelog
Backwards-incompatible Changes
Python 2.7 is not supported anymore.
Dealing with Python 2.7 tooling has become too difficult for a volunteer-run project.
We have supported Python 2 more than 2 years after it was officially discontinued and feel that we have paid our dues. All version up to 21.4.0 from December 2021 remain fully functional, of course. #936
The deprecated
cmpattribute ofattrs.Attributehas been removed. This does not affect the cmp argument toattr.sthat can be used as a shortcut to set eq and order at the same time. #939
Changes
- Instantiation of frozen slotted classes is now faster. #898
- If an
eqkey is defined, it is also used before hashing the attribute. #909 - Added
attrs.validators.min_len(). #916 -
attrs.validators.deep_iterable()'s member_validator argument now also accepts a list of validators and wraps them in anattrs.validators.and_(). #925 - Added missing type stub re-imports for
attrs.convertersandattrs.filters. #931 - Added missing stub for
attr(s).cmp_using(). #949 -
attrs.validators._in()'sValueErroris not missing the attribute, expected options, and the value it got anymore. #951 - Python 3.11 is now officially supported. #969
- Python
Published by hynek over 3 years ago
attrs - 21.4.0
This is a quick bug fix release for a regression that causes coverage report fail under certain circumstances.
Full Changelog
Changes
- Fixed the test suite on PyPy3.8 where
cloudpickledoes not work. #892 - Fixed
coverage reportfor projects that useattrsand don't set a--source. #895, #896
- Python
Published by hynek about 4 years ago
attrs - 21.3.0
This is a big release in the history of attrs and finishes an arc that took way too long and also delayed this very overdue release. But it's done: import attrs that has been talked about for years[^issue], but fell victim to “just this one more thing” has finally landed.
From now on, modern attrs code looks like this:
```python from attrs import define
@define class HelloWorld: modern: bool = True ```
The define/field APIs have been around for over a year and were very popular, now the rest of the package followed suit. I'm very excited that attrs remains relevant and keeps evolving over now more than half a decade. If you're curious about some of the background, the docs now contain a short explanation and history lesson. As long as our users keep pushing us, we will keep pushing forward class generation in Python!
Big thanks to my GitHub Sponsors, Tidelift subscribers, and Ko-fi buyers that help me mustering the motivation for such long-running project!
Since the release took so long, there's more highlights than we can enumerate here, we'd just like to point out a breaking change in the new APIs: converters now run on setting attributes by default. If this is causing problems to you, you can disable that behavior by setting @define(on_setattr=[]).
[^issue]: I have an issue from 2018 that I wanted to "come back the moment this lands".
Full Changelog
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 ison_setattr=[attrs.setters.convert, attrs.setters.validate].This is unfortunately a breaking change, but it was an oversight, impossible to raise a
DeprecationWarningabout, and it's better to fix it now while the APIs are very fresh with few users. #835, #886import attrshas finally landed! As of this release, you can finally importattrsusing its proper name.Not all names from the
attrnamespace have been transferred; most notablyattr.sandattr.ibare missing. Seeattrs.defineandattrs.fieldif you haven't seen our next-generation APIs yet. A more elaborate explanation can be found On The Core API NamesThis feature is at least for one release provisional. We don't plan on changing anything, but such a big change is unlikely to go perfectly on the first strike.
The API docs have been mostly updated, but it will be an ongoing effort to change everything to the new APIs. Please note that we have not moved -- or even removed -- anything from
attr!Please do report any bugs or documentation inconsistencies! #887
Changes
-
attr.asdict(retain_collection_types=False)(default) dumps collection-esque keys as tuples. #646, #888 -
__match_args__are now generated to support Python 3.10's Structural Pattern Matching. This can be controlled by thematch_argsargument to the class decorators on Python 3.10 and later. On older versions, it is never added and the argument is ignored. #815 - If the class-level on_setattr is set to
attrs.setters.validate(default in@defineand@mutable) but no field defines a validator, pretend that it's not set. #817 - The generated
__repr__is significantly faster on Pythons with f-strings. #819 - Attributes transformed via
field_transformerare wrapped withAttrsClassagain. #824 - Generated source code is now cached more efficiently for identical classes. #828
- Added
attrs.converters.to_bool(). #830 -
attrs.resolve_types()now resolves types of subclasses after the parents are resolved. #842 #843 - Added new validators:
lt(val)(< val),le(va)(≤ val),ge(val)(≥ val),gt(val)(> val), andmaxlen(n). #845 -
attrsclasses are now fully compatible with cloudpickle (no need to disablerepranymore). #857 - Added new context manager
attrs.validators.disabled()and functionsattrs.validators.(set|get)_disabled(). They deprecateattrs.(set|get)_run_validators(). All functions are interoperable and modify the same internal state. They are not – and never were – thread-safe, though. #859 -
attrs.validators.matches_re()now accepts pre-compiled regular expressions in addition to pattern strings. #877
- Python
Published by hynek about 4 years ago
attrs - 21.2.0
Yesterday's 21.1.0 has unfortunately two regressions that we're fixing with today's 21.2.0 release:
- The new recursive mode for
attr.evolve()broke some use cases. attrsis not importable under Python 3.4 anymore. While 3.4 hasn't been supported for a while now, we don't want it throw errors after installation.
We've reverted the changes to attr.evolve() and added packaging metadata blocking Python 3.4.
Additionally, we are yanking 21.1.0 from PyPI. If you've pinned attrs to 21.1.0, this does not affect you in any way.
- Python
Published by hynek almost 5 years ago
attrs - 21.1.0
I am extremely excited to announce the release of attrs 21.1.0.
attrs is the direct ancestor of – and the inspiration for – dataclasses in the standard library and remains the more powerful option for creating regular classes without getting bogged down with writing identical boilerplate again and again: https://www.attrs.org/
Heartfelt thanks go to my generous GitHub sponsors, companies subscribing to attrs on Tidelift, and people who bought me a coffee on Ko-fi! Support like that makes me work on FOSS on a Saturday afternoon – especially when a release drags itself like this one! <3
While this release took a bit longer than I wished for, it comes with many exciting changes. The highlights alone are longer than a usual changelog:
- The next-generation APIs (
@attr.define,@attr.mutable,@attr.frozen,@attr.field) are deemed stable now. The old ones aren't going anywhere, but I encourage you to check the new ones out – they're much nicer! - pyright and pylance support: Eric Traut of Microsoft was kind enough to involve me in their work on the dataclass_transforms spec.
As a result, Microsoft's type checker pyright will work with this attrs release, and so will their Python language server pylance which should be exciting to VS Code users.
Currently it only supports a subset of attrs's features, but it's the most important ones and more will most likely follow. Some of the limitations are documented in our documentation on type annotations. - Customization of field comparison. This is something especially NumPy users have been asking for for a long time: you can now fully customize how a field is compared. We also ship a helper to avoid boilerplate code. So if you'd like to have an object with a NumPy array that compares correctly, this is the way:
```python import attr import numpy
@attr.define class C: anarray = attr.field(eq=attr.cmpusing(eq=numpy.array_equal)) ```
Check out the new documentation on comparison for details.
- To make it more ergonomic, I've decided to un-deprecate the cmp argument again, so you can customize eq and order in one go. Sorry about the trouble! The cmp attribute remains deprecated.
- New powerful __init__ helpers:
1. If attrs deduces you don't want it to write a __init__ for you, it will create an __attrs_init__ instead that you can call from your custom __init__.
2. If attrs finds a __attrs_pre_init__, it will call it without any arguments before doing any initializations. This is really only useful if you want to run super().__init__(), but that's a use-case people have asked for for years!
See Hooking Yourself Into Initialization for details.
- In preparation for the (rescinded) plan to make from __future__ import annotations the default in Python 3.10, attr.resolve_types() can now also be used to resolve types inside of field_transformers.
A Look Ahead
For the next release we've got even bigger plans! By stabilizing the next-generation APIs we can finally go the last step, I've been talking for years (yeah, sorry): import attrs.
attrs's playful APIs (@attr.s, @attr.ib) lost a bit of their charm as the scope of the package grew – especially after the introduction of type annotations.
While the old APIs aren't going anywhere, in the next feature release there will be additionally an attrs package that you can use as an alternative to attr. No more attr.Factory!
The new package gives us the opportunity to rethink the defaults of some functions. So if you have any pet peeves, please air them on #487.
Full Changelog
Deprecations
The long-awaited, much-talked-about, little-delivered
import attrsis finally upon us!Since the NG APIs have now been proclaimed stable, the next release of
attrswill allow you to actuallyimport attrs. We're taking this opportunity to replace some defaults in our APIs that made sense in 2015, but don't in 2021.So please, if you have any pet peeves about defaults in
attrs's APIs, now is the time to air your grievances in #487! We're not gonna get such a chance for a second time, without breaking our backward-compatibility guarantees, or long deprecation cycles. Therefore, speak now or forever hold you peace! #487The cmp argument to
attr.s()and attr.ib() has been undeprecated It will continue to be supported as syntactic sugar to set eq and order in one go.I'm terribly sorry for the hassle around this argument! The reason we're bringing it back is it's usefulness regarding customization of equality/ordering.
The
cmpattribute and argument onattr.Attributeremains deprecated and will be removed later this year. #773
Changes
It's now possible to customize the behavior of
eqandorderby passing in a callable. #435, #627The instant favorite next-generation APIs are not provisional anymore!
They are also officially supported by Mypy as of their 0.800 release.
We hope the next release will already contain an (additional) importable package called
attrs. #668, #786If an attribute defines a converter, the type of its parameter is used as type annotation for its corresponding
__init__parameter.If an
attr.converters.pipeis used, the first one's is used. #710Fixed the creation of an extra slot for an
attr.ibwhen the parent class already has a slot with the same name. #718__attrs__init__()will now be injected ifinit=False, or ifauto_detect=Trueand a user-defined__init__()exists.This enables users to do "pre-init" work in their
__init__()(such assuper().__init__()).__init__()can then delegate constructor argument processing toself.__attrs_init__(*args, **kwargs). #731bool(attr.NOTHING)is nowFalse. #732It's now possible to use
super()inside of properties of slotted classes. #747Allow for a
__attrs_pre_init__()method that -- if defined -- will get called at the beginning of theattrs-generated__init__()method. #750Added forgotten
attr.Attribute.evolve()to type stubs. #752attrs.evolve()now works recursively with nestedattrsclasses. #759Python 3.10 is now officially supported. #763
attr.resolve_types()now takes an optional attrib argument to work inside afield_transformer. #774ClassVars are now also detected if they come from typing-extensions. #782To make it easier to customize attribute comparison (#435), we have added the
attr.cmp_with()helper.See the new docs on comparison for more details. #787
Added provisional support for static typing in
pyrightvia the dataclass_transforms specification. Both thepyrightspecification andattrsimplementation may change in future versions of both projects.Your constructive feedback is welcome in both attrs#795 and pyright#1782. #796
- Python
Published by hynek almost 5 years ago
attrs - 20.3.0
Backward-incompatible Changes
attr.define(),attr.frozen(),attr.mutable(), andattr.field()remain provisional.This release does not change change anything about them and they are already used widely in production though.
If you wish to use them together with mypy, you can simply drop this plugin into your project.
Feel free to provide feedback to them in the linked issue #668.
We will release the
attrsnamespace once we have the feeling that the APIs have properly settled. #668
Changes
-
attr.s()now has a field_transformer hook that is called for allAttributes and returns a (modified or updated) list ofAttributeinstances.attr.asdict()has a value_serializer hook that can change the way values are converted. Both hooks are meant to help with data (de-)serialization workflows. #653 -
kw_only=Truenow works on Python 2. #700 -
raise fromnow works on frozen classes on PyPy. #703, #712 -
attr.asdict()andattr.astuple()now treatfrozensets likesets with regards to the retain_collection_types argument. #704 - The type stubs for
attr.s()andattr.make_class()are not missing the collect_by_mro argument anymore. #711
- Python
Published by hynek over 5 years ago
attrs - 20.2.0
Backward-incompatible Changes
attr.define(),attr.frozen(),attr.mutable(), andattr.field()remain provisional.This release fixes a bunch of bugs and ergonomics but they remain mostly unchanged.
If you wish to use them together with mypy, you can simply drop this plugin into your project.
Feel free to provide feedback to them in the linked issue #668.
We will release the
attrsnamespace once we have the feeling that the APIs have properly settled. #668
Changes
attr.define()et al now correct detect__eq__and__ne__. #671attr.define()et al\'s hybrid behavior now also works correctly when arguments are passed. #675It\'s possible to define custom
__setattr__methods on slotted classes again. #681In 20.1.0 we introduced the
inheritedattribute on theattr.Attributeclass to differentiate attributes that have been inherited and those that have been defined directly on the class.It has shown to be problematic to involve that attribute when comparing instances of
attr.Attributethough, because when sub-classing, attributes from base classes are suddenly not equal to themselves in a super class.Therefore the
inheritedattribute will now be ignored when hashing and comparing instances ofattr.Attribute. #684zope.interfaceis now a \"soft dependency\" when running the test suite; ifzope.interfaceis not installed when running the test suite, the interface-related tests will be automatically skipped. #685The ergonomics of creating frozen classes using
@define(frozen=True)and sub-classing frozen classes has been improved: you don\'t have to seton_setattr=Noneanymore. #687
- Python
Published by hynek over 5 years ago
attrs - 20.1.0
Backward-incompatible Changes
Python 3.4 is not supported anymore. It has been unsupported by the Python core team for a while now, its PyPI downloads are negligible, and our CI provider removed it as a supported option.
It\'s very unlikely that
attrswill break under 3.4 anytime soon, which is why we do not block its installation on Python 3.4. But we don\'t test it anymore and will block it once someone reports breakage. #608
Deprecations
Less of a deprecation and more of a heads up: the next release of
attrswill introduce anattrsnamespace. That means that you\'ll finally be able to runimport attrswith new functions that aren\'t cute abbreviations and that will carry better defaults.This should not break any of your code, because project-local packages have priority before installed ones. If this is a problem for you for some reason, please report it to our bug tracker and we\'ll figure something out.
The old
attrnamespace isn\'t going anywhere and its defaults are not changing -- this is a purely additive measure. Please check out the linked issue for more details.These new APIs have been added provisionally as part of #666 so you can try them out today and provide feedback. Learn more in the API docs. #408
Changes
Added
attr.resolve_types(). It ensures that all forward-references and types in string form are resolved into concrete types.You need this only if you need concrete types at runtime. That means that if you only use types for static type checking, you do not need this function. #288, #302
Added
@attr.s(collect_by_mro=False)argument that if set toTruefixes the collection of attributes from base classes.It\'s only necessary for certain cases of multiple-inheritance but is kept off for now for backward-compatibility reasons. It will be turned on by default in the future.
As a side-effect,
attr.Attributenow always has aninheritedattribute indicating whether an attribute on a class was directly defined or inherited. #428, #635On Python 3, all generated methods now have a docstring explaining that they have been created by
attrs. #506It is now possible to prevent
attrsfrom auto-generating the__setstate__and__getstate__methods that are required for pickling of slotted classes.Either pass
@attr.s(getstate_setstate=False)or pass@attr.s(auto_detect=True)and implement them yourself: ifattrsfinds either of the two methods directly on the decorated class, it assumes implicitlygetstate_setstate=False(and implements neither).This option works with dict classes but should never be necessary. #512, #513, #642
Fixed a
ValueError: Cell is emptybug that could happen in some rare edge cases. #590attrscan now automatically detect your own implementations and inferinit=False,repr=False,eq=False,order=False, andhash=Falseif you set@attr.s(auto_detect=True).attrswill ignore inherited methods. If the argument implies more than one method (e.g.eq=Truecreates both__eq__and__ne__), it\'s enough for one of them to exist andattrswill create neither.This feature requires Python 3. #607
Added
attr.converters.pipe(). The feature allows combining multiple conversion callbacks into one by piping the value through all of them, and retuning the last result.As part of this feature, we had to relax the type information for converter callables. #618
Fixed serialization behavior of non-slots classes with
cache_hash=True. The hash cache will be cleared on operations which make \"deep copies\" of instances of classes with hash caching, though the cache will not be cleared with shallow copies like those made bycopy.copy().Previously,
copy.deepcopy()or serialization and deserialization withpicklewould result in an un-initialized object.This change also allows the creation of
cache_hash=Trueclasses with a custom__setstate__, which was previously forbidden (#494). #620It is now possible to specify hooks that are called whenever an attribute is set after a class has been instantiated.
You can pass
on_setattrboth to@attr.s()to set the default for all attributes on a class, and to@attr.ib()to overwrite it for individual attributes.attrsalso comes with a new moduleattr.settersthat brings helpers that run validators, converters, or allow to freeze a subset of attributes. #645, #660Provisional APIs called
attr.define(),attr.mutable(), andattr.frozen()have been added.They are only available on Python 3.6 and later, and call
attr.s()with different default values.If nothing comes up, they will become the official way for creating classes in 20.2.0 (see above).
Please note that it may take some time until mypy -- and other tools that have dedicated support for
attrs-- recognize these new APIs. Please do not open issues on our bug tracker, there is nothing we can do about it. #666We have also provisionally added
attr.field()that supplantsattr.ib(). It also requires at least Python 3.6 and is keyword-only. Other than that, it only dropped a few arguments, but changed no defaults.As with
attr.s():attr.ib()is not going anywhere. #669
- Python
Published by hynek over 5 years ago
attrs - 19.3.0
See http://www.attrs.org/en/19.3.0/changelog.html.
- Python
Published by hynek about 6 years ago
attrs - 19.2.0
See http://www.attrs.org/en/19.2.0/changelog.html.
- Python
Published by hynek over 6 years ago
attrs - 19.1.0
See https://www.attrs.org/en/19.1.0/changelog.html.
- Python
Published by hynek over 6 years ago
attrs - 18.2.0
See https://www.attrs.org/en/18.2.0/changelog.html.
- Python
Published by hynek over 6 years ago
attrs - 18.1.0
See https://www.attrs.org/en/18.1.0/changelog.html.
- Python
Published by hynek over 6 years ago
attrs - 17.4.0
See https://www.attrs.org/en/17.4.0/changelog.html.
- Python
Published by hynek over 6 years ago
attrs - Docs only
See https://www.attrs.org/en/17.3.0.post2/changelog.html.
- Python
Published by hynek over 6 years ago
attrs - Minor typo in docs
No code changes, no new distributions.
- Python
Published by hynek over 8 years ago