diff -r d168f439a14f Doc/library/inspect.rst --- a/Doc/library/inspect.rst Tue Aug 02 01:12:16 2011 +0200 +++ b/Doc/library/inspect.rst Tue Aug 02 04:29:29 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 @@ -405,9 +405,9 @@ keyword-only arguments and annotations. -.. function:: getfullargspec(func) +.. function:: getfullargspec(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` is returned: ``FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, @@ -422,6 +422,10 @@ The first four items in the tuple correspond to :func:`getargspec`. + .. versionchanged:: 3.3 + *callable* could be object instance, in that case *__call__* method would + be inspected if exists. + .. function:: getargvalues(frame) diff -r d168f439a14f Lib/inspect.py --- a/Lib/inspect.py Tue Aug 02 01:12:16 2011 +0200 +++ b/Lib/inspect.py Tue Aug 02 04:29:29 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,13 @@ The first four items in the tuple correspond to getargspec(). """ + 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 d168f439a14f Lib/test/inspect_fodder2.py --- a/Lib/test/inspect_fodder2.py Tue Aug 02 01:12:16 2011 +0200 +++ b/Lib/test/inspect_fodder2.py Tue Aug 02 04:29:29 2011 +0400 @@ -109,3 +109,10 @@ #line 109 def keyword_only_arg(*, arg): pass + +# line 113 +class callable_cls: + def __call__(self, a, b, c: int, *args, d: bool=False, **kwargs): + pass + +callable_instance = callable_cls() diff -r d168f439a14f Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Tue Aug 02 01:12:16 2011 +0200 +++ b/Lib/test/test_inspect.py Tue Aug 02 04:29:29 2011 +0400 @@ -500,6 +500,15 @@ kwonlyargs_e=['arg'], formatted='(*, arg)') + 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):