summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/CallTips.py
diff options
context:
space:
mode:
authorTerry Jan Reedy <tjreedy@udel.edu>2014-01-21 20:36:51 (GMT)
committerTerry Jan Reedy <tjreedy@udel.edu>2014-01-21 20:36:51 (GMT)
commit715476d8e325c41b8fbdcd3fb22d6538aafc0c3e (patch)
tree5f1ac2c7cdc83ad7c6107a8756fd419cd2edc2f3 /Lib/idlelib/CallTips.py
parent65fd0592fb3845c17b27c441380553fc22f78812 (diff)
downloadcpython-715476d8e325c41b8fbdcd3fb22d6538aafc0c3e.zip
cpython-715476d8e325c41b8fbdcd3fb22d6538aafc0c3e.tar.gz
cpython-715476d8e325c41b8fbdcd3fb22d6538aafc0c3e.tar.bz2
Issue #16630: Make Idle calltips work even when __getattr__ raises.
Initial patch by Roger Serwy.
Diffstat (limited to 'Lib/idlelib/CallTips.py')
-rw-r--r--Lib/idlelib/CallTips.py64
1 files changed, 33 insertions, 31 deletions
diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py
index cb46a89..83bb638 100644
--- a/Lib/idlelib/CallTips.py
+++ b/Lib/idlelib/CallTips.py
@@ -118,47 +118,49 @@ def get_entity(expression):
# The following are used in both get_argspec and tests
_first_param = re.compile('(?<=\()\w*\,?\s*')
-_default_callable_argspec = "No docstring, see docs."
+_default_callable_argspec = "See source or doc"
def get_argspec(ob):
- '''Return a string describing the arguments and return of a callable object.
+ '''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.
-
'''
argspec = ""
- if hasattr(ob, '__call__'):
- if isinstance(ob, type):
- fob = getattr(ob, '__init__', None)
- elif isinstance(ob.__call__, types.MethodType):
- fob = ob.__call__
- else:
- fob = ob
- if isinstance(fob, (types.FunctionType, types.MethodType)):
- argspec = inspect.formatargspec(*inspect.getfullargspec(fob))
- if (isinstance(ob, (type, types.MethodType)) or
- isinstance(ob.__call__, types.MethodType)):
- argspec = _first_param.sub("", argspec)
-
- if isinstance(ob.__call__, types.MethodType):
- doc = ob.__call__.__doc__
- 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]
- if not argspec:
- argspec = _default_callable_argspec
+ try:
+ ob_call = ob.__call__
+ except BaseException:
+ return argspec
+ if isinstance(ob, type):
+ fob = ob.__init__
+ elif isinstance(ob_call, types.MethodType):
+ fob = ob_call
+ else:
+ fob = ob
+ if isinstance(fob, (types.FunctionType, types.MethodType)):
+ argspec = inspect.formatargspec(*inspect.getfullargspec(fob))
+ if (isinstance(ob, (type, types.MethodType)) or
+ isinstance(ob_call, types.MethodType)):
+ argspec = _first_param.sub("", argspec)
+
+ if isinstance(ob_call, types.MethodType):
+ doc = ob_call.__doc__
+ 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]
+ if not argspec:
+ argspec = _default_callable_argspec
return argspec
if __name__ == '__main__':
from unittest import main
- main('idlelib.idle_test.test_calltips', verbosity=2, exit=False)
+ main('idlelib.idle_test.test_calltips', verbosity=2)