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
_______________________________________________
cython-devel mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cython-devel

Reply via email to