PFython / cleverdict

A JSON-friendly data structure which allows both object attributes and dictionary keys and values to be used simultaneously and interchangeably.
MIT License
101 stars 9 forks source link

Behaviour of @x.setter and @x.deleter #14

Closed PFython closed 3 years ago

PFython commented 3 years ago

In using a CleverDict instance to hold passwords (in conjunction with keyring) I noticed the setter and delete decorators didn't appear to be working:

    @property
    def password(self):
        return keyring.get_password(account, self.username)

    @password.setter
    def password(self, value):
        print("Setting!")
        keyring.set_password(account, self.username, value)

    @password.deleter
    def password(self):
        keyring.delete_password(account, username)
>>> value = "mysecret"
>>> keyring.set_password(CleverSession.choices[self.url], self.username, value)
>>> self.password
'mysecret'

# set
>>> self.password = "newpassword"
>>> self.password
'mysecret'
>>> self['password']
'newpassword'

# delete
>>> del self.password
>>> self.password
'mysecret'
>>> self['password']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Peter\AppData\Roaming\Python\Python39\site-packages\cleverdict\cleverdict.py", line 168, in __getitem__
    name = self.get_key(name)
  File "C:\Users\Peter\AppData\Roaming\Python\Python39\site-packages\cleverdict\cleverdict.py", line 310, in get_key
    raise KeyError(name)
KeyError: 'password'

So I'm just wondering if this is something that has to be worked around, a limitation of CleverDict, or if there's something even more Clever we can do in CleverDict itself so that @x.setter and @x.deleter work as expected right out of the box?

salabim commented 3 years ago

It is tricky to try and combine properties with setattr and getattr and getattribute. This stackoverflow article describes it quite well: https://stackoverflow.com/questions/15750522/class-properties-and-setattr

PFython commented 3 years ago

I reran this scenario against version 1.8.1 and it worked fine! Adding test to test_cleverdict.py and closing issue. Yay!