[Python-Dev] unsubscriptable vs object does not support indexing

Brett Cannon brett at python.org
Wed Sep 23 19:53:50 CEST 2009


On Tue, Sep 22, 2009 at 20:08, R. David Murray <rdmurray at bitdance.com> wrote:
> 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?

Let's ignore history, which I bet is the reason for the distinction,
and just look at the error messages; does the distinction make sense
to a newbie? I would say no and that the "does not support indexing"
error message is more useful. For expert programmers they could figure
out the problem with either error message. The only help is if you are
trying to debug a type, but I am willing to bet most of us didn't know
the distinction at the C level until David looked it up.

So I am +1 on unified the message and +1 on using the "does not
support indexing" one.

-Brett


More information about the Python-Dev mailing list