diff options
author | Terry Jan Reedy <tjreedy@udel.edu> | 2017-08-10 04:46:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-10 04:46:29 (GMT) |
commit | 646f6c3096abfe5bde13f039ebf32bce5baf083a (patch) | |
tree | 96f8f1c13357638c6bcda0b43dd8967a4025798b /Lib/idlelib/calltips.py | |
parent | 4388b4257abf3b9c348cf4db8c6144dcc07f3e98 (diff) | |
download | cpython-646f6c3096abfe5bde13f039ebf32bce5baf083a.zip cpython-646f6c3096abfe5bde13f039ebf32bce5baf083a.tar.gz cpython-646f6c3096abfe5bde13f039ebf32bce5baf083a.tar.bz2 |
[3.6] bpo-19903: IDLE: Calltips changed to use inspect.signature (GH-2822) (#3053)
Idlelib.calltips.get_argspec now uses inspect.signature instead of inspect.getfullargspec, like help() does. This improves the signature in the call tip in a few different cases, including builtins converted to provide a signature. A message is added if the object is not callable, has an invalid signature, or if it has positional-only parameters.
Patch by Louie Lu..
(cherry picked from commit 3b0f620c1a2a21272a9e2aeca6ca1d1ac10f8162)
Diffstat (limited to 'Lib/idlelib/calltips.py')
-rw-r--r-- | Lib/idlelib/calltips.py | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/Lib/idlelib/calltips.py b/Lib/idlelib/calltips.py index a8a3abe..49625ea 100644 --- a/Lib/idlelib/calltips.py +++ b/Lib/idlelib/calltips.py @@ -123,6 +123,8 @@ _MAX_LINES = 5 # enough for bytes _INDENT = ' '*4 # for wrapped signatures _first_param = re.compile(r'(?<=\()\w*\,?\s*') _default_callable_argspec = "See source or doc" +_invalid_method = "invalid method signature" +_argument_positional = "\n['/' marks preceding arguments as positional-only]\n" def get_argspec(ob): @@ -134,25 +136,30 @@ def get_argspec(ob): empty line or _MAX_LINES. For builtins, this typically includes the arguments in addition to the return value. ''' - argspec = "" + argspec = default = "" try: ob_call = ob.__call__ except BaseException: - return argspec - if isinstance(ob, type): - fob = ob.__init__ - elif isinstance(ob_call, types.MethodType): - fob = ob_call - else: - fob = ob - if isinstance(fob, (types.FunctionType, types.MethodType)): - argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) - if (isinstance(ob, (type, types.MethodType)) or - isinstance(ob_call, types.MethodType)): - argspec = _first_param.sub("", argspec) + return default + + fob = ob_call if isinstance(ob_call, types.MethodType) else ob + + try: + argspec = str(inspect.signature(fob)) + except ValueError as err: + msg = str(err) + if msg.startswith(_invalid_method): + return _invalid_method + + if '/' in argspec: + """Using AC's positional argument should add the explain""" + argspec += _argument_positional + if isinstance(fob, type) and argspec == '()': + """fob with no argument, use default callable argspec""" + argspec = _default_callable_argspec lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT) - if len(argspec) > _MAX_COLS else [argspec] if argspec else []) + if len(argspec) > _MAX_COLS else [argspec] if argspec else []) if isinstance(ob_call, types.MethodType): doc = ob_call.__doc__ @@ -171,6 +178,7 @@ def get_argspec(ob): argspec = _default_callable_argspec return argspec + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_calltips', verbosity=2) |