attrs

Frameworks & LibrariesMIT

attrs release notes.

Latest 26.1.0 · by attrsWritten in PythonWebsitepython-attrs/attrsRSS

Release activity

Release activity — 2 releases across 2 days in the last year. Each cell is one day; darker means more releases that day. Older weeks are hidden at this screen width.
JunJulAugSep
SundayNo releases on May 24, 2026No releases on May 31, 2026No releases on Jun 7, 2026No releases on Jun 14, 2026No releases on Jun 21, 2026No releases on Jun 28, 2026No releases on Jul 5, 2026No releases on Jul 12, 2026No releases on Jul 19, 2026No releases on Jul 26, 2026No releases on Aug 2, 2026No releases on Aug 9, 2026No releases on Aug 16, 2026No releases on Aug 23, 2026No releases on Aug 30, 2026No releases on Sep 6, 2026
MondayNo releases on May 25, 2026No releases on Jun 1, 2026No releases on Jun 8, 2026No releases on Jun 15, 2026No releases on Jun 22, 2026No releases on Jun 29, 2026No releases on Jul 6, 2026No releases on Jul 13, 2026No releases on Jul 20, 2026No releases on Jul 27, 2026No releases on Aug 3, 2026No releases on Aug 10, 2026No releases on Aug 17, 2026No releases on Aug 24, 2026No releases on Aug 31, 2026No releases on Sep 7, 2026
TuesdayNo releases on May 26, 2026No releases on Jun 2, 2026No releases on Jun 9, 2026No releases on Jun 16, 2026No releases on Jun 23, 2026No releases on Jun 30, 2026No releases on Jul 7, 2026No releases on Jul 14, 2026No releases on Jul 21, 2026No releases on Jul 28, 2026No releases on Aug 4, 2026No releases on Aug 11, 2026No releases on Aug 18, 2026No releases on Aug 25, 2026No releases on Sep 1, 2026No releases on Sep 8, 2026
WednesdayNo releases on May 27, 2026No releases on Jun 3, 2026No releases on Jun 10, 2026No releases on Jun 17, 2026No releases on Jun 24, 2026No releases on Jul 1, 2026No releases on Jul 8, 2026No releases on Jul 15, 2026No releases on Jul 22, 2026No releases on Jul 29, 2026No releases on Aug 5, 2026No releases on Aug 12, 2026No releases on Aug 19, 2026No releases on Aug 26, 2026No releases on Sep 2, 2026
ThursdayNo releases on May 28, 2026No releases on Jun 4, 2026No releases on Jun 11, 2026No releases on Jun 18, 2026No releases on Jun 25, 2026No releases on Jul 2, 2026No releases on Jul 9, 2026No releases on Jul 16, 2026No releases on Jul 23, 2026No releases on Jul 30, 2026No releases on Aug 6, 2026No releases on Aug 13, 2026No releases on Aug 20, 2026No releases on Aug 27, 2026No releases on Sep 3, 2026
FridayNo releases on May 29, 2026No releases on Jun 5, 2026No releases on Jun 12, 2026No releases on Jun 19, 2026No releases on Jun 26, 2026No releases on Jul 3, 2026No releases on Jul 10, 2026No releases on Jul 17, 2026No releases on Jul 24, 2026No releases on Jul 31, 2026No releases on Aug 7, 2026No releases on Aug 14, 2026No releases on Aug 21, 2026No releases on Aug 28, 2026No releases on Sep 4, 2026
SaturdayNo releases on May 30, 2026No releases on Jun 6, 2026No releases on Jun 13, 2026No releases on Jun 20, 2026No releases on Jun 27, 2026No releases on Jul 4, 2026No releases on Jul 11, 2026No releases on Jul 18, 2026No releases on Jul 25, 2026No releases on Aug 1, 2026No releases on Aug 8, 2026No releases on Aug 15, 2026No releases on Aug 22, 2026No releases on Aug 29, 2026No releases on Sep 5, 2026

2 releases in the last year

Changelog

What changed from 25 to 26

