diff -r 7af576e3cb0c Doc/library/inspect.rst --- a/Doc/library/inspect.rst Mon Aug 01 17:31:12 2011 +0200 +++ b/Doc/library/inspect.rst Tue Aug 02 01:36:44 2011 +0400 @@ -390,9 +390,9 @@ times. -.. function:: getargspec(func) +.. function:: getargspec(callable) - Get the names and default values of a Python function's arguments. A + Get the names and default values of a Python callable's arguments. A :term:`named tuple` ``ArgSpec(args, varargs, keywords, defaults)`` is returned. *args* is a list of the argument names. *varargs* and *keywords* are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is a @@ -404,10 +404,15 @@ Use :func:`getfullargspec` instead, which provides information about keyword-only arguments and annotations. + .. versionchanged:: 3.3 + Allowed to inspect any Python callable, not only functions. For classes + *__init__* method would be inspected if exists. For objects its *__call__* + method would be inspected if exists. -.. function:: getfullargspec(func) - Get the names and default values of a Python function's arguments. A +.. function:: getfullargspec(callable) + + Get the names and default values of a Python callable's arguments. A :term:`named tuple` is returned: ``FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, @@ -422,6 +427,11 @@ The first four items in the tuple correspond to :func:`getargspec`. + .. versionchanged:: 3.3 + Allowed to inspect any Python callable, not only functions. For classes + *__init__* method would be inspected if exists. For objects its *__call__* + method would be inspected if exists. + .. function:: getargvalues(frame) diff -r 7af576e3cb0c Lib/inspect.py --- a/Lib/inspect.py Mon Aug 01 17:31:12 2011 +0200 +++ b/Lib/inspect.py Tue Aug 02 01:36:44 2011 +0400 @@ -776,7 +776,7 @@ ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') def getargspec(func): - """Get the names and default values of a function's arguments. + """Get the names and default values of a callable's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names. @@ -800,7 +800,7 @@ 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations') def getfullargspec(func): - """Get the names and default values of a function's arguments. + """Get the names and default values of a callable's arguments. A tuple of seven things is returned: (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations). @@ -813,9 +813,19 @@ The first four items in the tuple correspond to getargspec(). """ + if not callable(func): + raise TypeError('{!r} is not a callable'.format(func)) + + if isclass(func) and isfunction(func.__init__): + func = func.__init__ + + if (hasattr(func, '__call__') and not isfunction(func) and + not ismethod(func) and ismethod(func.__call__)): + func = func.__call__ if ismethod(func): func = func.__func__ + if not isfunction(func): raise TypeError('{!r} is not a Python function'.format(func)) args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__) diff -r 7af576e3cb0c Lib/test/inspect_fodder2.py --- a/Lib/test/inspect_fodder2.py Mon Aug 01 17:31:12 2011 +0200 +++ b/Lib/test/inspect_fodder2.py Tue Aug 02 01:36:44 2011 +0400 @@ -109,3 +109,11 @@ #line 109 def keyword_only_arg(*, arg): pass + +# line 113 +class callable_cls: + def __init__(self, arg1, arg2=None): + pass + def __call__(self, a, b, c:int, *args, d:bool=False, **kwargs): + pass +callable_instance = callable_cls(42) diff -r 7af576e3cb0c Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Mon Aug 01 17:31:12 2011 +0200 +++ b/Lib/test/test_inspect.py Tue Aug 02 01:36:44 2011 +0400 @@ -500,6 +500,20 @@ kwonlyargs_e=['arg'], formatted='(*, arg)') + self.assertFullArgSpecEquals(mod2.callable_cls, + ['self', 'arg1', 'arg2'], + defaults_e=(None,), + formatted=('(self, arg1, arg2=None)')) + + self.assertFullArgSpecEquals(mod2.callable_instance, + ['self', 'a', 'b', 'c'], + varargs_e='args', + varkw_e='kwargs', + kwonlyargs_e=['d'], + kwonlydefaults_e={'d': False}, + ann_e={'c': int, 'd': bool}, + formatted='(self, a, b, c: int, *args, d: bool=False, **kwargs)') + def test_getargspec_method(self): class A(object):