| | 47 | |
|---|
| | 48 | def get_func_object(fun): |
|---|
| | 49 | """Get the function object from a method or function (designed to be hooked |
|---|
| | 50 | or not). |
|---|
| | 51 | Return None if the argument is not correct.""" |
|---|
| | 52 | if type(fun) in (MethodType, FunctionType): |
|---|
| | 53 | # is fun designed to be hooked? |
|---|
| | 54 | if hasattr(fun, '_wrapped_fun'): |
|---|
| | 55 | # remove the hook wrapper |
|---|
| | 56 | fun = fun._wrapped_fun |
|---|
| | 57 | # normal method? |
|---|
| | 58 | elif type(fun) is MethodType: |
|---|
| | 59 | fun = fun.im_func |
|---|
| | 60 | # do not change the "fun" for normal functions |
|---|
| | 61 | return fun |
|---|
| | 62 | return None |
|---|
| | 63 | |
|---|
| | 64 | def get_args_names(fun): |
|---|
| | 65 | """Get all the arguments names from a method or function (designed to be |
|---|
| | 66 | hooked or not).""" |
|---|
| | 67 | fun = get_func_object(fun) |
|---|
| | 68 | if fun is None: |
|---|
| | 69 | return None |
|---|
| | 70 | |
|---|
| | 71 | co = fun.func_code |
|---|
| | 72 | arg_count = co.co_argcount |
|---|
| | 73 | # code object has *args? |
|---|
| | 74 | if (co.co_flags & 4) != 0: |
|---|
| | 75 | arg_count += 1 |
|---|
| | 76 | # code object has **kwargs? |
|---|
| | 77 | if (co.co_flags & 8) != 0: |
|---|
| | 78 | arg_count += 1 |
|---|
| | 79 | return co.co_varnames[:arg_count] |
|---|
| | 80 | |
|---|
| | 81 | def get_default_arg(fun, name): |
|---|
| | 82 | """Find the default parameter from an argument name. |
|---|
| | 83 | The argument name belongs to a method or function (designed to be hooked or |
|---|
| | 84 | not). |
|---|
| | 85 | Return None if an error occured of if no default parameter was found.""" |
|---|
| | 86 | fun = get_func_object(fun) |
|---|
| | 87 | if fun is None: |
|---|
| | 88 | return None |
|---|
| | 89 | |
|---|
| | 90 | co = fun.func_code |
|---|
| | 91 | if name not in co.co_varnames: |
|---|
| | 92 | return None |
|---|
| | 93 | |
|---|
| | 94 | defaults = fun.func_defaults |
|---|
| | 95 | indice = list(co.co_varnames).index(name) |
|---|
| | 96 | offset = co.co_argcount - len(defaults) |
|---|
| | 97 | # arg has a default value? |
|---|
| | 98 | if indice >= offset: |
|---|
| | 99 | return defaults[indice - offset] |
|---|
| | 100 | return None |
|---|