lundi 13 mars 2023

Preserve argument information for inspect when stacking decorators

I'm writing a decorator that should pass a query to the function based on one of its parameters.

This is how it currently looks like, but not finished yet (still experimenting):

def pass_query(service: str, query: str):
    def decorate(decoratee):
        @functools.wraps(decoratee)
        def decorator(*args, **kwargs):
            params = inspect.getfullargspec(decoratee)
            if "query" in params and service == params.get("service", None):
                kwargs["query"] = query
            return decoratee(*args, **kwargs)

        return decorator

    return decorate

The problem is that inspect.getfullargspec(decoratee) doesn't retrieve any useful information with two or more decorators as then the other ones loose the information about the function parameters.

@pass_query("foo", "q1.sql")
@pass_query("bar", "q2.sql")
def track_report(service: str, query: Optional[str] = None) -> None:
    pass

Is there a way to preserve the parameters so that the decorators won't break reflection as if there was only one decorator?





Aucun commentaire:

Enregistrer un commentaire