Commit d6b91798 authored by Terry Jan Reedy's avatar Terry Jan Reedy

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

Original patch by Serhiy Storchaka.
parent b930f230
...@@ -5,16 +5,16 @@ parameter and docstring information when you type an opening parenthesis, and ...@@ -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): ...@@ -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): ...@@ -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
......
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): ...@@ -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'
......
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