Reputation: 30684
Documentation for PyObject_GetItem and PyObject_SetItem here states:
PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Return value: New reference.
Return element of o corresponding to the object key or NULL on failure. This is the equivalent of the Python expression o[key].
int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
Map the object key to the value v. Returns -1 on failure. This is the equivalent of the Python statement o[key] = v.
foo[key] syntax implies PyType_Dict
However, it doesn't state whether it also works on PyType_List, in which case key would be an index, i.e. a positive PyType_Long, or maybe a type converts into it, e.g. a PyType_Bytes containing "42".
Does this function work for both containers?
I would expect it to; such a design to be in keeping with Python's "it does everything you would expect it to do" philosophy.
Furthermore, the project I'm looking at has a comment forewarning:
// PyObject_SetItem is too weird to be using from C++
// so it is intentionally omitted.
Should I be worried about this? What could it possibly mean? And has it been fixed for Python3?
Upvotes: 1
Views: 964
Reputation: 30684
The answer is that it supports both!
You can find from the source code:
[email protected] ~ /Users/pi/Downloads/Python-3.4.2: ~ grep -R "PyObject_GetItem" . : ./Objects/abstract.c:PyObject_GetItem(PyObject *o, PyObject *key) :
And looking in abstract.c:
PyObject *
PyObject_GetItem(PyObject *o, PyObject *key)
{
PyMappingMethods *m;
if (o == NULL || key == NULL)
return null_error();
m = o->ob_type->tp_as_mapping;
if (m && m->mp_subscript)
return m->mp_subscript(o, key);
if (o->ob_type->tp_as_sequence) {
if (PyIndex_Check(key)) {
Py_ssize_t key_value;
key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (key_value == -1 && PyErr_Occurred())
return NULL;
return PySequence_GetItem(o, key_value);
}
else if (o->ob_type->tp_as_sequence->sq_item)
return type_error("sequence index must "
"be integer, not '%.200s'", key);
}
return type_error("'%.200s' object is not subscriptable", o);
}
Upvotes: 1
Reputation: 798754
Both functions work for all containers that support indexed accesses, be they dict, list, tuple, string, bytes, and so on.
I'm not sure why PyCXX has that comment; it may be due to the fact that Python's dynamic typing does not always mesh well with languages with static typing.
Upvotes: 1