python-interface icon indicating copy to clipboard operation
python-interface copied to clipboard

Default implementation for Interface property setters

Open diogo-rossi opened this issue 3 years ago • 1 comments

Hi @ssanderson, congratulations for this package! (btw, it should be included in python's stdlib)

I'd like to tell there may be an issue when there is a default property setter.

from interface import Interface, implements, default

class Person(Interface):
    
    def set_name(self, value):
        pass
    
    def get_name(self):
        pass
    
    @default
    @property
    def name(self):
        return self.get_name()
    
    @default
    @name.setter
    def name(self,value):
        self.set_name(value)

class MyPerson(implements(Person)):
    
    def set_name(self, value):
        self._name = value
    
    def get_name(self):
        return self._name

The above code leads to the following

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File [...]:9, in <module>
      6 from __future__ import annotations
      7 from interface import Interface, default, implements
----> 9 class MultiInputDialogInterface(Interface):
     11     @default
     12     @property
     13     def windowtitle(self) -> str:
     14         return "Multiple Input Dialog"

File [...]:17, in MultiInputDialogInterface()
     11 @default
     12 @property
     13 def windowtitle(self) -> str:
     14     return "Multiple Input Dialog"
     16 @default
---> 17 @windowtitle.setter
     18 def windowtitle(self, title: str) -> None:
     19     raise NotImplementedError
     21 @default
     22 def set_windowtitle(self, value:str) -> MultiInputDialogInterface:

AttributeError: 'default' object has no attribute 'setter'

Is that ok or did I miss something?

diogo-rossi avatar Apr 04 '22 11:04 diogo-rossi

Well, I solved it adding the @default decorator only to te setter method.

Is that the desired behaviour?

This code is running fine:

from interface import Interface, implements, default

class Person(Interface):
    
    def set_name(self, value):
        pass
    
    def get_name(self):
        pass
    
    @property
    def name(self):
        print('getting name, which is:')
        return self.get_name()
    
    @default
    @name.setter
    def name(self,value):
        print('setting name to:',value)
        self.set_name(value)

class MyPerson(implements(Person)):
    
    def set_name(self, value):
        self._name = value
    
    def get_name(self):
        return self._name

p = MyPerson()
p.name = 'John Doe'
print(p.name)

The output is:

setting name to: John Doe
getting name, which is:
John Doe

diogo-rossi avatar Apr 04 '22 11:04 diogo-rossi