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 (PyInt_Check(key)) return PySequence_GetItem(o, PyInt_AsLong(key)); else if (PyLong_Check(key)) { long key_value = PyLong_AsLong(key); if (key_value == -1 && PyErr_Occurred()) return NULL; return PySequence_GetItem(o, key_value); } return type_error("sequence index must be integer"); } return type_error("unsubscriptable object"); }
/** * Fetch a slice of the Key. */ static PyObject * key_subscript(Key *self, PyObject *key) { if(PySlice_Check(key)) { // TODO: make this more efficient PyObject *tup = PySequence_Tuple((PyObject *) self); PyObject *slice = NULL; PyObject *newkey = NULL; if(tup) { PyMappingMethods *funcs = tup->ob_type->tp_as_mapping; slice = funcs->mp_subscript((PyObject *) tup, key); Py_DECREF(tup); } if(slice) { newkey = key_new(&KeyType, slice, NULL); Py_DECREF(slice); } return newkey; } else { // Fetch the `i`th item from the Key. Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_OverflowError); if(i == -1 && PyErr_Occurred()) { return NULL; } struct reader rdr; rdr.p = Key_DATA(self); rdr.e = Key_SIZE(self) + rdr.p; int eof = rdr.p == rdr.e; if(i < 0) { // TODO: make this more efficient Py_ssize_t len = key_length(self); i += len; eof |= i < 0; } while(i-- && !eof) { if(acid_skip_element(&rdr, &eof)) { return NULL; } } if(eof) { PyErr_SetString(PyExc_IndexError, "Key index out of range"); return NULL; } return acid_read_element(&rdr); } }