def get_function_signature(func):
 arg_count = func.func_code.co_argcount
 arg_names = func.func_code.co_varnames[:arg_count]
 arg_defaults = {}
 func_defaults = ()
 if (func.func_defaults is not None):
  func_defaults = func.func_defaults
 for (name, value) in zip(arg_names[::(-1)], func_defaults[::(-1)]):
  arg_defaults[name] = value
 signature = {'name': func.__name__, 'arg_count': arg_count, 'arg_names': arg_names, 'arg_defaults': arg_defaults}
 non_pos_names = list(func.func_code.co_varnames[arg_count:])
 COLLECTS_ARBITRARY_POSITIONAL_ARGS = 4
 if (func.func_code.co_flags & COLLECTS_ARBITRARY_POSITIONAL_ARGS):
  signature['var_args'] = non_pos_names.pop(0)
 COLLECTS_ARBITRARY_KEYWORD_ARGS = 8
 if (func.func_code.co_flags & COLLECTS_ARBITRARY_KEYWORD_ARGS):
  signature['var_kw_args'] = non_pos_names.pop(0)
 return signature

def get_function_signature ( func ) : arg_count = func . func_code . co_argcount arg_names = func . func_code . co_varnames [ : arg_count ] arg_defaults = { } func_defaults = ( ) if ( func . func_defaults is not None ) : func_defaults = func . func_defaults for ( name , value ) in zip ( arg_names [ : : ( - 1 ) ] , func_defaults [ : : ( - 1 ) ] ) : arg_defaults [ name ] = value signature = { 'name' : func . __name__ , 'arg_count' : arg_count , 'arg_names' : arg_names , 'arg_defaults' : arg_defaults } non_pos_names = list ( func . func_code . co_varnames [ arg_count : ] ) COLLECTS_ARBITRARY_POSITIONAL_ARGS = 4 if ( func . func_code . co_flags & COLLECTS_ARBITRARY_POSITIONAL_ARGS ) : signature [ 'var_args' ] = non_pos_names . pop ( 0 ) COLLECTS_ARBITRARY_KEYWORD_ARGS = 8 if ( func . func_code . co_flags & COLLECTS_ARBITRARY_KEYWORD_ARGS ) : signature [ 'var_kw_args' ] = non_pos_names . pop ( 0 ) return signature
get the function signature as a mapping of attributes .