diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py index ce09983eec7..d533ce13b95 100644 --- a/Lib/idlelib/CallTips.py +++ b/Lib/idlelib/CallTips.py @@ -71,16 +71,16 @@ class CallTips: if not sur_paren: return hp.set_index(sur_paren[0]) - name = hp.get_expression() - if not name or (not evalfuncs and name.find('(') != -1): + expression = hp.get_expression() + if not expression or (not evalfuncs and expression.find('(') != -1): return - arg_text = self.fetch_tip(name) + arg_text = self.fetch_tip(expression) if not arg_text: return self.calltip = self._make_calltip_window() self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1]) - def fetch_tip(self, name): + def fetch_tip(self, expression): """Return the argument list and docstring of a function or class If there is a Python subprocess, get the calltip there. Otherwise, @@ -96,25 +96,27 @@ class CallTips: """ try: rpcclt = self.editwin.flist.pyshell.interp.rpcclt - except: + except AttributeError: rpcclt = None if rpcclt: return rpcclt.remotecall("exec", "get_the_calltip", - (name,), {}) + (expression,), {}) else: - entity = self.get_entity(name) + entity = self.get_entity(expression) return get_arg_text(entity) - def get_entity(self, name): - "Lookup name in a namespace spanning sys.modules and __main.dict__" - if name: + def get_entity(self, expression): + """Return the object corresponding to expression evaluated + in a namespace spanning sys.modules and __main.dict__. + """ + if expression: namespace = sys.modules.copy() namespace.update(__main__.__dict__) try: - return eval(name, namespace) - # any exception is possible if evalfuncs True in open_calltip - # at least Syntax, Name, Attribute, Index, and Key E. if not - except: + return eval(expression, namespace) + except BaseException: + # An uncaught exception closes idle, and eval can raise any + # exception, especially if user classes are involved. return None def _find_constructor(class_ob):