diff options
author | Jenkins <jenkins@review.openstack.org> | 2013-02-05 01:26:44 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2013-02-05 01:26:44 +0000 |
commit | 65949390762c41200ef8312ea934ae6bc630a0bd (patch) | |
tree | 6be00bbd333103b35b5a2865fb336405a8ad7541 /nova/utils.py | |
parent | f9eb7ca2ad7828c9b5a0790718d48a69b829658a (diff) | |
parent | 250230b32364b1e36ae6d62ec4bb8c3285c59401 (diff) | |
download | nova-65949390762c41200ef8312ea934ae6bc630a0bd.tar.gz nova-65949390762c41200ef8312ea934ae6bc630a0bd.tar.xz nova-65949390762c41200ef8312ea934ae6bc630a0bd.zip |
Merge "Record instance actions and events"
Diffstat (limited to 'nova/utils.py')
-rw-r--r-- | nova/utils.py | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/nova/utils.py b/nova/utils.py index 2386e6aa8..fb56df05c 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -1284,3 +1284,57 @@ def metadata_to_dict(metadata): if not item.get('deleted'): result[item['key']] = item['value'] return result + + +def get_wrapped_function(function): + """Get the method at the bottom of a stack of decorators.""" + if not hasattr(function, 'func_closure') or not function.func_closure: + return function + + def _get_wrapped_function(function): + if not hasattr(function, 'func_closure') or not function.func_closure: + return None + + for closure in function.func_closure: + func = closure.cell_contents + + deeper_func = _get_wrapped_function(func) + if deeper_func: + return deeper_func + elif hasattr(closure.cell_contents, '__call__'): + return closure.cell_contents + + return _get_wrapped_function(function) + + +def getcallargs(function, *args, **kwargs): + """This is a simplified inspect.getcallargs (2.7+). + + It should be replaced when python >= 2.7 is standard. + """ + keyed_args = {} + argnames, varargs, keywords, defaults = inspect.getargspec(function) + + keyed_args.update(kwargs) + + #NOTE(alaski) the implicit 'self' or 'cls' argument shows up in + # argnames but not in args or kwargs. Uses 'in' rather than '==' because + # some tests use 'self2'. + if 'self' in argnames[0] or 'cls' == argnames[0]: + # The function may not actually be a method or have im_self. + # Typically seen when it's stubbed with mox. + if inspect.ismethod(function) and hasattr(function, 'im_self'): + keyed_args[argnames[0]] = function.im_self + else: + keyed_args[argnames[0]] = None + + remaining_argnames = filter(lambda x: x not in keyed_args, argnames) + keyed_args.update(dict(zip(remaining_argnames, args))) + + if defaults: + num_defaults = len(defaults) + for argname, value in zip(argnames[-num_defaults:], defaults): + if argname not in keyed_args: + keyed_args[argname] = value + + return keyed_args |