You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
IDLE: Calltip fails if __getattr__ raises exception #60834
The calltip fails if __getattr__ raises an exception. Take as an example:
Python 3.4.0a0 (default:0238cc842805+, Dec 6 2012, 19:17:04)
[GCC 4.7.2] on linux
Type "copyright", "credits" or "license()" for more information.
>>> classTest:
def __getattr__(self, name):
raise Exception()
>> a = Test()
>> a(
This traceback is sent to stderr:
Exception in Tkinter callback
Traceback (most recent call last):
File "/home/serwy/Code/python/cpython/Lib/tkinter/__init__.py", line 1442, in __call__returnself.func(*args)
File "/home/serwy/Code/python/cpython/Lib/idlelib/MultiCall.py", line 166, in handler
r = l[i](event)
File "/home/serwy/Code/python/cpython/Lib/idlelib/CallTips.py", line 56, in try_open_calltip_eventself.open_calltip(False)
File "/home/serwy/Code/python/cpython/Lib/idlelib/CallTips.py", line 75, in open_calltip
argspec =self.fetch_tip(expression)
File "/home/serwy/Code/python/cpython/Lib/idlelib/CallTips.py", line 101, in fetch_tip
(expression,), {})
File "/home/serwy/Code/python/cpython/Lib/idlelib/rpc.py", line 216, in remotecallreturnself.asyncreturn(seq)
File "/home/serwy/Code/python/cpython/Lib/idlelib/rpc.py", line 247, in asyncreturnreturnself.decoderesponse(response)
File "/home/serwy/Code/python/cpython/Lib/idlelib/rpc.py", line 267, in decoderesponseraise what
Exception
Get_entity already has try-except to block exceptions propagating from eval failure, so wrapping it is redundant. We only need worry about get_argspec.
I presume the failure is in get_argspec in the remote process:
if hasattr(ob, '__call__'):
This can be replaced by callable(ob) as it converts exceptions to False. The appropriate return for non-callables is the current default, '', which results in no tip.
There are, however, other attribute accesses that could fail. I am reluctant to wrap get_argspec in its entirety, as that would mask bugs in Idle code as well as in user snippets. So I think each access should be protected. Since users will expect a tip for something that is a callable, I think a message might be appropriate. I checked that getattr(ob, name, default) does not convert exception to default.
Their are rpc calls in several places in Idle code. Unless failure can be triggered here in particular by user error, I do not think we should add specific protection here.
I added test_attribute_exception with two subtests for each of two nasty classes. The resulting failures were fixed in CallTips.py by replacing all ob.__call__ references with one reference inside try_except that saved the method for possible later use.
Activity
serwy commentedon Dec 7, 2012
The calltip fails if __getattr__ raises an exception. Take as an example:
This traceback is sent to stderr:
The attached patch fixes the issue.
serhiy-storchaka commentedon Dec 7, 2012
rpcclt.remotecall also can raise an exception.
I think fetch_tip() should return '' in case of exception as for non-existent arguments or for non-callables. You can add tests for this cases too.
"break" is a reserved word. It's not a good name for an attribute.
It will be better test for exception an instance of the special class and not break TC.
terryjreedy commentedon Jan 10, 2014
Get_entity already has try-except to block exceptions propagating from eval failure, so wrapping it is redundant. We only need worry about get_argspec.
I presume the failure is in get_argspec in the remote process:
if hasattr(ob, '__call__'):
This can be replaced by callable(ob) as it converts exceptions to False. The appropriate return for non-callables is the current default, '', which results in no tip.
There are, however, other attribute accesses that could fail. I am reluctant to wrap get_argspec in its entirety, as that would mask bugs in Idle code as well as in user snippets. So I think each access should be protected. Since users will expect a tip for something that is a callable, I think a message might be appropriate. I checked that getattr(ob, name, default) does not convert exception to default.
Their are rpc calls in several places in Idle code. Unless failure can be triggered here in particular by user error, I do not think we should add specific protection here.
python-dev commentedon Jan 21, 2014
New changeset d55d1cbf5f9a by Terry Jan Reedy in branch '2.7':
Issue bpo-16630: Make Idle calltips work even when __getattr__ raises.
http://hg.python.org/cpython/rev/d55d1cbf5f9a
New changeset 2fe0b2dcc98c by Terry Jan Reedy in branch '3.3':
Issue bpo-16630: Make Idle calltips work even when __getattr__ raises.
http://hg.python.org/cpython/rev/2fe0b2dcc98c
terryjreedy commentedon Jan 21, 2014
I added test_attribute_exception with two subtests for each of two nasty classes. The resulting failures were fixed in CallTips.py by replacing all ob.__call__ references with one reference inside try_except that saved the method for possible later use.