How to inject a line of code into an existing function?

  function, python, python-3.x, python-decorators

I have a function looking like following:

async def callback(ctx, first_arg, second_arg=None)
    ...

Where the parameter names, the count and everything can always be different.
In the first paremeter is a method called respond(), and I want to make a decorator that returns the modified callback, where ctx.respond() is called.

I thought of backing up the original callback and then creating a "fake" callback where the ctx.respond() method is called and then the real callback, but it won’t work because after my decorator there is another decorator that will check on the functions parameters

The decorator

def auto_respond():
    def wraper(callback):
        # this is what I thought of
        b_callback = callback
        async def auto_callback(ctx, here comes the problem):
            await ctx.respond()
            return await b_callback(ctx, the problem is here too)
        return auto_callback
    return wraper

The problem is, that I cannot set the right parameters of the function, because I never now how what they are going to be.

Originally, I thought of maybe using *args and **kwargs to receive the params and directly pass them over, but then the check wouldn’t work


Let’s say I have this example

@the_other_decorator()
@auto_respond()
async def callback(ctx, user=None):
    ...

And in the other decorator, the paremeters will be checked with inspect.signature(callback).parameters

the_other_decorator

def the_other_decorator():
    def wraper(callback):
        params = inspect.signature(callback).parameters
        for name in params:
            param = params.get(name)
            if param.annotation != param.empty:
                ...
            elif param.default != inspect._empty:
                ...
        ...
    return wraper

So my next soloution was that if I somehow could "inject" a line of code to the callback function, get the first argument and use the respond method of it, I would "bypass" the param check

Note that the params checks are needed because I need to get some information about them in the decorator

So now there are two options left, the first one is to inject a line of code as I said or somehow "clone" the parameters of the callback function and set them to the "fake" callback function

By the way, sorry for the bad English, if I didn’t express myself right or some information are missing in this problem, please tell me so I can improve the question!

Source: Python-3x Questions

LEAVE A COMMENT