Dear attrs community members
One thing I implemented in autoclass that I feel is missing in attrs is the ability to automatically generate the property setter that includes validation. This might be optional, for example
import attr
from attr.validators import instance_of
@attr.s(validation_setters=True)
class C(object):
x = attr.ib(validator=instance_of(float))
would transform x into a property (+ a private field) behind the scenes, equivalent to
@attr.s(these={'_x': attr.ib(validator=instance_of(float))})
class C(object):
@property
def x(self):
return self._x
@x.setter
def set_x(self, val):
x_attr = attr.fields(C).x
x_attr.validator(self, x_attr, val)
self._x = val
Note that the above code right now throws an AttributeError: can't set attribute so this would need to be fixed first.
Do you think that it would make sense to add this feature ?
Thanks !
Well there have been quite a bit of requests that in the end ask for that: frozen single attributes and validation on setting. We haven鈥檛 quite decided which route to take though. :|
I think this is an interesting idea and we should probably support it eventually. Users are constantly surprised there's no validation when setting the attributes.
The main problem is it will make accessing the attribute slower too.
At some point we鈥檒l have to write a similar monstrous generator for __setattr__ as we now have for __init__. :(
Do you need help (=contribution) for this feature to be added ? I can have a look at what you did to generate __init__ and replicate for __setattr__. Just let me know if that work started or no yet, so that I know if I have to start from an existing branch or not.
regards
Sylvain
I think this is a bit dependent on #172
Makes sense if we want to be consistent - thanks Hynek, I'll follow that topic closely then.
It could be even easier just using setattr behaviour, isn't it?
def __setattr__(self, key, value):
"""
This method will magically add the normal validation when setting attributes
:param key:
:param value:
:return:
"""
x_attr = getattr(attr.fields(self.__class__), key)
if x_attr.validator:
x_attr.validator(self, x_attr, value)
super(MyAttrClassBase, self).__setattr__(key, value)
Stupid question : now that #172 is closed with wont fix, does that mean that this will not be fixed ?
No it does not! #172 wasn't closed as wont fix, but as "abandoned". I'd like to have first-class property support, there's even a related issue for that: #353
I have implement this: https://github.com/pwwang/attr_property
Welcome to test it and give feedback.
Note that you can now also use pyfields as a viable alternative to attrs to cover all these cases that are "non-nominal" for attrs (mutable objects requiring validation on value change, non-pure attrs objects, different validator style, etc.) ; of course it does not beat the master in terms of speed perfs :) but the overhead is very small.
Everyone interested in this please look at #645.
鈥nd now #660 that implements this
I believe this is fixed.