Issue #20338: Increase allowed tip width slightly and wrap long signagure lines.

Original patch by Serhiy Storchaka.
This commit is contained in:
Terry Jan Reedy 2014-01-26 19:55:34 -05:00
parent 94338de49b
commit a0f1e22068
2 changed files with 33 additions and 14 deletions

View File

@ -5,16 +5,16 @@ parameter and docstring information when you type an opening parenthesis, and
which disappear when you type a closing parenthesis. which disappear when you type a closing parenthesis.
""" """
import __main__
import inspect
import re import re
import sys import sys
import textwrap
import types import types
import inspect
from idlelib import CallTipWindow from idlelib import CallTipWindow
from idlelib.HyperParser import HyperParser from idlelib.HyperParser import HyperParser
import __main__
class CallTips: class CallTips:
menudefs = [ menudefs = [
@ -117,8 +117,9 @@ def get_entity(expression):
return None return None
# The following are used in get_argspec and some in tests # The following are used in get_argspec and some in tests
_MAX_COLS = 79 _MAX_COLS = 85
_MAX_LINES = 5 # enough for bytes _MAX_LINES = 5 # enough for bytes
_INDENT = ' '*4 # for wrapped signatures
_first_param = re.compile('(?<=\()\w*\,?\s*') _first_param = re.compile('(?<=\()\w*\,?\s*')
_default_callable_argspec = "See source or doc" _default_callable_argspec = "See source or doc"
@ -149,13 +150,15 @@ def get_argspec(ob):
isinstance(ob_call, types.MethodType)): isinstance(ob_call, types.MethodType)):
argspec = _first_param.sub("", argspec) argspec = _first_param.sub("", argspec)
lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT)
if len(argspec) > _MAX_COLS else [argspec] if argspec else [])
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:
lines = [argspec] if argspec else [] for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]:
for line in doc.split('\n', 5)[:_MAX_LINES]:
line = line.strip() line = line.strip()
if not line: if not line:
break break

View File

@ -1,5 +1,6 @@
import unittest import unittest
import idlelib.CallTips as ct import idlelib.CallTips as ct
import textwrap
import types import types
default_tip = ct._default_callable_argspec default_tip = ct._default_callable_argspec
@ -64,20 +65,35 @@ class Get_signatureTest(unittest.TestCase):
gtest(types.MethodType, "method(function, instance)") gtest(types.MethodType, "method(function, instance)")
gtest(SB(), default_tip) gtest(SB(), default_tip)
def test_signature_wrap(self):
self.assertEqual(signature(textwrap.TextWrapper), '''\
(width=70, initial_indent='', subsequent_indent='', expand_tabs=True,
replace_whitespace=True, fix_sentence_endings=False, break_long_words=True,
drop_whitespace=True, break_on_hyphens=True, tabsize=8)''')
def test_docline_truncation(self):
def f(): pass
f.__doc__ = 'a'*300
self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...')
def test_multiline_docstring(self): def test_multiline_docstring(self):
# Test fewer lines than max. # Test fewer lines than max.
self.assertEqual(signature(list), self.assertEqual(signature(list),
"list() -> new empty list\n" "list() -> new empty list\n"
"list(iterable) -> new list initialized from iterable's items") "list(iterable) -> new list initialized from iterable's items")
# Test max lines and line (currently) too long. # Test max lines
self.assertEqual(signature(bytes), self.assertEqual(signature(bytes), '''\
"bytes(iterable_of_ints) -> bytes\n" bytes(iterable_of_ints) -> bytes
"bytes(string, encoding[, errors]) -> bytes\n" bytes(string, encoding[, errors]) -> bytes
"bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n" bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
#bytes(int) -> bytes object of size given by the parameter initialized with null bytes bytes(int) -> bytes object of size given by the parameter initialized with null bytes
"bytes(int) -> bytes object of size given by the parameter initialized with n...\n" bytes() -> empty bytes object''')
"bytes() -> empty bytes object")
# Test more than max lines
def f(): pass
f.__doc__ = 'a\n' * 15
self.assertEqual(signature(f), '()' + '\na' * ct._MAX_LINES)
def test_functions(self): def test_functions(self):
def t1(): 'doc' def t1(): 'doc'