Skip to content

Commit 9a98e00

Browse files
committed
Prepare 25.4.0
1 parent abe8284 commit 9a98e00

File tree

12 files changed

+59
-39
lines changed

12 files changed

+59
-39
lines changed

CHANGELOG.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,65 @@ Changes for the upcoming release can be found in the [`changelog.d` directory](h
1212

1313
<!-- towncrier release notes start -->
1414

15+
## [25.4.0](https://github.com/python-attrs/attrs/tree/25.4.0) - 2025-10-06
16+
17+
### Backwards-incompatible Changes
18+
19+
- Class-level `kw_only=True` behavior is now consistent with `dataclasses`.
20+
21+
Previously, a class that sets `kw_only=True` makes all attributes keyword-only, including those from base classes.
22+
If an attribute sets `kw_only=False`, that setting is ignored, and it is still made keyword-only.
23+
24+
Now, only the attributes defined in that class that doesn't explicitly set `kw_only=False` are made keyword-only.
25+
26+
This shouldn't be a problem for most users, unless you have a pattern like this:
27+
28+
```python
29+
@attrs.define(kw_only=True)
30+
class Base:
31+
a: int
32+
b: int = attrs.field(default=1, kw_only=False)
33+
34+
@attrs.define
35+
class Subclass(Base):
36+
c: int
37+
```
38+
39+
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`).
40+
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.
41+
[#1457](https://github.com/python-attrs/attrs/issues/1457)
42+
43+
44+
### Changes
45+
46+
- 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).
47+
[#1427](https://github.com/python-attrs/attrs/issues/1427)
48+
- Added support for Python 3.14 and [PEP 749](https://peps.python.org/pep-0749/).
49+
[#1446](https://github.com/python-attrs/attrs/issues/1446),
50+
[#1451](https://github.com/python-attrs/attrs/issues/1451)
51+
- `attrs.validators.deep_mapping()` now allows to leave out either *key_validator* xor *value_validator*.
52+
[#1448](https://github.com/python-attrs/attrs/issues/1448)
53+
- `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_()`.
54+
[#1449](https://github.com/python-attrs/attrs/issues/1449)
55+
- Added a new **experimental** way to inspect classes:
56+
57+
`attrs.inspect(cls)` returns the _effective_ class-wide parameters that were used by *attrs* to construct the class.
58+
59+
The returned class is the same data structure that *attrs* uses internally to decide how to construct the final class.
60+
[#1454](https://github.com/python-attrs/attrs/issues/1454)
61+
- Fixed annotations for `attrs.field(converter=...)`.
62+
Previously, a `tuple` of converters was only accepted if it had exactly one element.
63+
[#1461](https://github.com/python-attrs/attrs/issues/1461)
64+
- The performance of `attrs.asdict()` has been improved by 45–260%.
65+
[#1463](https://github.com/python-attrs/attrs/issues/1463)
66+
- The performance of `attrs.astuple()` has been improved by 49–270%.
67+
[#1469](https://github.com/python-attrs/attrs/issues/1469)
68+
- The type annotation for `attrs.validators.or_()` now allows for different types of validators.
69+
70+
This was only an issue on Pyright.
71+
[#1474](https://github.com/python-attrs/attrs/issues/1474)
72+
73+
1574
## [25.3.0](https://github.com/python-attrs/attrs/tree/25.3.0) - 2025-03-13
1675

1776
### Changes

changelog.d/1427.change.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

changelog.d/1446.change.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

changelog.d/1448.change.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

changelog.d/1449.change.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

changelog.d/1451.change.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

changelog.d/1454.change.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

changelog.d/1457.breaking.md

Lines changed: 0 additions & 22 deletions
This file was deleted.

changelog.d/1461.change.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

changelog.d/1463.change.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)