[Python-Dev] PyDict_GetItem & dict_subscript
M.-A. Lemburg
mal@lemburg.com
Wed, 14 Nov 2001 13:03:11 +0100
Thomas Heller wrote:
>
> From: "Thomas Wouters" <thomas@xs4all.net>
> >
> > While trying to figure out why passing an unhashable object to switch didn't
> > cause a TypeError: unhashable object, I found out PyDict_GetItem and
> > dict_subscript behave differently in that respect. PyDict_GetItem does:
> >
> > hash = PyObject_Hash(key);
> > if (hash == -1) {
> > PyErr_Clear();
> > return NULL;
> > }
> >
> > whereas dict_subscript does:
> >
> > hash = PyObject_Hash(key);
> > if (hash == -1)
> > return NULL;
> >
> > PyDict_SetItem and PyDict_DelItem both behave like dict_subscript (that is,
> > they propagate the error upwards, instead of clearing the error.) Is this
> > intentional ?
>
> It seems so, at least it's documented.
Yes, that's intentional.
The reason is that historically PyDict_GetItem() was always used in
this way by Python's internal code and many extensions.
> > Why ? :P
>
> Probably because retrieving a value from a dictionary, and trying something
> else (after clearing the error) if it fails is so common...
Right.
> > And what is the 'right' way to do a PyDict_GetItem()
> > that gives the proper error-message without relying on the need for that
> > particular dict (which could be a subtype that has more or less
> > restrictions) to have hashable keys ?
>
> I'd use PyObject_GetItem(), but...
Because of security concerns, the dict must be a read-only dictionary
implementation. Using generic APIs is the wrong approach here. Of course,
since we don't have a read-only dictionary type, the argument is
not relevant to your prototype ;-)
I'd suggest to use this construct:
if ((value = PyDict_GetItem(key)) == NULL) {
if (PyObject_Hash(key) == -1)
return NULL;
else
goto notFound;
}
--
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
______________________________________________________________________
Consulting & Company: http://www.egenix.com/
Python Software: http://www.lemburg.com/python/