Basically, if @define is applied to a class def with a dunder attribute name, like __x__, then calling evolve on an instance of this class raises an exception. This is because evolve only removes the first_ leading underscore, whereas the generated __init__(self, x__=..., ...) removes all leading underscores.
The fix is to use lstrip(name, "_") in the evolve function.
I gather that Attribute will be getting an alias member, which evolve() will make use of, rather than doing the stripping on its own. This might fix the problem. At least if define() makes use of that feature without the class def having to use it explicitly.
A test case could be:
@attrs.define
class C:
__x__: int
__y__: int = 42
__z: int = 42 # mangled to _C__z.
C(0).evolve() # Should not raise an exception
See #1060.
Basically, if
@defineis applied to a class def with a dunder attribute name, like__x__, then callingevolveon an instance of this class raises an exception. This is becauseevolveonly removes the first_ leading underscore, whereas the generated__init__(self, x__=..., ...)removes all leading underscores.The fix is to use
lstrip(name, "_")in theevolvefunction.I gather that
Attributewill be getting analiasmember, whichevolve()will make use of, rather than doing the stripping on its own. This might fix the problem. At least ifdefine()makes use of that feature without the class def having to use it explicitly.A test case could be:
See #1060.