DanielSank / observed

Observer pattern in python
MIT License
33 stars 4 forks source link

observable properties doesn't work with python 3.5 #16

Open Carnou opened 7 years ago

Carnou commented 7 years ago

This is largely discussed at your answer on StackOverflow, but I'll summarize here.

Using the @observableMethod decorator on a method that is part of a property doesn't work in (c)python 3.5. Some problem occurs when the property is correctly bound to the class instance. For example,

class Bar(object):
    def __init__(self):
        self._bbb = "bar"
    @property
    def bbb(self):
        return self._bbb
    @bbb.setter
    @observable_method
    def setbbb(self, value):
            self._bbb = value

will cause the following error when you create an instance of Bar and try to set bar.bbb

Traceback (most recent call last): File "", line 1, in TypeError: 'ObservableMethodManager_PersistOnInstances' object is not callable

Using explicit properties as below causes the same issue:

class Bar(object):
    def __init__(self):
        self._bbb = "bar"
    def getbbb(self):
        return self._bbb
    @observable_method
        def setbbb(self, value):
            self._bbb = value
    bbb = property(getbbb, setbbb)

Interestingly, a hackneyed attempt where the property is completely distinct from the class doesn't have the issue. The following works:

class Bar(object):
    def __init__(self):
        self._bbb = "bar"
    def getbbb(self):
        return self._bbb
    @observable_method
    def setbbb(self, value):
        self._bbb = value

b = Bar()

prop = property(Bar.getbbb)
prop = prop.setter(Bar.setbbb)

def cb(val):
print("Called, {0}".format(val))

b.setbbb.add_observer(cb)
# >>> True
prop.__get__(b)
# >>> 'bar'
prop.__set__(b, 'BAR')
# >>> Called, BAR
b._bbb
# >>> 'BAR'
DanielSank commented 7 years ago

@Carnou did you wind up fixing this? Pull requests are always welcomed.

Carnou commented 7 years ago

@DanielSank, no, I never did. In the Stack Overflow chat, I said I should, but I never actually touched your code. I'm still making use of the subclass workaround, though!

Trezorro commented 3 years ago

Hi @DanielSank, any update on this? I was actually hoping to use your package because of this use case specifically!

DanielSank commented 3 years ago

@Trezorro I have not done any work on this issue. Would you like to try?

danieljfarrell commented 3 years ago

Lurker here: I tried to find out more information about python’s built in property decorator. It’s implemented in C so probably the only way forward here is to implements your own @property decorator which integrates with observed.

For instance, this is a reimplementation of python’s property decorator which introduces caching, https://github.com/pydanny/cached-property/blob/master/cached_property.py

I would use the above decorator and debug this. At least you have the code and can set breakpoints to see what is going on.