diff --git a/Lib/inspect.py b/Lib/inspect.py index c9d10dc..ee77b3d 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -951,9 +951,54 @@ def getfullargspec(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__) - return FullArgSpec(args, varargs, varkw, func.__defaults__, - kwonlyargs, func.__kwdefaults__, func.__annotations__) + + sig = signature(func) + + args = [] + varargs = None + varkw = None + kwonlyargs = [] + defaults = () + annotations = {} + defaults = () + kwdefaults = {} + + if sig.return_annotation is not sig.empty: + annotations['return'] = sig.return_annotation + + for param in sig.parameters.values(): + kind = param.kind + name = param.name + + if kind is _POSITIONAL_ONLY: + args.append(name) + elif kind is _POSITIONAL_OR_KEYWORD: + args.append(name) + if param.default is not param.empty: + defaults += (param.default,) + elif kind is _VAR_POSITIONAL: + varargs = name + elif kind is _KEYWORD_ONLY: + kwonlyargs.append(name) + if param.default is not param.empty: + kwdefaults[name] = param.default + elif kind is _VAR_KEYWORD: + varkw = name + + if param.annotation is not param.empty: + annotations[name] = param.annotation + + if not kwdefaults: + # compatibility with 'func.__kwdefaults__' + kwdefaults = None + + if not defaults: + # compatibility with 'func.__defaults__' + defaults = None + + return FullArgSpec(args, varargs, varkw, defaults, + kwonlyargs, kwdefaults, annotations) + ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 9dc5475..914f0cb 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -566,6 +566,13 @@ class TestClassesAndFunctions(unittest.TestCase): kwonlyargs_e=['arg'], formatted='(*, arg)') + def test_getfullargspec_signature(self): + def test(): + pass + spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY) + test.__signature__ = inspect.Signature(parameters=(spam_param,)) + + self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)') def test_getargspec_method(self): class A(object):