[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.  I’m wondering if there’s some reason why the different error
>>  messages occur which I’m 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