26.1.0

Latest
Added 2
  • Add Attribute.alias_is_default flag to indicate whether the alias was auto-generated (True) or explicitly set by the user (False)
  • It is now possible to pass attrs instances in addition to attrs classes to attrs.fields()
Changed 3
  • Field aliases are now resolved before calling field_transformer, so transformers receive fully populated Attribute objects with usable alias values instead of None
  • The attrs.validators.disabled() contextmanager can now be nested
  • Frozen classes can set on_setattr=attrs.setters.NO_OP in addition to None
Fixed 1
  • Fix type annotations for attrs.validators.optional() so it no longer rejects tuples with more than one validator

From attrs

Highlights

The main outward change here only affects people using field transformers, but it should be a nice quality of life improvement!

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), Kraken Tech (@kraken-tech), Privacy Solutions GmbH (@privacy-solutions), FilePreviews (@filepreviews), Ecosystems (@ecosyste-ms), TestMu AI Open Source Office (Formerly LambdaTest) (@LambdaTest-Inc), Doist (@Doist), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).

Maintenance Sustainers

Buttondown (@buttondown), Christopher Dignam (@chdsbd), Magnus Watn (@magnuswatn), David Cramer (@dcramer), 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
  • Field aliases are now resolved before calling field_transformer, so transformers receive fully populated Attribute objects with usable alias values instead of None. The new Attribute.alias_is_default flag indicates whether the alias was auto-generated (True) or explicitly set by the user (False). #1509
Changes
  • Fix type annotations for attrs.validators.optional(), so it no longer rejects tuples with more than one validator. #1496
  • The attrs.validators.disabled() contextmanager can now be nested. #1513
  • Frozen classes can set on_setattr=attrs.setters.NO_OP in addition to None. #1515
  • It's now possible to pass attrs instances in addition to attrs classes to attrs.fields(). #1529

This release contains contributions from @bysiber, @DavidCEllis, @finite-state-machine, @hynek, @veeceey, and @vstinner.

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-26.1.0.tar.gz

and

$ gh attestation verify --owner python-attrs attrs-26.1.0-py3-none-any.whl
View originalPermalink
How 26.1.0 went

25.4.0

Added 2
  • Support for Python 3.14 and PEP 749
  • New experimental attrs.inspect(cls) function to inspect classes and return the effective class-wide parameters used by attrs
Changed 4
  • Class-level kw_only=True behavior is now consistent with dataclasses, where only attributes defined in that class that don't explicitly set kw_only=False are made keyword-only
  • attrs.validators.deep_mapping() now allows to leave out either key_validator or value_validator
  • attrs.validators.deep_iterator() and attrs.validators.deep_mapping() now accept lists and tuples for all validators and wrap them into attrs.validators.and_()
  • Performance of attrs.asdict() has been improved by 45–260%
Fixed 2
  • Values passed to the __init__() method of attrs classes are now correctly passed to __attrs_pre_init__() instead of their default values
  • Fixed annotations for attrs.field(converter=...) to accept a tuple of converters with any number of elements

From attrs

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=True behavior is now consistent with dataclasses.

    Previously, a class that sets kw_only=True makes all attributes keyword-only, including those from base classes. If an attribute sets kw_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=False are 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=True attrs class (Base) with an attribute that sets kw_only=False and has a default (Base.b), and then create a subclass (Subclass) with required arguments (Subclass.c). Previously this would work, since it would make Base.b keyword-only, but now this fails since Base.b is positional, and we have a required positional argument (Subclass.c) following another argument with defaults. #1457

Changes
  • Values passed to the __init__() method of attrs classes are now correctly passed to __attrs_pre_init__() instead of their default values (in cases where kw_only was not specified). #1427

  • Added support for Python 3.14 and PEP 749. #1446, #1451

  • attrs.validators.deep_mapping() now allows to leave out either key_validator xor value_validator. #1448

  • attrs.validators.deep_iterator() and attrs.validators.deep_mapping() now accept lists and tuples for all validators and wrap them into a attrs.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, a tuple of 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.gz

