1

Given the following code,

def myfunc(a=None, b=None, c=None, **kw):
    func(arga=a, argb=b, **kw)
    #do something with c

def func(arga=None, argb=None, argc=None):
    ....

Can I replicate part of the signature of func, namely the missing args, without imitating every missing arg of func manually?

Put it more simply, I want to see argc in keywords of myfunc such that myfunc? would be different. It would contain argc. myfunc(a=None,b=None,c=None,argc=None)

@functools.wraps allows for wrapping a complete functions. Using partial can subtract args. But don't know to add.

5
  • 2
    It's really not clear to me what you are asking, functools.wraps and functools.partial are doing pretty unrelated things But maybe I'm missing something obvious Commented Apr 13, 2022 at 21:08
  • If I do wraps(partial(func,1,1)) I can subtract args from func. not obvious. Commented Apr 13, 2022 at 21:25
  • It’s not clear to me what your question is asking. Can you try rewording it more carefully? Specifically, it’s not clear what “I want to see argc in the options of my func”. Can you give an example showing how func() would be used once it’s working as desired? Commented Apr 13, 2022 at 21:32
  • it's somewhat evil, but you can pass locals().copy() as an argument Commented Apr 13, 2022 at 21:34
  • The sameway, the signature on ? would be different. It would contain argc. func(a=None,b=None,c=None,argc=None). My original problem is a wrapper of mongo queries and allowed the keywords of pymongo.find in my original function. The thing is that nnobody (some people) don't know the full options of find.. Commented Apr 13, 2022 at 21:34

2 Answers 2

1

yes, it is possible, though not trivial - Python's introspection capabilities allow you to check all parameters the target function declares, and it is possible to build a new function programmatically that will include those attributes automatically.

I have written this for a project of mine, and had exposed the relevant code as my answer here: Signature-changing decorator: properly documenting additional argument

I will not mark this as duplicate, since the other question is more worried about documenting the new function.

If you want to give a try, with your code, maybe with something simpler, you can check the inspect.signature call from the standard library, which allows one to discover everything about parameters and default arguments of the target function.

Building a new function from this information is a bit more tricky, but possible - but one can always resort to a exec call which will can create a new function from a string template. The answer there follows this line.

Sign up to request clarification or add additional context in comments.

2 Comments

It definitely solves this
It can be solved with signature.replace. It is quite overkill. But IDC.
0

I'm not sure what is being asked here either but I have here alternative code to functools.partial that might be adapted ???

(edit>) The difference here from partial is that the mkcall argument is a string rather than a series of arguments. This string can then be formatted and analysed according to whatever appropriate requirements are needed before the target function is called. (<edit)

def mkcall(fs, globals=None,locals=None):
    class func:
        def __init__(f,fcnm=None,params=None,globals=None,locals=None):
            f.nm = fcnm
            f.pm = params
            f.globals = globals
            f.locals = locals

        def __call__(f):
            s = f.nm + f.pm
            eval(s,f.globals,f.locals)    

    if '(' in fs:
        funcn,lbr,r = fs.partition('(')
        tp = lbr + r
        newf = func(funcn,tp,globals,locals)
        callf = newf.__call__
    else:
        callf = eval(fs,globals,locals)
    return callf

#call examples
# mkcall("func(arg)")
# mkcall("func")

3 Comments

It is always dangerous to write code without understanding the question. I don't think this is different.
yeah fair enough - it is a risk - I felt that sometimes relying on libraries when contemplating a new angle can be limiting. Of course you are correcct - it is not different and just intended to suggest perhaps writing your soution from scratch. Woukd have made a comment but wanted to present the code.
Actually there is an important difference that I've explained in an edit to the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.