decorator to set attributes of function
Your decorator should return a function that can replace do_x
or do_y
, not return the execution result of do_x
or do_y
You can modity you decorate as below:
def permission(permission_required):
def wrapper(func):
def inner():
setattr(func, 'permission_required', permission_required)
return func
return inner()
return wrapper
Of course, you have another brief solution:
def permission(permission_required):
def wrapper(func):
setattr(func, 'permission_required', permission_required)
return func
return wrapper
You are checking the attribute on the inner (wrapper) function, but set it on the original (wrapped) function. But you need a wrapper function at all:
def permission(permission_required):
def decorator(func):
func.permission_required = permission_required
return func
return decorator
Your decorator needs to return something that'll replace the original function. The original function itself (with the attribute added) will do fine for that, because all you wanted to do is add an attribute to it.
If you still need a wrapper, then set the attribute on the wrapper function instead:
from functools import wraps
def permission(permission_required):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# only use a wrapper if you need extra code to be run here
return func(*args, **kwargs)
wrapper.permission_required = permission_required
return wrapper
return decorator
After all, you are replacing the wrapped function with the wrapper returned by the decorator, so that's the object you'll be looking for the attribute on.
I also added the @functools.wraps()
decorator to the wrapper, which copied across important identifying information and other helpful things from func
to the wrapper, making it much easier to work with.