[Python-Dev] unsubscriptable vs object does not support indexing
R. David Murray
rdmurray at bitdance.com
Wed Sep 23 05:08:07 CEST 2009
On Wed, 23 Sep 2009 at 02:01, MRAB wrote:
> Dino Viehland wrote:
>> Is there a reason or a rule by which CPython reports different error
>> message for different failures to subscript?
>>
>> For example:
>>
>> > > > set()[2]
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> TypeError: 'set' object does not support indexing
>> > > > class c(object): pass
>> ...
[....]
>> > > > [].append[42]
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> TypeError: 'builtin_function_or_method' object is unsubscriptable
[...]
>> IronPython had a bug report that we were getting this wrong for set
>> objects and that does not support indexing was also a clearer error
>> message. Im wondering if theres some reason why the different error
>> messages occur which Im missing. Otherwise I could switch to using the
>> more clear message or start marking types which should report the
>> unsubscriptable error. Does anyone have any insights into this?
>>
> I thought that the difference might be between iterable and non-iterable
> objects, but then I'd expect the class 'c' to behave like the other
> non-iterables. In fact, the result is different again if it's an
> old-style class:
>
>> > > class c: pass
>> > > c()[2]
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> c()[2]
> AttributeError: c instance has no attribute '__getitem__'
Looking at the source, these messages are generated from abstract.c, and
the difference appears to be whether or not the tp_as_sequence slot is
filled in or not. If it is, but there is no sq_item method, then
PySequence_GetItem gives the "does not support indexing" message.
If it isn't filled in, you get the 'not subscriptable"(*) message from
PyObject_GetItem.
The logic appears to be, roughly, if an object does not have mapping
methods, or has them but does not have mp_subscript, and does have
sequence methods but does not have sq_item, then you get a 'does
not support indexing'. Otherwise you get 'not subscriptable'.
The question is, is this a useful distinction, or is it an
implementation artifact?
--David
(*) The error message changed format slightly in 2.7 due to
http://bugs.python.org/issue5760, and the discussion there is
worth reading in this context.
More information about the Python-Dev
mailing list