summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2015-10-14 11:39:09 -0700
committerJoshua Harlow <harlowja@yahoo-inc.com>2015-10-16 11:00:46 -0700
commit43451e5cc767747b64d7b5700800c001b2d1d895 (patch)
treeacb73982e51bc0d9d5324e570d57cf02867319a6
parent9ec6cccb77a1e8ec5ba0b0947b3ba5e16502a2db (diff)
downloadoslo-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.py45
-rw-r--r--requirements.txt1
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