Commit 82c48e09 authored by Terry Jan Reedy's avatar Terry Jan Reedy

Issue #16638: Include up to 5 docstring header lines (before first blank) in

Idle calltips. This is needed for builtins, such 3.x bytes (which is why 5).
Based on patch by Serhiy Storchaka.
parent edfd9add
...@@ -130,14 +130,24 @@ def _find_constructor(class_ob): ...@@ -130,14 +130,24 @@ def _find_constructor(class_ob):
if rc is not None: return rc if rc is not None: return rc
return None return None
# The following are used in get_arg_text
_MAX_COLS = 79
_MAX_LINES = 5 # enough for bytes
def get_arg_text(ob): def get_arg_text(ob):
"""Get a string describing the arguments for the given object, '''Return a string describing the signature of a callable object, or ''.
only if it is callable."""
arg_text = "" For Python-coded functions and methods, the first line is introspected.
Delete 'self' parameter for classes (.__init__) and bound methods.
The next lines are the first lines of the doc string up to the first
empty line or _MAX_LINES. For builtins, this typically includes
the arguments in addition to the return value.
'''
argspec = ""
try: try:
ob_call = ob.__call__ ob_call = ob.__call__
except BaseException: except BaseException:
return arg_text return argspec
arg_offset = 0 arg_offset = 0
if type(ob) in (types.ClassType, types.TypeType): if type(ob) in (types.ClassType, types.TypeType):
...@@ -171,22 +181,24 @@ def get_arg_text(ob): ...@@ -171,22 +181,24 @@ def get_arg_text(ob):
items.append("*args") items.append("*args")
if fob.func_code.co_flags & 0x8: if fob.func_code.co_flags & 0x8:
items.append("**kwds") items.append("**kwds")
arg_text = ", ".join(items) argspec = ", ".join(items)
arg_text = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", arg_text) argspec = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", argspec)
# See if we can use the docstring # See if we can use the docstring
if isinstance(ob_call, types.MethodType): if isinstance(ob_call, types.MethodType):
doc = ob_call.__doc__ doc = ob_call.__doc__
else: else:
doc = getattr(ob, "__doc__", "") doc = getattr(ob, "__doc__", "")
if doc: if doc:
doc = doc.lstrip() lines = [argspec] if argspec else []
pos = doc.find("\n") for line in doc.split('\n', 5)[:_MAX_LINES]:
if pos < 0 or pos > 70: line = line.strip()
pos = 70 if not line:
if arg_text: break
arg_text += "\n" if len(line) > _MAX_COLS:
arg_text += doc[:pos] line = line[: _MAX_COLS - 3] + '...'
return arg_text lines.append(line)
argspec = '\n'.join(lines)
return argspec
if __name__ == '__main__': if __name__ == '__main__':
from unittest import main from unittest import main
......
...@@ -53,7 +53,6 @@ class Get_signatureTest(unittest.TestCase): ...@@ -53,7 +53,6 @@ class Get_signatureTest(unittest.TestCase):
def gtest(obj, out): def gtest(obj, out):
self.assertEqual(signature(obj), out) self.assertEqual(signature(obj), out)
gtest(list, "()\nlist() -> new empty list")
gtest(List, '()\n' + List.__doc__) gtest(List, '()\n' + List.__doc__)
gtest(list.__new__, gtest(list.__new__,
'T.__new__(S, ...) -> a new object with type S, a subtype of T') 'T.__new__(S, ...) -> a new object with type S, a subtype of T')
...@@ -67,6 +66,20 @@ class Get_signatureTest(unittest.TestCase): ...@@ -67,6 +66,20 @@ class Get_signatureTest(unittest.TestCase):
gtest(types.MethodType, '()\ninstancemethod(function, instance, class)') gtest(types.MethodType, '()\ninstancemethod(function, instance, class)')
gtest(SB(), default_tip) gtest(SB(), default_tip)
def test_multiline_docstring(self):
# Test fewer lines than max.
self.assertEqual(signature(list),
"()\nlist() -> new empty list\n"
"list(iterable) -> new list initialized from iterable's items")
# Test max lines and line (currently) too long.
def f():
pass
s = 'a\nb\nc\nd\n'
f.__doc__ = s + 300 * 'e' + 'f'
self.assertEqual(signature(f),
'()\n' + s + (ct._MAX_COLS - 3) * 'e' + '...')
def test_functions(self): def test_functions(self):
def t1(): 'doc' def t1(): 'doc'
t1.tip = "()" t1.tip = "()"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment