114 curated breaking changes across major versions of attrs. Use this as a migration checklist before bumping dependencies.
When using `@define`, converters are now run by default when setting an attribute on an instance -- additionally to validators.
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.
`attr.asdict(retain_collection_types=False)` (default) dumps collection-esque keys as tuples.
`attrs.resolve_types()` now resolves types of subclasses after the parents are resolved.
`__match_args__` are now generated to support Python 3.10's
The generated `__repr__` is significantly faster on Pythons with f-strings.
Attributes transformed via `field_transformer` are wrapped with `AttrsClass` again.
Generated source code is now cached more efficiently for identical classes.
Added `attrs.converters.to_bool()`.
Added new validators: `lt(val)` (\< val), `le(va)` (≤ val), `ge(val)` (≥ val), `gt(val)` (> val), and `maxlen(n)`.
`attrs` classes are now fully compatible with [cloudpickle](https://github.com/cloudpipe/cloudpickle) (no need to disable `repr` anymore).
Added new context manager `attrs.validators.disabled()` and functions `attrs.validators.(set|get)_disabled()`.
`attrs.validators.matches_re()` now accepts pre-compiled regular expressions in addition to pattern strings.
`import attrs` has finally landed!
Python 3.4 is now blocked using packaging metadata because `attrs` can't be imported on it anymore.
We had to revert the recursive feature for `attr.evolve()` because it broke some use-cases -- sorry!
The type stubs for `attr.s()` and `attr.make_class()` are not missing the *collect_by_mro* argument anymore.
`attr.asdict()` and `attr.astuple()` now treat `frozenset`s like `set`s with regards to the *retain_collection_types* argument.
`attr.s()` now has a *field_transformer* hook that is called for all `Attribute`s and returns a (modified or updated) list of `Attribute` instances.
`attr.define()`, `attr.frozen()`, `attr.mutable()`, and `attr.field()` remain **provisional**.
`kw_only=True` now works on Python 2.
`raise from` now works on frozen classes on PyPy.
`attr.define()` et al's hybrid behavior now also works correctly when arguments are passed.
The ergonomics of creating frozen classes using `@define(frozen=True)` and sub-classing frozen classes has been improved:
`attr.define()`, `attr.frozen()`, `attr.mutable()`, and `attr.field()` remain **provisional**.
`attr.define()` et al now correctly detect `__eq__` and `__ne__`.
It's possible to define custom `__setattr__` methods on slotted classes again.
In 20.1.0 we introduced the `inherited` attribute on the `attr.Attribute` class to differentiate attributes that have been inherited and those that have been defined directly on the class.
`zope.interface` is now a "soft dependency" when running the test suite; if `zope.interface` is not installed when running the test suite, the interface-related tests will be automatically skipped.
**Provisional** APIs called `attr.define()`, `attr.mutable()`, and `attr.frozen()` have been added.
Added `@attr.s(collect_by_mro=False)` argument that if set to `True` fixes the collection of attributes from base classes.
Fixed serialization behavior of non-slots classes with `cache_hash=True`.
It is now possible to prevent `attrs` from auto-generating the `__setstate__` and `__getstate__` methods that are required for pickling of slotted classes.
Fixed a `ValueError: Cell is empty` bug that could happen in some rare edge cases.
`attrs` can now automatically detect your own implementations and infer `init=False`, `repr=False`, `eq=False`, `order=False`, and `hash=False` if you set `@attr.s(auto_detect=True)`.
Added `attr.converters.pipe()`.
It is now possible to specify hooks that are called whenever an attribute is set **after** a class has been instantiated.
We have also provisionally added `attr.field()` that supplants `attr.ib()`.
Added `attr.resolve_types()`.
On Python 3, all generated methods now have a docstring explaining that they have been created by `attrs`.
Python 3.4 is not supported anymore.
Less of a deprecation and more of a heads up: the next release of `attrs` will introduce an `attrs` namespace.
Added `attr.__version_info__` that can be used to reliably check the version of `attrs` and write forward- and backward-compatible code.
`__lt__`, `__le__`, `__gt__`, and `__ge__` do not consider subclasses comparable anymore.
Keyword-only attributes (`kw_only=True`) and attributes that are excluded from the `attrs`'s `__init__` (`init=False`) now can appear before mandatory attributes.
The fake filename for generated methods is now more stable.
The value passed to `@attr.ib(repr=…)` can now be either a boolean (as before) or a callable.
Updated `attr.validators.__all__` to include new validators added in [#425].
Slotted classes now use a pure Python mechanism to rewrite the `__class__` cell when rebuilding the class, so `super()` works even on environments where `ctypes` is not installed.
Fixed `attr.validators.deep_iterable()` and `attr.validators.deep_mapping()` type stubs.
`attr.validators.is_callable()` validator now raises an exception `attr.exceptions.NotCallableError`, a subclass of `TypeError`, informing the received value.
`@attr.s(auto_exc=True)` now generates classes that are hashable by ID, as the documentation always claimed it would.
Added `attr.validators.matches_re()` that checks string attributes whether they match a regular expression.
The `cmp` argument to `attr.s()` and `attr.ib()` is now deprecated.
When collecting attributes using `@attr.s(auto_attribs=True)`, attributes with a default of `None` are now deleted too.
Removed deprecated `Attribute` attribute `convert` per scheduled removal on 2019/1.
Add `is_callable`, `deep_iterable`, and `deep_mapping` validators.
Fixed a bug where deserialized objects with `cache_hash=True` could have incorrect hash code values.
`is_callable`: validates that a value is callable
`deep_iterable`: Allows recursion down into an iterable,
`deep_mapping`: Allows recursion down into the items in a mapping object,
Fixed stub files to prevent errors raised by mypy's `disallow_any_generics = True` option.
Attributes with `init=False` now can follow after `kw_only=True` attributes.
`attrs` now has first class support for defining exception classes.
Clarified documentation for hashing to warn that hashable objects should be deeply immutable (in their usage, even if this is not enforced).
`attr.ib`’s *metadata* argument now defaults to a unique empty `dict` instance instead of sharing a common empty `dict` for all.
Generated `__hash__` methods now hash the class type along with the attribute values.
`ctypes` is optional now however if it's missing, a bare `super()` will not work in slotted classes.
The traversal of MROs when using multiple inheritance was backward:
All generated methods now have correct `__module__`, `__name__`, and (on Python 3) `__qualname__` attributes.
The attribute redefinition feature introduced in 17.3.0 now takes into account if an attribute is redefined via multiple inheritance.
Equality tests are *much* faster now.
Subclasses of `auto_attribs=True` can be empty now.
The `attr.ib(convert=callable)` option is now deprecated in favor of `attr.ib(converter=callable)`.
The `__repr__` set by `attrs` no longer produces an `AttributeError` when the instance is missing some of the specified attributes (either through deleting or after using `init=False` on some attributes).
Added *type* argument to `attr.ib()` and corresponding `type` attribute to `attr.Attribute`.
`super()` and `__class__` now work with slotted classes on Python 3.
The combination of `str=True` and `slots=True` now works on Python 2.
`attr.Factory` is hashable again.
Subclasses now can overwrite attribute definitions of their base classes.
Added new option *auto_attribs* to `@attr.s` that allows to collect annotated fields without setting them to `attr.ib()`.
Instances of classes created using `attr.make_class()` can now be pickled.
Attributes are no longer defined on the class body.
For convenience, the *validator* argument of `@attr.s` now can take a list of validators that are wrapped using `and_()`.
Correspondingly, `attr.ib`'s *hash* argument is `None` by default too and mirrors the *cmp* argument as it should.
`attr.make_class()` now accepts the keyword argument `bases` which allows for subclassing.
Added `attr.evolve()` that, given an instance of an `attrs` class and field changes as keyword arguments, will instantiate a copy of the given instance with the changes applied.
`attr.Factory()` now has a *takes_self* argument that makes the initializer to pass the partially initialized instance into the factory.
Default factories can now also be defined inline using decorators.
Fix default hashing behavior.
`attrs` will set the `__hash__()` method to `None` by default now.
Validators can now be defined conveniently inline by using the attribute as a decorator.
Frozen-ness of classes is now inherited.
`__attrs_post_init__()` is now run if validation is disabled.
Added `attr.validators.in_(options)` that, given the allowed `options`, checks whether the attribute value is in it.
Added `attr.validators.and_()` that composes multiple validators into one.
Accordingly, `attr.validators.optional()` now can take a list of validators too.
Conversion can now be made optional using `attr.converters.optional()`.
Metaclasses are now preserved with `slots=True`.
`attr.assoc()` is now deprecated in favor of `attr.evolve()` and will stop working in 2018.
`FrozenInstanceError` is now raised when trying to delete an attribute from a frozen class.
`attr.asdict()`'s `dict_factory` arguments is now propagated on recursion.
All instances where function arguments were called `cl` have been changed to the more Pythonic `cls`.
`attr.asdict()` now takes `retain_collection_types` as an argument.
Add `attr.attrs` and `attr.attrib` as a more consistent aliases for `attr.s` and `attr.ib`.
`attr.asdict()`, `attr.has()` and `attr.fields()` are significantly faster.
Add *frozen* option to `attr.s` that will make instances best-effort immutable.
Accessing `Attribute` instances on class objects is now deprecated and will stop working in 2017.
The serious-business aliases `attr.attributes` and `attr.attr` have been deprecated in favor of `attr.attrs` and `attr.attrib` which are much more consistent and frankly obvious in hindsight.
`attr.asdict()` can now produce arbitrary mappings instead of Python `dict`s when provided with a `dict_factory` argument.
Multiple performance improvements.
`__slots__` have arrived!
Python 3.3 and 2.6 are no longer supported.
Allow the case of initializing attributes that are set to `init=False`.
Get this data programmatically \u2014 free, no authentication.
curl https://depscope.dev/api/breaking/pypi/attrs