def enableAttributes(genfunc):
"""Wrapper for generators to enable classlike attribute access.
The generator definition should specify 'self' as the first parameter.
Calls to a wrapped generator should ignore the self parameter.
"""
old = getargspec(genfunc)
old[0].pop(0)
new = getargspec(genfunc)
new[0][0] = 'wrapped'
specs = {'name': genfunc.func_name,
'oldargs': formatargspec(*old),
'newargs': formatargspec(*new)}
exec(_redefinition % specs, genfunc.func_globals)
#### A minimal, complete example
python类formatargspec()的实例源码
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError, e:
signature = '%s()' % func_name
self['Signature'] = signature
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def document_custom_signature(section, name, method,
include=None, exclude=None):
"""Documents the signature of a custom method
:param section: The section to write the documentation to.
:param name: The name of the method
:param method: The handle to the method being documented
:type include: Dictionary where keys are parameter names and
values are the shapes of the parameter names.
:param include: The parameter shapes to include in the documentation.
:type exclude: List of the names of the parameters to exclude.
:param exclude: The names of the parameters to exclude from
documentation.
"""
args, varargs, keywords, defaults = inspect.getargspec(method)
args = args[1:]
signature_params = inspect.formatargspec(
args, varargs, keywords, defaults)
signature_params = signature_params.lstrip('(')
signature_params = signature_params.rstrip(')')
section.style.start_sphinx_py_method(name, signature_params)
def get_wrapped(func, wrapper_template, evaldict):
# Preserve the argspec for the wrapped function so that testing
# tools such as pytest can continue to use their fixture injection.
args, a, kw, defaults = inspect.getargspec(func)
signature = inspect.formatargspec(args, a, kw, defaults)
is_bound_method = hasattr(func, '__self__')
if is_bound_method:
args = args[1:] # Omit 'self'
callargs = inspect.formatargspec(args, a, kw, None)
ctx = {'signature': signature, 'funcargs': callargs}
six.exec_(wrapper_template % ctx, evaldict)
wrapper = evaldict['wrapper']
update_wrapper(wrapper, func)
if is_bound_method:
wrapper = wrapper.__get__(func.__self__, type(func.__self__))
return wrapper
def document_custom_signature(section, name, method,
include=None, exclude=None):
"""Documents the signature of a custom method
:param section: The section to write the documentation to.
:param name: The name of the method
:param method: The handle to the method being documented
:type include: Dictionary where keys are parameter names and
values are the shapes of the parameter names.
:param include: The parameter shapes to include in the documentation.
:type exclude: List of the names of the parameters to exclude.
:param exclude: The names of the parameters to exclude from
documentation.
"""
args, varargs, keywords, defaults = inspect.getargspec(method)
args = args[1:]
signature_params = inspect.formatargspec(
args, varargs, keywords, defaults)
signature_params = signature_params.lstrip('(')
signature_params = signature_params.rstrip(')')
section.style.start_sphinx_py_method(name, signature_params)
def get_func_doc(name, func):
doc_source = ''
if name in SKIP:
return ''
if name[0] == '_':
return ''
if func in classes_and_functions:
return ''
classes_and_functions.add(func)
header = name + inspect.formatargspec(*inspect.getargspec(func))
docstring = format_func_doc(inspect.getdoc(func), module_name + '.' +
header)
if docstring != '':
doc_source += docstring
doc_source += '\n\n ---------- \n\n'
return doc_source
def get_method_doc(name, func):
doc_source = ''
if name in SKIP:
return ''
if name[0] == '_':
return ''
if func in classes_and_functions:
return ''
classes_and_functions.add(func)
header = name + inspect.formatargspec(*inspect.getargspec(func))
docstring = format_method_doc(inspect.getdoc(func), header)
if docstring != '':
doc_source += '\n\n <span class="hr_large"></span> \n\n'
doc_source += docstring
return doc_source
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
if sys.version_info[0] >= 3:
argspec = inspect.getfullargspec(func)
else:
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError, e:
signature = '%s()' % func_name
self['Signature'] = signature
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
if sys.version_info[0] >= 3:
argspec = inspect.getfullargspec(func)
else:
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
varkw_e=None, defaults_e=None,
kwonlyargs_e=[], kwonlydefaults_e=None,
ann_e={}, formatted=None):
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
inspect.getfullargspec(routine)
self.assertEqual(args, args_e)
self.assertEqual(varargs, varargs_e)
self.assertEqual(varkw, varkw_e)
self.assertEqual(defaults, defaults_e)
self.assertEqual(kwonlyargs, kwonlyargs_e)
self.assertEqual(kwonlydefaults, kwonlydefaults_e)
self.assertEqual(ann, ann_e)
if formatted is not None:
self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
kwonlyargs, kwonlydefaults, ann),
formatted)
def getargnames(argspecs, with_unbox=False):
"""Resembles list of arg-names as would be seen in a function signature, including
var-args, var-keywords and keyword-only args.
"""
# todo: We can maybe make use of inspect.formatargspec
args = argspecs.args
vargs = argspecs.varargs
try:
kw = argspecs.keywords
except AttributeError:
kw = argspecs.varkw
try:
kwonly = argspecs.kwonlyargs
except AttributeError:
kwonly = None
res = []
if not args is None:
res.extend(args)
if not vargs is None:
res.append('*'+vargs if with_unbox else vargs)
if not kwonly is None:
res.extend(kwonly)
if not kw is None:
res.append('**'+kw if with_unbox else kw)
return res
def document_custom_signature(section, name, method,
include=None, exclude=None):
"""Documents the signature of a custom method
:param section: The section to write the documentation to.
:param name: The name of the method
:param method: The handle to the method being documented
:type include: Dictionary where keys are parameter names and
values are the shapes of the parameter names.
:param include: The parameter shapes to include in the documentation.
:type exclude: List of the names of the parameters to exclude.
:param exclude: The names of the parameters to exclude from
documentation.
"""
args, varargs, keywords, defaults = inspect.getargspec(method)
args = args[1:]
signature_params = inspect.formatargspec(
args, varargs, keywords, defaults)
signature_params = signature_params.lstrip('(')
signature_params = signature_params.rstrip(')')
section.style.start_sphinx_py_method(name, signature_params)
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError, e:
signature = '%s()' % func_name
self['Signature'] = signature
def raw_result(wrapped):
"""
Decorator for functions whose output should not be JSON-serialized.
"""
def wrapper(*args, **kwargs):
result = wrapped(*args, **kwargs)
return {'raw_result': result}
# These contortions are necessary to retain compatibility with
# argparse's ability to generate CLI options by signature inspection.
import functools
wrapped_signature = inspect.getargspec(wrapped)
formatted_args = inspect.formatargspec(*wrapped_signature)
compat_name = "_%s" % wrapped.func_name
compat_def = 'lambda %s: %s%s' % (formatted_args.lstrip('(').rstrip(')'),
compat_name, formatted_args)
compat_fn = eval(compat_def, {compat_name: wrapper})
return functools.wraps(wrapped)(compat_fn)
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def format_args(self):
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
# cannot introspect arguments of a C function or method
return None
try:
argspec = getargspec(self.object)
except TypeError:
if (is_builtin_class_method(self.object, '__new__') and
is_builtin_class_method(self.object, '__init__')):
raise TypeError('%r is a builtin class' % self.object)
# if a class should be documented as function (yay duck
# typing) we try to use the constructor signature as function
# signature without the first argument.
try:
argspec = getargspec(self.object.__new__)
except TypeError:
argspec = getargspec(self.object.__init__)
if argspec[0]:
del argspec[0][0]
args = formatargspec(*argspec)
# escape backslashes for reST
args = args.replace('\\', '\\\\')
return args
def format_args(self):
# for classes, the relevant signature is the __init__ method's
initmeth = self.get_attr(self.object, '__init__', None)
# classes without __init__ method, default __init__ or
# __init__ written in C?
if initmeth is None or \
is_builtin_class_method(self.object, '__init__') or \
not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)):
return None
try:
argspec = getargspec(initmeth)
except TypeError:
# still not possible: happens e.g. for old-style classes
# with __init__ in C
return None
if argspec[0] and argspec[0][0] in ('cls', 'self'):
del argspec[0][0]
return formatargspec(*argspec)
def get_func_doc(name, func):
doc_source = ''
if name in SKIP:
return ''
# if name[0] == '_':
# return ''
if func in classes_and_functions:
return ''
classes_and_functions.add(func)
header = name + inspect.formatargspec(*inspect.getargspec(func))
path = get_src_path(func)
# FUNC_TEMP = "[{header}]({path})"
# header = FUNC_TEMP.format(header=header, path=path)
# print(header)
docstring = format_func_doc(inspect.getdoc(func), module_name + '.' +
header, path)
print(docstring)
if docstring != '':
doc_source += docstring
doc_source += '\n\n ---------- \n\n'
return doc_source
def get_method_doc(name, func):
doc_source = ''
if name in SKIP:
return ''
if name[0] == '_':
return ''
if func in classes_and_functions:
return ''
classes_and_functions.add(func)
header = name + inspect.formatargspec(*inspect.getargspec(func))
path = get_src_path(func)
docstring = format_method_doc(inspect.getdoc(func), header, path)
if docstring != '':
doc_source += '\n\n <span class="hr_large"></span> \n\n'
doc_source += docstring
return doc_source
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
if sys.version_info[0] >= 3:
argspec = inspect.getfullargspec(func)
else:
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError, e:
signature = '%s()' % func_name
self['Signature'] = signature
def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
varkw_e=None, defaults_e=None,
kwonlyargs_e=[], kwonlydefaults_e=None,
ann_e={}, formatted=None):
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
inspect.getfullargspec(routine)
self.assertEqual(args, args_e)
self.assertEqual(varargs, varargs_e)
self.assertEqual(varkw, varkw_e)
self.assertEqual(defaults, defaults_e)
self.assertEqual(kwonlyargs, kwonlyargs_e)
self.assertEqual(kwonlydefaults, kwonlydefaults_e)
self.assertEqual(ann, ann_e)
if formatted is not None:
self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
kwonlyargs, kwonlydefaults, ann),
formatted)
def __init__(self, func, role='func', doc=None, config={}):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
if func is None:
raise ValueError("No function or docstring given")
doc = inspect.getdoc(func) or ''
NumpyDocString.__init__(self, doc)
if not self['Signature'] and func is not None:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*', '\*')
signature = '%s%s' % (func_name, argspec)
except TypeError as e:
signature = '%s()' % func_name
self['Signature'] = signature
def _pulse_method_call(pulse_op, func=None, index_arg=True):
'''Creates following synchronous wrapper for async pa_operation callable:
wrapper(index, ...) -> pulse_op(index, [*]args_func(...))
index_arg=False: wrapper(...) -> pulse_op([*]args_func(...))'''
def _wrapper(self, *args, **kws):
if index_arg:
if 'index' in kws: index = kws.pop('index')
else: index, args = args[0], args[1:]
pulse_args = func(*args, **kws) if func else list()
if not is_list(pulse_args): pulse_args = [pulse_args]
if index_arg: pulse_args = [index] + list(pulse_args)
with self._pulse_op_cb() as cb:
try: pulse_op(self._ctx, *(list(pulse_args) + [cb, None]))
except c.ArgumentError as err: raise TypeError(err.args)
except c.pa.CallError as err: raise PulseOperationInvalid(err.args[-1])
func_args = list(inspect.getargspec(func or (lambda: None)))
func_args[0] = list(func_args[0])
if index_arg: func_args[0] = ['index'] + func_args[0]
_wrapper.__name__ = '...'
_wrapper.__doc__ = 'Signature: func' + inspect.formatargspec(*func_args)
if func.__doc__: _wrapper.__doc__ += '\n\n' + func.__doc__
return _wrapper
def preserve_signature(func):
"""Preserve the original function signature and attributes in decorator wrappers."""
from inspect import getargspec, formatargspec
from gnutls.constants import GNUTLSConstant
constants = [c for c in (getargspec(func)[3] or []) if isinstance(c, GNUTLSConstant)]
signature = formatargspec(*getargspec(func))[1:-1]
parameters = formatargspec(*getargspec(func), **{'formatvalue': lambda value: ""})[1:-1]
def fix_signature(wrapper):
if constants:
## import the required GNUTLSConstants used as function default arguments
code = "from gnutls.constants import %s\n" % ', '.join(c.name for c in constants)
exec code in locals(), locals()
code = "def %s(%s): return wrapper(%s)\nnew_wrapper = %s\n" % (func.__name__, signature, parameters, func.__name__)
exec code in locals(), locals()
new_wrapper.__name__ = func.__name__
new_wrapper.__doc__ = func.__doc__
new_wrapper.__module__ = func.__module__
new_wrapper.__dict__.update(func.__dict__)
return new_wrapper
return fix_signature
# Argument validating decorators
#
def synchronized(meth):
args, vargs, kwargs, defs = inspect.getargspec(meth)
scope = {}
scope["meth"] = meth
exec """
def %s%s:
%s
%s._lock.acquire()
try:
return meth%s
finally:
%s._lock.release()
""" % (meth.__name__, inspect.formatargspec(args, vargs, kwargs, defs),
repr(inspect.getdoc(meth)), args[0],
inspect.formatargspec(args, vargs, kwargs, defs,
formatvalue=lambda x: ""),
args[0]) in scope
return scope[meth.__name__]