mirror of
https://github.com/python/cpython.git
synced 2025-08-22 01:35:16 +00:00
gh-107782: Pydoc: fall back to __text_signature__ if inspect.signature() fails (GH-107786)
It allows to show signatures which are not representable in Python, e.g. for getattr and dict.pop.
This commit is contained in:
parent
5f7d4ecf30
commit
a39f0a3506
3 changed files with 94 additions and 40 deletions
78
Lib/pydoc.py
78
Lib/pydoc.py
|
@ -197,6 +197,24 @@ def splitdoc(doc):
|
|||
return lines[0], '\n'.join(lines[2:])
|
||||
return '', '\n'.join(lines)
|
||||
|
||||
def _getargspec(object):
|
||||
try:
|
||||
signature = inspect.signature(object)
|
||||
if signature:
|
||||
return str(signature)
|
||||
except (ValueError, TypeError):
|
||||
argspec = getattr(object, '__text_signature__', None)
|
||||
if argspec:
|
||||
if argspec[:2] == '($':
|
||||
argspec = '(' + argspec[2:]
|
||||
if getattr(object, '__self__', None) is not None:
|
||||
# Strip the bound argument.
|
||||
m = re.match(r'\(\w+(?:(?=\))|,\s*(?:/(?:(?=\))|,\s*))?)', argspec)
|
||||
if m:
|
||||
argspec = '(' + argspec[m.end():]
|
||||
return argspec
|
||||
return None
|
||||
|
||||
def classname(object, modname):
|
||||
"""Get a class name and qualify it with a module name if necessary."""
|
||||
name = object.__name__
|
||||
|
@ -1003,14 +1021,9 @@ class HTMLDoc(Doc):
|
|||
title = title + '(%s)' % ', '.join(parents)
|
||||
|
||||
decl = ''
|
||||
try:
|
||||
signature = inspect.signature(object)
|
||||
except (ValueError, TypeError):
|
||||
signature = None
|
||||
if signature:
|
||||
argspec = str(signature)
|
||||
if argspec and argspec != '()':
|
||||
decl = name + self.escape(argspec) + '\n\n'
|
||||
argspec = _getargspec(object)
|
||||
if argspec and argspec != '()':
|
||||
decl = name + self.escape(argspec) + '\n\n'
|
||||
|
||||
doc = getdoc(object)
|
||||
if decl:
|
||||
|
@ -1063,18 +1076,13 @@ class HTMLDoc(Doc):
|
|||
anchor, name, reallink)
|
||||
argspec = None
|
||||
if inspect.isroutine(object):
|
||||
try:
|
||||
signature = inspect.signature(object)
|
||||
except (ValueError, TypeError):
|
||||
signature = None
|
||||
if signature:
|
||||
argspec = str(signature)
|
||||
if realname == '<lambda>':
|
||||
title = '<strong>%s</strong> <em>lambda</em> ' % name
|
||||
# XXX lambda's won't usually have func_annotations['return']
|
||||
# since the syntax doesn't support but it is possible.
|
||||
# So removing parentheses isn't truly safe.
|
||||
argspec = argspec[1:-1] # remove parentheses
|
||||
argspec = _getargspec(object)
|
||||
if argspec and realname == '<lambda>':
|
||||
title = '<strong>%s</strong> <em>lambda</em> ' % name
|
||||
# XXX lambda's won't usually have func_annotations['return']
|
||||
# since the syntax doesn't support but it is possible.
|
||||
# So removing parentheses isn't truly safe.
|
||||
argspec = argspec[1:-1] # remove parentheses
|
||||
if not argspec:
|
||||
argspec = '(...)'
|
||||
|
||||
|
@ -1321,14 +1329,9 @@ location listed above.
|
|||
contents = []
|
||||
push = contents.append
|
||||
|
||||
try:
|
||||
signature = inspect.signature(object)
|
||||
except (ValueError, TypeError):
|
||||
signature = None
|
||||
if signature:
|
||||
argspec = str(signature)
|
||||
if argspec and argspec != '()':
|
||||
push(name + argspec + '\n')
|
||||
argspec = _getargspec(object)
|
||||
if argspec and argspec != '()':
|
||||
push(name + argspec + '\n')
|
||||
|
||||
doc = getdoc(object)
|
||||
if doc:
|
||||
|
@ -1492,18 +1495,13 @@ location listed above.
|
|||
argspec = None
|
||||
|
||||
if inspect.isroutine(object):
|
||||
try:
|
||||
signature = inspect.signature(object)
|
||||
except (ValueError, TypeError):
|
||||
signature = None
|
||||
if signature:
|
||||
argspec = str(signature)
|
||||
if realname == '<lambda>':
|
||||
title = self.bold(name) + ' lambda '
|
||||
# XXX lambda's won't usually have func_annotations['return']
|
||||
# since the syntax doesn't support but it is possible.
|
||||
# So removing parentheses isn't truly safe.
|
||||
argspec = argspec[1:-1] # remove parentheses
|
||||
argspec = _getargspec(object)
|
||||
if argspec and realname == '<lambda>':
|
||||
title = self.bold(name) + ' lambda '
|
||||
# XXX lambda's won't usually have func_annotations['return']
|
||||
# since the syntax doesn't support but it is possible.
|
||||
# So removing parentheses isn't truly safe.
|
||||
argspec = argspec[1:-1] # remove parentheses
|
||||
if not argspec:
|
||||
argspec = '(...)'
|
||||
decl = asyncqualifier + title + argspec + note
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue