I have a problem cythonizing my python code. I tried to reproduce the most simple case of the error i'm getting.
Here is the illustration of the code i want to cythonize:
def some_decorator_with_arg(arg):
def decorator(func):
def wrapper(x):
return func(x) + arg
return wrapper
return decorator
class some_class():
def __init__(self):
pass
@staticmethod
@some_decorator_with_arg(1)
def some_method(a):
return a
print(some_class().some_method(1))
This works without problems in pure python. But when i cythonize this code it throws an error on the run time:
print(some_class().some_method(1))
TypeError: wrapper() takes exactly one argument (2 given)
Compilation runs without problem. If i write @some_decorator_with_arg(arg=1)
I get another error:
@some_decorator_with_arg(arg=1)
TypeError: some_decorator_with_arg() takes no keyword arguments
Does someone know a workaround this problem?
I found the simplest way to solve the problem - combine the functionality of the two (or more) decorators into one, then cython does not have a problem. For example for the case above, i would do the following:
def some_decorator_with_arg(arg):
def decorator(func):
def wrapper(x):
return func(x) + arg
return wrapper
return decorator
#combine the created decorator with the staticmethod functionality
def staticmethod_combined(*args,**kwargs):
return lambda func: staticmethod(some_decorator_with_arg(*args,**kwargs)(func))
class some_class():
def __init__(self):
pass
@staticmethod_combined(1)
def some_method(a):
return a
print(some_class().some_method(1))
The problem with keyword arguments can be solved by providing the flag at the time of cythonizing always_allow_keywords=True