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?
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to