Releases: python-attrs/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.convert
to 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.gz
and
$ gh attestation verify --owner python-attrs attrs-24.2.0-py3-none-any.whl
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. #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 theattr
andattrs
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, likefloat('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
, andmake_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. 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
attrs
namespace. #1234 -
Preserve
AttributeError
raised by properties of slotted classes withfunctools.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 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.gz
and
$ gh attestation verify --owner python-attrs attrs-24.1.0-py3-none-any.whl
23.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_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()
withretain_collection_types=True
. #1165 attrs.AttrsInstance
is now atyping.Protocol
in 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_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
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.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()
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 -
@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 andattrs.astuple()
's type stubs now accept theattrs.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 passinclude_extras
totyping.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 namedinst
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
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.NOTHING
is now an enum value, making it possible to use with e.g.typing.Literal
. #983 -
Added missing re-import of
attr.AttrsInstance
to theattrs
namespace. #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 aTypeGuard
forAttrsInstance
. That means that type checkers know a class is an instance of anattrs
class if you check it usingattrs.has()
(orattr.has()
) first. #997 -
Made
attrs.AttrsInstance
stub available at runtime and fixed type errors related to the usage ofattrs.AttrsInstance
in 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 aValueError
orTypeError
(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
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
cmp
attribute ofattrs.Attribute
has been removed. This does not affect the cmp argument toattr.s
that 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
eq
key 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.converters
andattrs.filters
. #931 - Added missing stub for
attr(s).cmp_using()
. #949 attrs.validators._in()
'sValueError
is not missing the attribute, expected options, and the value it got anymore. #951- Python 3.11 is now officially supported. #969
21.4.0
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 years1, but fell victim to “just this one more thing” has finally landed.
From now on, modern attrs
code looks like this:
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=[])
.
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
DeprecationWarning
about, and it's better to fix it now while the APIs are very fresh with few users. #835, #886 -
import attrs
has finally landed! As of this release, you can finally importattrs
using its proper name.Not all names from the
attr
namespace have been transferred; most notablyattr.s
andattr.ib
are missing. Seeattrs.define
andattrs.field
if 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_args
argument 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@define
and@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_transformer
are wrapped withAttrsClass
again. #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 attrs
classes are now fully compatible with cloudpickle (no need to disablerepr
anymore). #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
-
I have an issue from 2018 that I wanted to "come back the moment this lands". ↩
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. attrs
is 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.
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:
import attr import numpy @attr.define class C: an_array = attr.field(eq=attr.cmp_using(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 customizeeq
andorder
in one go. Sorry about the trouble! Thecmp
attribute remains deprecated. -
New powerful
__init__
helpers:- 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__
. - 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 runsuper().__init__()
, but that's a use-case people have asked for for years!
See Hooking Yourself Into Initialization for details.
- If attrs deduces you don't want it to write a
-
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 offield_transformer
s.
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 attrs
is finally upon us!Since the NG APIs have now been proclaimed stable, the next release of
attrs
will 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! #487 -
The 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
cmp
attribute and argument onattr.Attribute
remains deprecated and will be removed later this year. #773
Changes
-
It's now possible to customize the behavior of
eq
andorder
by passing in a callable. #435, #627 -
The 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, #786 -
If an attribute defines a converter, the type of its parameter is used as type annotation for its corresponding
__init__
parameter.If an
attr.converters.pipe
is used, the first one's is used. #710 -
Fixed the creation of an extra slot for an
attr.ib
when the parent class already has a slot with the same name. #718 -
__attrs__init__()
will now be injected ifinit=False
, or ifauto_detect=True
and 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)
. #731 -
bool(attr.NOTHING)
is nowFalse
. #732 -
It's now possible to use
super()
inside of properties of slotted classes. #747 -
Allow for a
__attrs_pre_init__()
method that -- if defined -- will get called at the beginning of theattrs
-generated__init__()
method. #750 -
Added forgotten
attr.Attribute.evolve()
to type stubs. #752 -
attrs.evolve()
now works recursively with nestedattrs
classes. #759 -
Python 3.10 is now officially supported. #763
-
attr.resolve_types()
now takes an optional attrib argument to work inside afield_transformer
. #774 -
ClassVar
s are now also detected if they come from typing-extensions. #782 -
To 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
pyright
via the dataclass_transforms specification. Both thepyright
specification andattrs
implementation may change in future versions of both projects.Your constructive feedback is welcome in both attrs#795 and pyright#1782. #796