cdgriffith / Box

Python dictionaries with advanced dot notation access
https://github.com/cdgriffith/Box/wiki
MIT License
2.61k stars 106 forks source link

Ability to use getters/setters? #211

Closed aronchick closed 1 year ago

aronchick commented 3 years ago

Hi - LOVE box - just terrific software.

Is there any way to add a getter/setter to a particular field? I've tried subclassing box, but it's not working as intended. Specifically, I'm looking to valid if a path set on a value exists or not when it's set.

cdgriffith commented 3 years ago

Sorry for delay on any feedback on this idea. It's a great idea, and something I didn't know wasn't working.

I did some initial testing and confirmed the behavior. Did a little digging into why....then backed off because I really didn't want to do that much work. I still don't, but at least admitting it for time being :smile:

Example of the problem for future reference:

from box import Box

class MySubclass(Box):

    def __init__(self, *args, **kwargs):
        super(MySubclass, self).__init__(*args, **kwargs)
        self._my_field = None

    @property
    def my_field(self):
        return self._my_field

    @my_field.setter
    def my_field(self, data):
        print('SHOULD BE CALLED!')
        self._my_field = data

a = MySubclass()
a.my_field = 5

What seems to happen is my_field setter isn't called, as Box's __setattr__ is called fist and is unaware of it. So self._my_field is never set, instead is added to internal dict as designed. Then when my_field @property is called, it actually is being called correctly with the logic currently in __getattr__ so it would return None still, even after being set.

cdgriffith commented 1 year ago

Thanks @Serge45 for fixing this!

Adding this feature in Box 7! Please test and give feedback if possible pip install python-box[all]~=7.0.0rc0

cdgriffith commented 1 year ago

Added in 7.0.0