I found this interesting question on SO to combine multiple decorators in python to a single decorator.
I wanted to do the same thing in Cython. Typically, I have Cython codes that look like:
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cdef ar[dtype_t, ndim=2] sma_vec(ar[dtype_t, ndim=2] x, int m):
cdef int n
cdef Py_ssize_t i, j
...
or like
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef ar[dtype_t, ndim=2] sma_vec(ar[dtype_t, ndim=2] x, int m):
cdef int n
cdef Py_ssize_t i, j
...
and I tend to repeat these three decorators @cython.boundscheck(False)
, @cython.wraparound(False)
, @cython.cdivision(True)
pretty much everywhere.
The solution for regular Python given in that page is
def composed(*decs):
def deco(f):
for dec in reversed(decs):
f = dec(f)
return f
return deco
For Cython, I tried to do the following:
cdef composed_for_cdef(*decs):
cdef deco(f):
for dec in reversed(decs):
f = dec(f)
return f
return deco
and
cpdef composed_for_cpdef(*decs):
cpdef deco(f):
for dec in reversed(decs):
f = dec(f)
return f
return deco
but I got an error during compilation:
cdef composed_for_cdef(*decs):
cdef deco(f):
^
------------------------------------------------------------
stat\movavg.pyx:12:16: C function definition not allowed here
I even tried the solution for regular Python (given above), but I got an error:
@composed(cython.boundscheck(False), cython.wraparound(False), cython.cdivision(True))
^
------------------------------------------------------------
stat\movavg.pyx:24:0: Cdef functions/classes cannot take arbitrary decorators.