You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added `Attribute.reuse(**kwargs)`, which allows you to reuse (and simultaneously `evolve()`) attribute definitions from already defined classes:
2
+
3
+
```py
4
+
@define
5
+
classA:
6
+
a: int=100
7
+
8
+
@define
9
+
classB(A):
10
+
a = fields(B).a.reuse(default=200)
11
+
12
+
assert B().a ==200
13
+
```
14
+
15
+
To preserve attribute ordering of `reuse`d attributes, `inherited` was exposed as a public keyword argument to `attrib` and friends. Setting `inherited=True` manually on a *attrs* field definition simply acts as a flag to tell *attrs* to use the parent class ordering, *if* it can find an attribute in the parent MRO with the same name. Otherwise, the field is simply added to the class's attribute list as if `inherited=False`.
Copy file name to clipboardExpand all lines: docs/examples.md
+47Lines changed: 47 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -747,6 +747,53 @@ If you need to dynamically make a class with {func}`~attrs.make_class` and it ne
747
747
True
748
748
```
749
749
750
+
In certain situations, you might want to reuse part (or all) of an existing attribute instead of entirely redefining it. This pattern is common in inheritance schemes, where you might just want to change one parameter of an attribute (i.e. default value) while leaving all other parts unchanged. For this purpose, *attrs* offers {meth}`.Attribute.reuse`:
This method inherits all of the keyword arguments from {func}`~attrs.field`, which works identically to defining a new attribute with the same parameters.
771
+
772
+
While this feature is mostly intended for making working with inherited classes easier, there's nothing requiring `reuse`d attributes actually be part of a parent class:
773
+
774
+
```{doctest}
775
+
>>> @define
776
+
... class C: # does not inherit class `A`
777
+
... a = fields(A).a.reuse(factory=lambda: 100)
778
+
... # And now that `a` is in scope of `C`, field decorators work again:
779
+
... @a.validator
780
+
... def my_new_validator_func(self, attr, value):
781
+
... print("Another validator function!")
782
+
783
+
>>> C()
784
+
Validator runs!
785
+
Another validator function!
786
+
C(a=100)
787
+
```
788
+
789
+
This in combination with {func}`~attrs.make_class` makes a very powerful suite of *attrs* class manipulation tools both before and after class creation:
0 commit comments