Commit e7a72a19 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 59243655
...@@ -5,14 +5,15 @@ parameter and docstring information when you type an opening parenthesis, and ...@@ -5,14 +5,15 @@ 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 re import re
import sys import sys
import textwrap
import types import types
from idlelib import CallTipWindow from idlelib import CallTipWindow
from idlelib.HyperParser import HyperParser from idlelib.HyperParser import HyperParser
import __main__
class CallTips: class CallTips:
...@@ -131,8 +132,9 @@ def _find_constructor(class_ob): ...@@ -131,8 +132,9 @@ def _find_constructor(class_ob):
return None return None
# The following are used in get_arg_text # The following are used in get_arg_text
_MAX_COLS = 79 _MAX_COLS = 85
_MAX_LINES = 5 # enough for bytes _MAX_LINES = 5 # enough for bytes
_INDENT = ' '*4 # for wrapped signatures
def get_arg_text(ob): def get_arg_text(ob):
'''Return a string describing the signature of a callable object, or ''. '''Return a string describing the signature of a callable object, or ''.
...@@ -147,11 +149,15 @@ def get_arg_text(ob): ...@@ -147,11 +149,15 @@ def get_arg_text(ob):
try: try:
ob_call = ob.__call__ ob_call = ob.__call__
except BaseException: except BaseException:
if type(ob) is types.ClassType: # old-style
ob_call = ob
else:
return argspec return argspec
arg_offset = 0 arg_offset = 0
if type(ob) in (types.ClassType, types.TypeType): if type(ob) in (types.ClassType, types.TypeType):
# Look for the highest __init__ in the class chain. # Look for the first __init__ in the class chain with .im_func.
# Slot wrappers (builtins, classes defined in funcs) do not.
fob = _find_constructor(ob) fob = _find_constructor(ob)
if fob is None: if fob is None:
fob = lambda: None fob = lambda: None
...@@ -183,14 +189,16 @@ def get_arg_text(ob): ...@@ -183,14 +189,16 @@ def get_arg_text(ob):
items.append("**kwds") items.append("**kwds")
argspec = ", ".join(items) argspec = ", ".join(items)
argspec = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", argspec) argspec = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", argspec)
# See if we can use the docstring
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
CTi = ct.CallTips() # needed for get_entity test in 2.7 CTi = ct.CallTips() # needed for get_entity test in 2.7
import textwrap
import types import types
default_tip = '' default_tip = ''
...@@ -66,6 +67,18 @@ class Get_signatureTest(unittest.TestCase): ...@@ -66,6 +67,18 @@ 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_signature_wrap(self):
# This is also a test of an old-style class
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)''')
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),
......
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