Merge with 3.3
This commit is contained in:
commit
3f440de7d3
|
@ -116,17 +116,21 @@ def get_entity(expression):
|
|||
# exception, especially if user classes are involved.
|
||||
return None
|
||||
|
||||
# The following are used in both get_argspec and tests
|
||||
# The following are used in get_argspec and some in tests
|
||||
_MAX_COLS = 79
|
||||
_MAX_LINES = 5 # enough for bytes
|
||||
_first_param = re.compile('(?<=\()\w*\,?\s*')
|
||||
_default_callable_argspec = "See source or doc"
|
||||
|
||||
|
||||
def get_argspec(ob):
|
||||
'''Return a string describing the signature of a callable object, or ''.
|
||||
|
||||
For Python-coded functions and methods, the first line is introspected.
|
||||
Delete 'self' parameter for classes (.__init__) and bound methods.
|
||||
The last line is the first line of the doc string. For builtins, this typically
|
||||
includes the arguments in addition to the return value.
|
||||
The next lines are the first lines of the doc string up to the first
|
||||
empty line or _MAX_LINES. For builtins, this typically includes
|
||||
the arguments in addition to the return value.
|
||||
'''
|
||||
argspec = ""
|
||||
try:
|
||||
|
@ -150,13 +154,15 @@ def get_argspec(ob):
|
|||
else:
|
||||
doc = getattr(ob, "__doc__", "")
|
||||
if doc:
|
||||
doc = doc.lstrip()
|
||||
pos = doc.find("\n")
|
||||
if pos < 0 or pos > 70:
|
||||
pos = 70
|
||||
if argspec:
|
||||
argspec += "\n"
|
||||
argspec += doc[:pos]
|
||||
lines = [argspec] if argspec else []
|
||||
for line in doc.split('\n', 5)[:_MAX_LINES]:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
break
|
||||
if len(line) > _MAX_COLS:
|
||||
line = line[: _MAX_COLS - 3] + '...'
|
||||
lines.append(line)
|
||||
argspec = '\n'.join(lines)
|
||||
if not argspec:
|
||||
argspec = _default_callable_argspec
|
||||
return argspec
|
||||
|
|
|
@ -42,17 +42,15 @@ class Get_signatureTest(unittest.TestCase):
|
|||
# For a simple mismatch, change the expected output to the actual.
|
||||
|
||||
def test_builtins(self):
|
||||
# These test will break if
|
||||
|
||||
# Python class that inherits builtin methods
|
||||
class List(list): "List() doc"
|
||||
# Simulate builtin with no docstring for default argspec test
|
||||
# Simulate builtin with no docstring for default tip test
|
||||
class SB: __call__ = None
|
||||
|
||||
def gtest(obj, out):
|
||||
self.assertEqual(signature(obj), out)
|
||||
|
||||
gtest(list, "list() -> new empty list")
|
||||
gtest(List, List.__doc__)
|
||||
gtest(list.__new__,
|
||||
'T.__new__(S, ...) -> a new object with type S, a subtype of T')
|
||||
|
@ -66,6 +64,21 @@ class Get_signatureTest(unittest.TestCase):
|
|||
gtest(types.MethodType, "method(function, instance)")
|
||||
gtest(SB(), default_tip)
|
||||
|
||||
def test_multiline_docstring(self):
|
||||
# Test fewer lines than max.
|
||||
self.assertEqual(signature(list),
|
||||
"list() -> new empty list\n"
|
||||
"list(iterable) -> new list initialized from iterable's items")
|
||||
|
||||
# Test max lines and line (currently) too long.
|
||||
self.assertEqual(signature(bytes),
|
||||
"bytes(iterable_of_ints) -> bytes\n"
|
||||
"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")
|
||||
|
||||
def test_functions(self):
|
||||
def t1(): 'doc'
|
||||
t1.tip = "()"
|
||||
|
@ -100,7 +113,8 @@ class Get_signatureTest(unittest.TestCase):
|
|||
assert ct._first_param.sub('', uni) == '(a)'
|
||||
|
||||
def test_no_docstring(self):
|
||||
def nd(s): pass
|
||||
def nd(s):
|
||||
pass
|
||||
TC.nd = nd
|
||||
self.assertEqual(signature(nd), "(s)")
|
||||
self.assertEqual(signature(TC.nd), "(s)")
|
||||
|
|
Loading…
Reference in New Issue