diff options
author | Louie Lu <git@louie.lu> | 2017-08-10 08:58:13 +0800 |
---|---|---|
committer | Terry Jan Reedy <tjreedy@udel.edu> | 2017-08-09 20:58:13 -0400 |
commit | 3b0f620c1a2a21272a9e2aeca6ca1d1ac10f8162 (patch) | |
tree | ed0b81d4643ce3f589307b23fefe70052f2d629f /Lib/idlelib/calltips.py | |
parent | 3ca9f50f96cfa5c1b7aa56639042531b57f07fbb (diff) | |
download | cpython-git-3b0f620c1a2a21272a9e2aeca6ca1d1ac10f8162.tar.gz |
bpo-19903: IDLE: Calltips changed to use inspect.signature (#2822)
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.
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 a8a3abe6c6..49625eac15 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) |