I want to make a function that being a decorator to another function will print that function call details - parameters names and effective values. My current implementation is this.
def describeFuncCall(func):
    """
    Decorator to print function call details.
    parameters names and effective values.
    """
    def wrapper(*func_args, **func_kwargs):
        print "func_code.co_varnames =", func.func_code.co_varnames
        print "func_code.co_argcount =", func.func_code.co_argcount
        print "func_args =", func_args
        print "func_kwargs =", func_kwargs
        params = []
        for argNo in range(func.func_code.co_argcount):
            argName = func.func_code.co_varnames[argNo]
            argValue = (
                func_args[argNo]
                if argNo < len(func_args)
                else func.func_defaults[argNo - func.func_code.co_argcount]
            )
            params.append((argName, argValue))
        for argName, argValue in func_kwargs.items():
            params.append((argName, argValue))
        params = [argName + " = " + repr(argValue)
                  for argName, argValue in params]
        print (func.__name__ + " ( " + ", ".join(params) + " )")
        return func(*func_args, **func_kwargs)
    return wrapper
@describeFuncCall
def test(a, b=4, c="blah-blah", *args, **kwargs):
    pass
test(1)
# test(1, 3)
# test(1, d = 5)
test(1, 2, 3, 4, 5, d=6, g=12.9)
Kinda works, but with some bugs:
For call
test(1, 2, 3, 4, 5, d = 6, g = 12.9)
it prints
test ( a = 1, b = 2, c = 3, d = 6, g = 12.9 ).
The expected result is
test ( a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} )
I got stuck here. Can you help me to find the right solution?