diff options
author | Thomas Wouters <thomas@python.org> | 2000-08-17 22:37:32 (GMT) |
---|---|---|
committer | Thomas Wouters <thomas@python.org> | 2000-08-17 22:37:32 (GMT) |
commit | 1d75a79c009e500923128716a02efbe86135e64e (patch) | |
tree | 9c978062db6b1e9c4c775a9d4b763fd115bd671e /Objects/abstract.c | |
parent | 68add2e9389e9cb2b74e448201ec101564391fe5 (diff) | |
download | cpython-1d75a79c009e500923128716a02efbe86135e64e.zip cpython-1d75a79c009e500923128716a02efbe86135e64e.tar.gz cpython-1d75a79c009e500923128716a02efbe86135e64e.tar.bz2 |
Apply SF patch #101029: call __getitem__ with a proper slice object if there
is no __getslice__ available. Also does the same for C extension types.
Includes rudimentary documentation (it could use a cross reference to the
section on slice objects, I couldn't figure out how to do that) and a test
suite for all Python __hooks__ I could think of, including the new
behaviour.
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r-- | Objects/abstract.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 4a64daa..8044d86 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -876,10 +876,29 @@ PySequence_GetItem(PyObject *s, int i) return type_error("unindexable object"); } +static PyObject * +sliceobj_from_intint(int i, int j) +{ + PyObject *start, *end, *slice; + start = PyInt_FromLong((long)i); + if (!start) + return NULL; + end = PyInt_FromLong((long)j); + if (!end) { + Py_DECREF(start); + return NULL; + } + slice = PySlice_New(start, end, NULL); + Py_DECREF(start); + Py_DECREF(end); + return slice; +} + PyObject * PySequence_GetSlice(PyObject *s, int i1, int i2) { PySequenceMethods *m; + PyMappingMethods *mp; if (!s) return null_error(); @@ -897,6 +916,14 @@ PySequence_GetSlice(PyObject *s, int i1, int i2) } } return m->sq_slice(s, i1, i2); + } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) { + PyObject *res; + PyObject *slice = sliceobj_from_intint(i1, i2); + if (!slice) + return NULL; + res = mp->mp_subscript(s, slice); + Py_DECREF(slice); + return res; } return type_error("unsliceable object"); @@ -960,6 +987,7 @@ int PySequence_SetSlice(PyObject *s, int i1, int i2, PyObject *o) { PySequenceMethods *m; + PyMappingMethods *mp; if (s == NULL) { null_error(); @@ -980,7 +1008,16 @@ PySequence_SetSlice(PyObject *s, int i1, int i2, PyObject *o) } } return m->sq_ass_slice(s, i1, i2, o); + } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) { + int res; + PyObject *slice = sliceobj_from_intint(i1, i2); + if (!slice) + return -1; + res = mp->mp_ass_subscript(s, slice, o); + Py_DECREF(slice); + return res; } + type_error("object doesn't support slice assignment"); return -1; } |