diff options
| -rw-r--r-- | Lib/idlelib/CallTips.py | 15 | ||||
| -rw-r--r-- | Lib/idlelib/idle_test/test_calltips.py | 48 | 
2 files changed, 40 insertions, 23 deletions
| diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py index 4f88da6..81bd5f1 100644 --- a/Lib/idlelib/CallTips.py +++ b/Lib/idlelib/CallTips.py @@ -5,16 +5,16 @@ parameter and docstring information when you type an opening parenthesis, and  which disappear when you type a closing parenthesis.  """ +import __main__ +import inspect  import re  import sys +import textwrap  import types -import inspect  from idlelib import CallTipWindow  from idlelib.HyperParser import HyperParser -import __main__ -  class CallTips:      menudefs = [ @@ -117,8 +117,9 @@ def get_entity(expression):              return None  # The following are used in get_argspec and some in tests -_MAX_COLS = 79 +_MAX_COLS = 85  _MAX_LINES = 5  # enough for bytes +_INDENT = ' '*4  # for wrapped signatures  _first_param = re.compile('(?<=\()\w*\,?\s*')  _default_callable_argspec = "See source or doc" @@ -149,13 +150,15 @@ def get_argspec(ob):                  isinstance(ob_call, types.MethodType)):              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):          doc = ob_call.__doc__      else:          doc = getattr(ob, "__doc__", "")      if doc: -        lines = [argspec] if argspec else [] -        for line in doc.split('\n', 5)[:_MAX_LINES]: +        for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]:              line = line.strip()              if not line:                  break diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py index 5b51732..4bf5e7e 100644 --- a/Lib/idlelib/idle_test/test_calltips.py +++ b/Lib/idlelib/idle_test/test_calltips.py @@ -1,5 +1,6 @@  import unittest  import idlelib.CallTips as ct +import textwrap  import types  default_tip = ct._default_callable_argspec @@ -55,32 +56,45 @@ class Get_signatureTest(unittest.TestCase):          gtest(list.__new__,                 'T.__new__(S, ...) -> a new object with type S, a subtype of T')          gtest(list.__init__, -               'Initializes self.  See help(type(self)) for accurate signature.') +               'x.__init__(...) initializes x; see help(type(x)) for signature')          append_doc =  "L.append(object) -> None -- append object to end"          gtest(list.append, append_doc)          gtest([].append, append_doc)          gtest(List.append, append_doc) -        gtest(types.MethodType, "Create a bound instance method object.") +        gtest(types.MethodType, "method(function, instance)")          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, *, max_lines=None, +    placeholder=' [...]')''') + +    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):          # Test fewer lines than max. -        self.assertEqual(signature(dict), -                "dict(mapping) -> new dictionary initialized from a mapping object's\n" -                "(key, value) pairs\n" -                "dict(iterable) -> new dictionary initialized as if via:\n" -                "d = {}\n" -                "for k, v in iterable:" -                ) - -        # Test max lines and line (currently) too long. -        self.assertEqual(signature(bytes), -"bytes(string, encoding[, errors]) -> bytes\n" -"bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n" -#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") +        self.assertEqual(signature(list), +                "list() -> new empty list\n" +                "list(iterable) -> new list initialized from iterable's items") + +        # Test max lines +        self.assertEqual(signature(bytes), '''\ +bytes(iterable_of_ints) -> bytes +bytes(string, encoding[, errors]) -> bytes +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() -> 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 t1(): 'doc' | 