and

$ gh attestation verify --owner python-attrs attrs-25.4.0-py3-none-any.whl
View originalPermalink
How 25.4.0 went

25.3.0

Fixed 1
  • Restore support for generator-based field_transformers

From attrs

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.gz

and

$ gh attestation verify --owner python-attrs attrs-25.3.0-py3-none-any.whl
View originalPermalink
How 25.3.0 went

25.2.0

Added 1
  • attrs.make_class() now allows for Unicode class names
Changed 3
  • 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
  • Speed up class creation by 30%-50% by compiling methods only once and using a variety of other techniques
  • The error message if an attribute has both an annotation and a type argument will now disclose what attribute seems to be the problem
Deprecated 1
  • This is the last attrs version to support Python 3.8

From attrs

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.gz

and

$ gh attestation verify --owner python-attrs attrs-25.2.0-py3-none-any.whl
View originalPermalink
How 25.2.0 went

25.1.0

Changed 1
  • Ensure correct PyPI licensing metadata

From attrs

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.gz

and

$ gh attestation verify --owner python-attrs attrs-25.1.0-py3-none-any.whl
View originalPermalink
How 25.1.0 went

24.3.0

Added 2
  • Introduce attrs.NothingType, for annotating types consistent with attrs.NOTHING
  • attrs instances now support copy.replace()
Changed 2
  • Allow mutating __suppress_context__ and __notes__ on frozen exceptions
  • attrs.validators.instance_of()'s type hints now allow for union types
Fixed 1
  • attrs.converters.optional() works again when taking attrs.converters.pipe() or another Converter as its argument
Removed 1
  • Python 3.7 has been dropped

From attrs

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 with attrs.NOTHING. #1358
  • Allow mutating __suppress_context__ and __notes__ on frozen exceptions. #1365
  • attrs.converters.optional() works again when taking attrs.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.gz

and

$ gh attestation verify --owner python-attrs attrs-24.3.0-py3-none-any.whl
View originalPermalink
How 24.3.0 went

24.2.0

Fixed 2
  • attrs.converters.pipe() and passing a list for converter argument now works again when passing attrs.setters.convert to on_setattr
  • Restore support for PEP 649 / 749-implementing Pythons including Python 3.14-dev
Deprecated 1
  • Soft-deprecate the hash argument to @define / @attr.s in favor of not using it in new code

