[Cython] Problems with decorated methods in cdef classes

Stefan Behnel stefan_ml at behnel.de
Mon Aug 22 13:36:33 CEST 2011


Robert Bradshaw, 17.08.2011 08:02:
> On Sun, Aug 14, 2011 at 8:02 AM, Stefan Behnel wrote:
>> def print_args(func):
>>     def f(*args, **kwds):
>>         print "args", args, "kwds", kwds
>>         return func(*args, **kwds)
>>     return f
>>
>> cdef class Num:
>>     @print_args
>>     def is_prime(self, bint print_factors=False):
>>         ...
>>
>> Now, the problem is that Cython considers "is_prime" to be a method of a
>> cdef class, although it actually is not. It's only an arbitrary function
>> that happens to be defined inside of a cdef class body and that happens to
>> be *called* by a method, namely "f". It now crashes for me because the
>> "self" argument is not being passed into is_prime() as a C method argument
>> when called by the wrapper function - and that's correct, because it's not a
>> method call but a regular function call at that point.
>>
>> The correct way to fix this is to turn all decorated methods in cdef classes
>> into plain functions. However, this has huge drawbacks, especially that the
>> first argument ('self') can no longer be typed as the surrounding extension
>> type. But, after all, you could do this:
>>
>> def swap_args(func):
>>     def f(*args):
>>         return func(*args[::-1])
>>     return f
>>
>> cdef class Num:
>>     @swap_args
>>     def is_prime(arg, self):
>>         ...
>>
>> I'm not sure what to make of this. Does it make sense to go this route? Or
>> does anyone see a way to make this "mostly" work, e.g. by somehow
>> restricting cdef classes and their methods? Or should we just add runtime
>> checks to prevent bad behaviour of decorators?
>
> I would be happy in making decorated methods into "ordinary"
> functions--this will probably play more nicely with many real-world
> decorators as well.

I created a ticket for this:

http://trac.cython.org/cython_trac/ticket/719

Stefan


More information about the cython-devel mailing list