How to implement __setattr__ without infinite recursion
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
Re: How to implement __setattr__ without infinite recursion
@jimmo into the issue : py: object base class doesn't implement __setattr__ and __delattr__ #2755 i have already implemented this, can be this reuse?
Re: How to implement __setattr__ without infinite recursion
Well, where's the PR?jimmo wrote: ↑Thu Oct 03, 2019 8:43 amOh yeah, wholeheartedly agree!! Just got distracted by the puzzle, but I have already started doing exactly that (implementing object.__setattr__).pythoncoder wrote: ↑Thu Oct 03, 2019 7:37 am@jimmo These are clever solutions but a naive Python programmer would expect to use object.__setattr__() to break the recursion. Would implementing this be a major problem?
I wrote a piece of code today that worked nicely in CPython. It took a while to learn this object.__setattr__ trick. Anyway, I was quite sad when I got the first "AttributeError: 'super' object has no attribute '__setattr__'" exception.
Lucky I found this thread! I feel more okay now knowing that I wasn't fighting Python for nothing. Something's really missing.
I'd be happy to add it if you haven't got to it yet.
Re: How to implement __setattr__ without infinite recursion
Okay I patched something quick and it seems to work. It's late so I'll tidy it up and open a PR tomorrow.
I added an "object.__setattr__" function that basically does "mp_map_lookup(&self->members, attr, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;".
The following code now works:
An X object is created, nothing is printed and it has a "y" attribute.
"super(X, self).__setattr__" doesn't work yet though If I define it as a static method then object.__setattr__ works but the "super" trick doesn't.
If I remove the static method, then "super(X, self).__setattr__" works but object.__setattr__ is now rejected with "TypeError: argument should be a 'object' not a 'X'".
I added an "object.__setattr__" function that basically does "mp_map_lookup(&self->members, attr, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;".
The following code now works:
Code: Select all
class X(object):
def __init__(self):
object.__setattr__(self, "y", 5)
def __setattr__(self, attr, value):
print(attr, "=", value)
"super(X, self).__setattr__" doesn't work yet though If I define it as a static method then object.__setattr__ works but the "super" trick doesn't.
If I remove the static method, then "super(X, self).__setattr__" works but object.__setattr__ is now rejected with "TypeError: argument should be a 'object' not a 'X'".
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy