Skip to content

Use inspect.signature() instead of inspect.getfullargspec() #1164

@jwodder

Description

@jwodder

Currently, the implementation of Memory.cache() implements the ignore option using inspect.getfullargspec(). However, this function does not handle decorated functions correctly; inspect.signature(), on the other hand, does. Observe:

from functools import wraps
import inspect

def decorate(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
        return f(*args, **kwargs)
    return wrapped

@decorate
def foo(arg, extra=None):
    return arg

print(inspect.signature(foo))
print(inspect.getfullargspec(foo))

This prints out:

(arg, extra=None)
FullArgSpec(args=[], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})

Note that signature() reports the signature of the original foo, while getfullargspec() reports the signature of wrapped.

As a consequence of this, using the ignore option on a Memory-cached function with an intervening decorator does not work. Example:

from functools import wraps
import inspect
from joblib import Memory

mem = Memory("cache", verbose=0)

def decorate(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
        return f(*args, **kwargs)
    return wrapped

@mem.cache(ignore=["extra"])
@decorate
def foo(arg, extra=None):
    return arg

foo(1)

This fails with the error ValueError: Ignore list: argument 'extra' is not defined for function foo(*args, **kwargs).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions