diff options
author | Joshua Harlow <harlowja@yahoo-inc.com> | 2015-10-14 11:39:09 -0700 |
---|---|---|
committer | Joshua Harlow <harlowja@yahoo-inc.com> | 2015-10-16 11:00:46 -0700 |
commit | 43451e5cc767747b64d7b5700800c001b2d1d895 (patch) | |
tree | acb73982e51bc0d9d5324e570d57cf02867319a6 | |
parent | 9ec6cccb77a1e8ec5ba0b0947b3ba5e16502a2db (diff) | |
download | oslo-utils-43451e5cc767747b64d7b5700800c001b2d1d895.tar.gz |
Expose function signature fetching function
This function is the recommended way to get information
about functions going forward, so all the variations of
getargspec can just use this instead (including the variations
of this used in openstack).
This exposes a 'get_signature' function that correctly aliases
the exposed function in python3.x and the backwards compat
library (funcsigs) that exposes this same information in python2.x
Internally in the other reflection functions we now switch
away from using getargspec as well, and replace it with using
this new signature object/function instead.
Depends-On: I1aa0054089ca57fc2d68779f4ee133a9750fec2a
Change-Id: I910b353f5db290832ef87bf7c5e5bb2e9788e3ec
-rw-r--r-- | oslo_utils/reflection.py | 45 | ||||
-rw-r--r-- | requirements.txt | 1 |
2 files changed, 23 insertions, 23 deletions
diff --git a/oslo_utils/reflection.py b/oslo_utils/reflection.py index 34714fc..5baf496 100644 --- a/oslo_utils/reflection.py +++ b/oslo_utils/reflection.py @@ -29,6 +29,17 @@ except AttributeError: # others)... _BUILTIN_MODULES = ('builtins', '__builtin__', '__builtins__', 'exceptions') +if six.PY3: + Parameter = inspect.Parameter + Signature = inspect.Signature + get_signature = inspect.signature +else: + # Provide an equivalent but use funcsigs instead... + import funcsigs + Parameter = funcsigs.Parameter + Signature = funcsigs.Signature + get_signature = funcsigs.signature + def get_members(obj, exclude_hidden=True): """Yields the members of an object, filtering by hidden/not hidden.""" @@ -173,19 +184,6 @@ def is_subclass(obj, cls): return inspect.isclass(obj) and issubclass(obj, cls) -def _get_arg_spec(function): - if isinstance(function, _TYPE_TYPE): - bound = True - function = function.__init__ - elif isinstance(function, (types.FunctionType, types.MethodType)): - bound = is_bound_method(function) - function = getattr(function, '__wrapped__', function) - else: - function = function.__call__ - bound = is_bound_method(function) - return inspect.getargspec(function), bound - - def get_callable_args(function, required_only=False): """Get names of callable arguments. @@ -195,16 +193,17 @@ def get_callable_args(function, required_only=False): If required_only is True, optional arguments (with default values) are not included into output. """ - argspec, bound = _get_arg_spec(function) - f_args = argspec.args - if required_only and argspec.defaults: - f_args = f_args[:-len(argspec.defaults)] - if bound: - f_args = f_args[1:] - return f_args + sig = get_signature(function) + function_args = list(six.iterkeys(sig.parameters)) + for param_name, p in six.iteritems(sig.parameters): + if (p.kind in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD) + or (required_only and p.default is not Parameter.empty)): + function_args.remove(param_name) + return function_args def accepts_kwargs(function): - """Returns True if function accepts kwargs.""" - argspec, _bound = _get_arg_spec(function) - return bool(argspec.keywords) + """Returns ``True`` if function accepts kwargs otherwise ``False``.""" + sig = get_signature(function) + return any(p.kind == Parameter.VAR_KEYWORD + for p in six.itervalues(sig.parameters)) diff --git a/requirements.txt b/requirements.txt index 03ccbe8..cc0898a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ pbr>=1.6 Babel>=1.3 six>=1.9.0 +funcsigs>=0.4;python_version=='2.7' or python_version=='2.6' iso8601>=0.1.9 oslo.i18n>=1.5.0 # Apache-2.0 monotonic>=0.3 # Apache-2.0 |