Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some problems with decorators for classmethods

I have some piece of code in which I want to use a decorator on a classmethod as follows:

import functools

def mydeco(function):
    @classmethod
    def wrapper(cls):
        return function(cls) 
    return functools.update_wrapper(wrapper, function)
    # return wrapper

class BaseClass(object):
    @classmethod
    @mydeco
    def foo(cls):
        return "42" 

print BaseClass.foo()

When I comment out the line @mydeco the code works, i.e. the text 42 is printed. When including this decorator I have several problems:

  • When using the simpler line return wrapper I get the error

    TypeError: 'classmethod' object is not callable
    

How to do it right, i.e. that, in the given example, the original function is returned without being altered.

  • When using the more complex call return functools.update_wrapper(wrapper, function) to preserve some of the original function attributed I get the error

    AttributeError: 'classmethod' object has no attribute '__module__'
    

I am not sure if this error is related to the first issue, but it looks a different issue to me. Any specific suggestions to solve these issues are welcome.

The above example does not really 'do' something, it is merely the smallest possible example to show the problem I have.

like image 464
Alex Avatar asked Nov 27 '22 16:11

Alex


1 Answers

Is there a reason this will not work for you?

import functools

def mydeco(function):
    def wrapper(*args, **kwargs):
        return function(*args, **kwargs) 
    return functools.update_wrapper(wrapper, function)

class BaseClass(object):
    @classmethod
    @mydeco
    def foo(cls):
        return "42" 

print BaseClass.foo()
42
like image 159
cmd Avatar answered Nov 29 '22 06:11

cmd