Upgrading attrs 24 to 25
Breaking24.3.0 → 25.4.0Breaking1Platform2New3Changed6Fixed4Other1
BreakingUpgrade verdict
1 breaking change and 2 platform requirement changes.
In plain terms
- Setting kw_only=True on a class no longer forces inherited attributes to be keyword-only, so some subclasses with required positional fields may now fail.
- The package now works on Python 3.14.
- Python 3.8 is supported for the last time in this release; future versions will drop it.
Must act 3 items need code or config changes
Python requirement changed in 25.4.0: >=3.8 → >=3.9.
What you must change
Breaking1
Class-level kw_only=True now matches dataclasses: only attributes defined in that class without explicit kw_only=False become keyword-only.
kw_onlyattrs.defineattrs.fieldPlatform2
Adds support for Python 3.14 and PEP 749.
This is the last attrs version to support Python 3.8.
API changes
Generated by DepDelta from published Python source. Not mixed with prose notes.
- changed:
function attrib(default: None=…, validator: None=…, repr: _ReprArgType=…, cmp: _EqOrderType | None=…, hash: bool | None=…, init: bool=…, metadata: Mapping[Any, Any] | None=…, type: None=…, converter: None=…, factory: None=…, kw_only: bool=…, eq: _EqOrderType | None=…, order: _EqOrderType | None=…, on_setattr: _OnSetAttrArgType | None=…, alias: str | None=…) -> Any | (default: None=…, validator: _… → function attrib(default: None=…, validator: None=…, repr: _ReprArgType=…, cmp: _EqOrderType | None=…, hash: bool | None=…, init: bool=…, metadata: Mapping[Any, Any] | None=…, type: None=…, converter: None=…, factory: None=…, kw_only: bool | None=…, eq: _EqOrderType | None=…, order: _EqOrderType | None=…, on_setattr: _OnSetAttrArgType | None=…, alias: str | None=…) -> Any | (default: None=…, valid…
- changed:
function deep_iterable(member_validator: _ValidatorArgType[_T], iterable_validator: _ValidatorType[_I] | None=…) -> _ValidatorType[_I] → function deep_iterable(member_validator: _ValidatorArgType[_T], iterable_validator: _ValidatorArgType[_I] | None=…) -> _ValidatorType[_I] - changed:
function deep_mapping(key_validator: _ValidatorType[_K], value_validator: _ValidatorType[_V], mapping_validator: _ValidatorType[_M] | None=…) -> _ValidatorType[_M] → function deep_mapping(key_validator: _ValidatorArgType[_K], value_validator: _ValidatorArgType[_V] | None=…, mapping_validator: _ValidatorArgType[_M] | None=…) -> _ValidatorType[_M] | (key_validator: _ValidatorArgType[_K] | None=…, value_validator: _ValidatorArgType[_V]=…, mapping_validator: _ValidatorArgType[_M] | None=…) -> _ValidatorType[_M] - changed:
function or_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T] → function or_(__v1: _ValidatorType[_T1], __v2: _ValidatorType[_T2]) -> _ValidatorType[_T1 | _T2] | (__v1: _ValidatorType[_T1], __v2: _ValidatorType[_T2], __v3: _ValidatorType[_T3]) -> _ValidatorType[_T1 | _T2 | _T3] | (__v1: _ValidatorType[_T1], __v2: _ValidatorType[_T2], __v3: _ValidatorType[_T3], __v4: _ValidatorType[_T4]) -> _ValidatorType[_T1 | _T2 | _T3 | _T4] | (__v1: _ValidatorType[_T1], __…
- changed:
function field(*, default: None=…, validator: None=…, repr: _ReprArgType=…, hash: bool | None=…, init: bool=…, metadata: Mapping[Any, Any] | None=…, converter: None=…, factory: None=…, kw_only: bool=…, eq: bool | None=…, order: bool | None=…, on_setattr: _OnSetAttrArgType | None=…, alias: str | None=…, type: type | None=…) -> Any | (*, default: None=…, validator: _ValidatorArgType[_T] | None=…, r… → function field(*, default: None=…, validator: None=…, repr: _ReprArgType=…, hash: bool | None=…, init: bool=…, metadata: Mapping[Any, Any] | None=…, converter: None=…, factory: None=…, kw_only: bool | None=…, eq: bool | None=…, order: bool | None=…, on_setattr: _OnSetAttrArgType | None=…, alias: str | None=…, type: type | None=…) -> Any | (*, default: None=…, validator: _ValidatorArgType[_T] | No… - added:
class ClassProps - added:
constructor ClassProps(is_exception: bool, is_slotted: bool, has_weakref_slot: bool, is_frozen: bool, kw_only: Any, collected_fields_by_mro: bool, added_init: bool, added_repr: bool, added_eq: bool, added_ordering: bool, hashability: Any, added_match_args: bool, added_str: bool, added_pickling: bool, on_setattr_hook: _OnSetAttrType, field_transformer: Callable[[Attribute[Any]], Attribute[Any]]) -… - added:
field ClassProps.Hashability: Any - added:
field ClassProps.KeywordOnly: Any - added:
field ClassProps.added_eq: bool - added:
field ClassProps.added_init: bool - added:
field ClassProps.added_match_args: bool - added:
field ClassProps.added_ordering: bool - added:
field ClassProps.added_pickling: bool - added:
field ClassProps.added_repr: bool - added:
field ClassProps.added_str: bool - added:
field ClassProps.collected_fields_by_mro: bool - added:
field ClassProps.field_transformer: Callable[[Attribute[Any]], Attribute[Any]] | None - added:
field ClassProps.has_weakref_slot: bool - added:
field ClassProps.hashability: Any - added:
field ClassProps.is_exception: bool - added:
field ClassProps.is_frozen: bool - added:
field ClassProps.is_slotted: bool - added:
field ClassProps.kw_only: Any - added:
field ClassProps.on_setattr_hook: _OnSetAttrType | None - added:
function inspect(cls: type) -> ClassProps - added:
property ClassProps.is_hashable -> bool