From attrs

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 for attrs.field()'s / attr.ib()'s converter argument) works again when passing attrs.setters.convert to on_setattr (which is default for attrs.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.gz

and

$ gh attestation verify --owner python-attrs attrs-24.2.0-py3-none-any.whl
View originalPermalink
How 24.2.0 went

24.1.0

Added 2
  • Wrap a converter into attrs.Converter to receive the current instance and/or the current field definition in the converter callable
  • Add __attrs_init_subclass__ as a replacement for __init_subclass__
Changed 5
  • Speed up generated __eq__ methods by generating a chain of attribute comparisons instead of constructing and comparing tuples
  • Allow original slotted functools.cached_property classes to be cleaned by garbage collection
  • Allow super() calls in slotted cached properties
  • Update type stubs to use modern type notation and organize them so VS Code's quick-fix prefers the attrs namespace
  • Preserve AttributeError raised by properties of slotted classes with functools.cached_properties
Removed 3
  • Remove attrs.evolve() acceptance of inst argument as a keyword argument; pass it as the first positional argument instead
  • Remove attrs.validators.provides()
  • Remove all packaging metadata except __version__ and __version_info__ from attr and attrs modules
Deprecated 2
  • Deprecate repr_ns argument to attr.s
  • Deprecate hash argument to @attr.s, @attrs.define, and make_class() in favor of unsafe_hash

From attrs

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 the attr and attrs modules (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, like float('nan'). #1310

Deprecations
  • The repr_ns argument to attr.s is 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, and make_class() is now deprecated in favor of unsafe_hash, as defined by PEP 681. #1323
Changes
  • Allow original slotted functools.cached_property classes to be cleaned by garbage collection. Allow super() 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 attrs namespace. #1234

  • Preserve AttributeError raised by properties of slotted classes with functools.cached_properties. #1253

  • It is now possible to wrap a converter into an attrs.Converter and 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 that attrs.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.gz

and

$ gh attestation verify --owner python-attrs attrs-24.1.0-py3-none-any.whl
View originalPermalink
How 24.1.0 went

23.2.0

Added 2
  • Slotted classes now transform functools.cached_property decorated methods to support equivalent semantics
  • Added class_body argument to attrs.make_class() to provide additional attributes for newly created classes
Changed 3
  • Type stubs now use typing.dataclass_transform to decorate dataclass-like decorators instead of the non-standard __dataclass_transform__ special form
  • attrs.AttrsInstance is now a typing.Protocol in both type hints and code, allowing you to subclass it along with another Protocol
  • If attrs detects that __attrs_pre_init__ accepts more than just self, it will call it with the same arguments as __init__ was called
Fixed 2
  • The type annotation for attrs.resolve_types() is now correct
  • Fixed serialization of namedtuple fields using attrs.asdict/astuple() with retain_collection_types=True

From 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.

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_transform to 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() with retain_collection_types=True. #1165
  • attrs.AttrsInstance is now a typing.Protocol in both type hints and code. This allows you to subclass it along with another Protocol. #1172
  • If attrs detects that __attrs_pre_init__ accepts more than just self, it will call it with the same arguments as __init__ was called. This allows you to, for example, pass arguments to super().__init__(). #1187
  • Slotted classes now transform functools.cached_property decorated 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
View originalPermalink
How 23.2.0 went

23.1.0

Added 1
  • Added type parameter to attrs.field() function for use with attrs.make_class()
Changed 8
  • Packaging switched to static package data using Hatch
  • attrs.filters.exclude() and attrs.filters.include() now support passing attribute names as strings
  • attrs.has() and attrs.fields() now handle generic classes correctly
  • attrs.frozen now works with type checkers that implement PEP-681
  • attrs.asdict() and attrs.astuple() type stubs now accept the attrs.AttrsInstance protocol
  • attrs.resolve_types() can now pass include_extras to typing.get_type_hints() on Python 3.9+ and does so by default
  • attrs.evolve() can now change fields named inst if the instance is passed as a positional argument
  • attrs.validators.optional() now also accepts a tuple of validators in addition to lists of validators
Fixed 3
  • Fix frozen exception classes when raised within contextlib.contextmanager which mutates their __traceback__ attributes
  • Restored ability to unpickle instances pickled before 22.2.0
  • Fix slots class cellvar updating closure in CPython 3.8+ even when __code__ introspection is unavailable
Removed 1
  • Python 3.6 support has been dropped
Deprecated 2
  • Support for zope-interface via the attrs.validators.provides validator is deprecated and will be removed in or after April 2024
  • Passing the instance to attrs.evolve() using the inst keyword argument is deprecated and will be removed in or after April 2024

From attrs

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
  • Python 3.6 has been dropped and packaging switched to static package data using Hatch. #993
Deprecations
  • The support for zope-interface via the attrs.validators.provides validator 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() and attrs.filters.include() now support the passing of attribute names as strings. #1068

  • attrs.has() and attrs.fields() now handle generic classes correctly. #1079

  • Fix frozen exception classes when raised within e.g. contextlib.contextmanager, which mutates their __traceback__ attributes. #1081

  • @frozen now 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 and attrs.astuple()'s type stubs now accept the attrs.AttrsInstance protocol. #1090

  • Fix slots class cellvar updating closure in CPython 3.8+ even when __code__ introspection is unavailable. #1092

  • attrs.resolve_types() can now pass include_extras to typing.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 with attrs.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() (and attr.evolve()) to change fields named inst if 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

View originalPermalink
How 23.1.0 went
View all

Discussion

If you publish attrs, you can claim this product by proving you administer its repository.