mirror of https://github.com/python/cpython
Merge heads.
This commit is contained in:
commit
ddc5758885
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
@ -55,32 +56,45 @@ class Get_signatureTest(unittest.TestCase):
|
||||||
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')
|
||||||
gtest(list.__init__,
|
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"
|
append_doc = "L.append(object) -> None -- append object to end"
|
||||||
gtest(list.append, append_doc)
|
gtest(list.append, append_doc)
|
||||||
gtest([].append, append_doc)
|
gtest([].append, append_doc)
|
||||||
gtest(List.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)
|
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):
|
def test_multiline_docstring(self):
|
||||||
# Test fewer lines than max.
|
# Test fewer lines than max.
|
||||||
self.assertEqual(signature(dict),
|
self.assertEqual(signature(list),
|
||||||
"dict(mapping) -> new dictionary initialized from a mapping object's\n"
|
"list() -> new empty list\n"
|
||||||
"(key, value) pairs\n"
|
"list(iterable) -> new list initialized from iterable's items")
|
||||||
"dict(iterable) -> new dictionary initialized as if via:\n"
|
|
||||||
"d = {}\n"
|
|
||||||
"for k, v in iterable:"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test max lines and line (currently) too long.
|
# Test max lines
|
||||||
self.assertEqual(signature(bytes),
|
self.assertEqual(signature(bytes), '''\
|
||||||
"bytes(string, encoding[, errors]) -> bytes\n"
|
bytes(iterable_of_ints) -> bytes
|
||||||
"bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n"
|
bytes(string, encoding[, errors]) -> bytes
|
||||||
#bytes(int) -> bytes object of size given by the parameter initialized with null bytes
|
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
|
||||||
"bytes(int) -> bytes object of size given by the parameter initialized with n...\n"
|
bytes(int) -> bytes object of size given by the parameter initialized with null bytes
|
||||||
"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'
|
||||||
|
|
Loading…
Reference in New Issue