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

M.-A. Lemburg mal at egenix.com
Wed Sep 23 23:17:16 CEST 2009

Brett Cannon wrote:
> 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.

+1 as well.

Note that the wording of error message has never been something
we guaranteed backwards compatibility for, so such changes are a
lot easier to implement than API changes.

(I just hope that doctest doesn't rely on the message texts.)

Marc-Andre Lemburg

Professional Python Services directly from the Source  (#1, Sep 23 2009)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611

More information about the Python-Dev mailing list