diff options
Diffstat (limited to 'Objects/structseq.c')
-rw-r--r-- | Objects/structseq.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/Objects/structseq.c b/Objects/structseq.c index 5e57f1f..a3ff045 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -90,6 +90,54 @@ structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high) } static PyObject * +structseq_subscript(PyStructSequence *self, PyObject *item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + + if (i < 0) + i += VISIBLE_SIZE(self); + + if (i < 0 || i >= VISIBLE_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, + "tuple index out of range"); + return NULL; + } + Py_INCREF(self->ob_item[i]); + return self->ob_item[i]; + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelen, cur, i; + PyObject *result; + + if (PySlice_GetIndicesEx((PySliceObject *)item, + VISIBLE_SIZE(self), &start, &stop, + &step, &slicelen) < 0) { + return NULL; + } + if (slicelen <= 0) + return PyTuple_New(0); + result = PyTuple_New(slicelen); + if (result == NULL) + return NULL; + for (cur = start, i = 0; i < slicelen; + cur += step, i++) { + PyObject *v = self->ob_item[cur]; + Py_INCREF(v); + PyTuple_SET_ITEM(result, i, v); + } + return result; + } + else { + PyErr_SetString(PyExc_TypeError, + "structseq index must be integer"); + return NULL; + } +} + +static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *arg = NULL; @@ -298,6 +346,11 @@ static PySequenceMethods structseq_as_sequence = { (objobjproc)structseq_contains, /* sq_contains */ }; +static PyMappingMethods structseq_as_mapping = { + (lenfunc)structseq_length, + (binaryfunc)structseq_subscript, +}; + static PyMethodDef structseq_methods[] = { {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL}, @@ -317,7 +370,7 @@ static PyTypeObject _struct_sequence_template = { (reprfunc)structseq_repr, /* tp_repr */ 0, /* tp_as_number */ &structseq_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ + &structseq_as_mapping, /* tp_as_mapping */ structseq_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ |