On Mon, Nov 8, 2010 at 10:13 AM, Darren Dale <[email protected]> wrote:
> On Mon, Nov 8, 2010 at 11:01 AM, Stefan Behnel <[email protected]> wrote:
>> Darren Dale, 08.11.2010 16:24:
>>> On Mon, Nov 8, 2010 at 10:05 AM, Stefan Behnel wrote:
>>>> Darren Dale, 08.11.2010 15:34:
>>>>> Python-2.6 extended the definition of property to include getter,
>>>>> setter, and deleter methods that can be used as decorators. This
>>>>> allows a really nice pattern for declaring properties without
>>>>> populating the namespace with a bunch of private methods:
>>>>>
>>>>> class Foo(object):
>>>>>
>>>>>       _bar = None
>>>>>       @property
>>>>>       def bar(self):
>>>>>           return self._bar
>>>>>       @bar.setter
>>>>>       def bar(self, val):
>>>>>           self._bar = val
>>>>>
>>>>> What happens is @bar.setter makes a copy of bar, updates the copy to
>>>>> use the decorated method as the setter, and returns the copy, which is
>>>>> then bound to the name of the decorated function. The decorated
>>>>> function has to be called bar, so that the updated copy is bound to
>>>>> bar, replacing the original.
>>>>>
>>>>> Attempting to cythonize this example yields an error:
>>>>>
>>>>> $ python setup.py build_ext --inplace
>>>>> running build_ext
>>>>> cythoning test_property.pyx to test_property.c
>>>>>
>>>>> Error converting Pyrex file to C:
>>>>> ------------------------------------------------------------
>>>>> ...
>>>>>       _bar = None
>>>>>       @property
>>>>>       def bar(self):
>>>>>           return self._bar
>>>>>       @bar.setter
>>>>>       def bar(self, val):
>>>>>      ^
>>>>> ------------------------------------------------------------
>>>>>
>>>>> /Users/darren/temp/test/test_property.pyx:11:4: 'bar' already declared
>>>>>
>>>>> Would it be possible for Cython to support this pattern?
>>>>
>>>> The problem is not the property behaviour, it's the mapping from a Python
>>>> function/method to a C function, which must have a unique name. Currently,
>>>> functions are unique within one namespace, be it the module namespace or a
>>>> class body namespace. They are actually looked up statically, not
>>>> dynamically in definition order, so the fix is not as easy as adding a
>>>> counted ID to the C-level name.
>>>>
>>>> The above might actually work if you change one of the method names, i.e.
>>>> either the getter or setter name. If it works as you say, the setter name
>>>> shouldn't have any impact on the result.
>>>
>>> Sorry, I should have emphasized the point about the importance of the
>>> setter name. It *must* be the same as the original property.
>>>
>>> class Foo(object):
>>>
>>>      _bar = None
>>>     �...@property
>>>      def bar(self):
>>>          return self._bar
>>>     �[email protected]
>>>      def bar_(self, val):
>>>          self._bar = val
>>>
>>> That produces a class with two properties: bar and bar_. Foo.bar is a
>>> property with a getter but no setter. Foo.bar_ is a property with a
>>> getter and a setter.
>>
>> Renaming the getter works for me, though:
>>
>>     class Foo(object):
>>         _bar = None
>>
>>         @property
>>         def bar_(self):
>>             return self._bar
>>
>>         @bar_.setter
>>         def bar(self, val):
>>             self._bar = val
>>
>>         del bar_
>>
>>     f = Foo()
>>     print f.bar
>>     f.bar = 5
>>     print f.bar
>>
>>     try:
>>         Foo.bar_
>>     except AttributeError:
>>         pass
>>     except:
>>         print "hoppsa!"
>>
>> I admit that it's ugly to do a "del bar_" at the end, but it's not more
>> than a work-around after all...
>
> Oh, that's what you meant. I suppose that is a reasonable workaround.
> Is issue 489 solvable?

Yes, but it won't be a quick fix.

- Robert
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to