human
Complete this python program:
def infer_signature(func, class_name=''):
assistant
#Here is the Python code you requested.

    """Decorator that infers the signature of a function.
    """
    if hasattr(func, '__is_inferring_sig'):
        return func
    assert (func.__module__ != infer_method_signature.__module__)
    try:
        funcfile = get_defining_file(func)
        (funcsource, sourceline) = inspect.getsourcelines(func)
        sourceline -= 1
    except:
        return func
    funcid = (class_name, func.__name__, funcfile, sourceline)
    func_source_db[funcid] = ''.join(funcsource)
    try:
        func_argid_db[funcid] = getfullargspec(func)
        (vargs_name, kwargs_name) = (func_argid_db[funcid][1], func_argid_db[funcid][2])
    except TypeError:
        return func
    def wrapper(*args, **kwargs):
        global is_performing_inference
        if is_performing_inference:
            return func(*args, **kwargs)
        (expecting_type_error, got_type_error, got_exception) = (False, False, False)
        is_performing_inference = True
        try:
            callargs = getcallargs(func, *args, **kwargs)
            if vargs_name:
                va = callargs.pop(vargs_name)
            if kwargs_name:
                kw = callargs.pop(kwargs_name)
            arg_db = {arg: infer_value_type(value) for (arg, value) in callargs.items()}
            if vargs_name:
                arg_db[vargs_name] = union_many_types(*[infer_value_type(v) for v in va])
            if kwargs_name:
                arg_db[kwargs_name] = union_many_types(*[infer_value_type(v) for v in kw.values()])
        except TypeError:
            got_exception = expecting_type_error = True
        except:
            got_exception = True
        finally:
            is_performing_inference = False
        try:
            ret = func(*args, **kwargs)
        except TypeError:
            got_type_error = got_exception = True
            raise
        except:
            got_exception = True
            raise
        finally:
            if (not got_exception):
                assert (not expecting_type_error)
                for (arg, t) in arg_db.items():
                    update_db(func_arg_db, (funcid,...