summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2000-08-17 22:37:32 (GMT)
committerThomas Wouters <thomas@python.org>2000-08-17 22:37:32 (GMT)
commit1d75a79c009e500923128716a02efbe86135e64e (patch)
tree9c978062db6b1e9c4c775a9d4b763fd115bd671e /Objects/abstract.c
parent68add2e9389e9cb2b74e448201ec101564391fe5 (diff)
downloadcpython-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.c37
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;
}