summaryrefslogtreecommitdiff
path: root/Lib/idlelib/calltips.py
diff options
context:
space:
mode:
authorLouie Lu <git@louie.lu>2017-08-10 08:58:13 +0800
committerTerry Jan Reedy <tjreedy@udel.edu>2017-08-09 20:58:13 -0400
commit3b0f620c1a2a21272a9e2aeca6ca1d1ac10f8162 (patch)
treeed0b81d4643ce3f589307b23fefe70052f2d629f /Lib/idlelib/calltips.py
parent3ca9f50f96cfa5c1b7aa56639042531b57f07fbb (diff)
downloadcpython-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.py36
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)