Search code examples
pythonclassdecoratorpylintcallable

Pylint throws not-callable on decorator defined within class


Im trying to create a class that has a time remaining property and executing functions within it reduces this time. Here is the code

class TestClass:
    def __init__(self):
        self.time_remaining = 240

    @staticmethod
    def time_taken(start):
        return (datetime.now() - start).seconds

    def with_timeout(f):
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            start = datetime.now()
            result = f(self, *args, **kwargs)
            self.time_remaining = (
                self.time_remaining - TestClass.time_taken(start)
            )
            return result

        return wrapper

    @with_timeout
    def do_something(self, param):
        # DO Something

Then when i instantiaite the class and use do_something like so:

test_class = TestClass()
test_class.do_something("param")

It works as expected. However when i run pylint on the code i get an error:

pylint: not-callable / f is not callable

Is this a false positive or is there a better way to write this functionality?

Thanks


Solution

  • Thanks for the comments. Moving the method outside the class was what was required as self is bound depending on how a method is called, not where it is defined so the decorator doesn't need to be defined within the class to have access to self:

    def time_taken(start):
        return (datetime.now() - start).seconds
    
    def with_timeout(f):
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            start = datetime.now()
            result = f(self, *args, **kwargs)
            self.time_remaining = self.time_remaining - time_taken(start)
            return result
    
        return wrapper
    
    
    class TestClass:
        def __init__(self):
            self.time_remaining = 240
    
        @with_timeout
        def do_something(self, param):
            # DO Something