Releases: python-attrs/attrs
25.4.0
Highlights
The main reason for this release (and why it's published today) is that it ships the first pieces of work for Python 3.14 and PEP 749. There will be more work required and there's going to be a lot more churn once everyone starts testing 3.14 earnestly. We hope to receive more feedback before spending more time on this.
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), Privacy Solutions GmbH (@privacy-solutions), Quesma (@QuesmaOrg), FilePreviews (@filepreviews), Doist (@Doist), 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), Celebrity News AG (@celebritynewsag), 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).
Full Changelog
Backwards-incompatible Changes
-
Class-level
kw_only=Truebehavior is now consistent withdataclasses.Previously, a class that sets
kw_only=Truemakes all attributes keyword-only, including those from base classes. If an attribute setskw_only=False, that setting is ignored, and it is still made keyword-only.Now, only the attributes defined in that class that doesn't explicitly set
kw_only=Falseare made keyword-only.This shouldn't be a problem for most users, unless you have a pattern like this:
@attrs.define(kw_only=True) class Base: a: int b: int = attrs.field(default=1, kw_only=False) @attrs.define class Subclass(Base): c: int
Here, we have a
kw_only=Trueattrs class (Base) with an attribute that setskw_only=Falseand has a default (Base.b), and then create a subclass (Subclass) with required arguments (Subclass.c). Previously this would work, since it would makeBase.bkeyword-only, but now this fails sinceBase.bis positional, and we have a required positional argument (Subclass.c) following another argument with defaults. #1457
Changes
-
Values passed to the
__init__()method ofattrsclasses are now correctly passed to__attrs_pre_init__()instead of their default values (in cases where kw_only was not specified). #1427 -
attrs.validators.deep_mapping()now allows to leave out either key_validator xor value_validator. #1448 -
attrs.validators.deep_iterator()andattrs.validators.deep_mapping()now accept lists and tuples for all validators and wrap them into aattrs.validators.and_(). #1449 -
Added a new experimental way to inspect classes:
attrs.inspect(cls)returns the effective class-wide parameters that were used by attrs to construct the class.The returned class is the same data structure that attrs uses internally to decide how to construct the final class. #1454
-
Fixed annotations for
attrs.field(converter=...). Previously, atupleof converters was only accepted if it had exactly one element. #1461 -
The performance of
attrs.asdict()has been improved by 45–260%. #1463 -
The performance of
attrs.astuple()has been improved by 49–270%. #1469 -
The type annotation for
attrs.validators.or_()now allows for different types of validators.This was only an issue on Pyright. #1474
This release contains contributions from @A5rocks, @carltongibson, @eendebakpt, @finite-state-machine, @huzecong, @hynek, @JelleZijlstra, @ProfDoof, @redruin1, @Tinche, and @zed.
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:
$ gh attestation verify --owner python-attrs attrs-25.4.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-25.4.0-py3-none-any.whl25.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:
$ gh attestation verify --owner python-attrs attrs-25.3.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-25.3.0-py3-none-any.whl25.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:
$ gh attestation verify --owner python-attrs attrs-25.2.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-25.2.0-py3-none-any.whl25.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:
$ gh attestation verify --owner python-attrs attrs-25.1.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-25.1.0-py3-none-any.whl24.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:
$ gh attestation verify --owner python-attrs attrs-24.3.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-24.3.0-py3-none-any.whl24.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 artifact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:
$ gh attestation verify --owner python-attrs attrs-24.2.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-24.2.0-py3-none-any.whl24.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. #1264 -
attrs.validators.provides()has been removed. The removed code is available as a gist for convenient copy and pasting. #1265 -
All packaging metadata except from
__version__and__version_info__has been removed from theattrandattrsmodules (for example,attrs.__url__).Please use
importlib.metadataor 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. #1221 -
Our type stubs now use modern type notation and are organized such that VS Code's quick-fix prefers the
attrsnamespace. #1234 -
Preserve
AttributeErrorraised by properties of slotted classes withfunctools.cached_properties. #1253 -
It 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. #1285 -
Added the
attrs.validators.or_()validator. #1303 -
The combination of a
__attrs_pre_init__that takes arguments, a kw-only field, and a default on that field does not crash anymore. #1319 -
attrs.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:
$ gh attestation verify --owner python-attrs attrs-24.1.0.tar.gzand
$ gh attestation verify --owner python-attrs attrs-24.1.0-py3-none-any.whl23.2.0
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.
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), 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
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. #1068 -
attrs.has()andattrs.fields()now handle generic classes correctly. #1079 -
Fix 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). #1084 -
Restored ability to unpickle instances pickled before 22.2.0. #1085
-
attrs.asdict()'s andattrs.astuple()'s type stubs now accept theattrs.AttrsInstanceprotocol. #1090 -
Fix slots class cellvar updating closure in CPython 3.8+ even when
__code__introspection is unavailable. #1092 -
attrs.resolve_types()can now passinclude_extrastotyping.get_type_hints()on Python 3.9+, and does so by default. #1099 -
Added instructions for pull request workflow to
CONTRIBUTING.md. #1105 -
Added 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
instkeyword 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
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. #983 -
Added missing re-import of
attr.AttrsInstanceto theattrsnamespace. #987 -
Fix slight performance regression in classes with custom
__setattr__and speedup even more. #991 -
Class-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. #997 -
Made
attrs.AttrsInstancestub available at runtime and fixed type errors related to the usage ofattrs.AttrsInstancein Pyright. #999 -
On Python 3.10 and later, call
abc.update_abstractmethods()on dict classes after creation. This improves the detection of abstractness. #1001 -
attrs'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). #1010 -
The type stubs for
attrs.cmp_using()now have default values. #1027 -
To conform with PEP 681,
attr.s()andattrs.define()now accept unsafe_hash in addition to hash. #1065