summaryrefslogtreecommitdiffstats
path: root/Objects/classobject.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/classobject.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/classobject.c')
-rw-r--r--Objects/classobject.c69
1 files changed, 60 insertions, 9 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 3b97a02..66d1080 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -972,6 +972,27 @@ instance_item(PyInstanceObject *inst, int i)
}
static PyObject *
+sliceobj_from_intint(int i, int j)
+{
+ PyObject *start, *end, *res;
+
+ start = PyInt_FromLong((long)i);
+ if (!start)
+ return NULL;
+
+ end = PyInt_FromLong((long)j);
+ if (!end) {
+ Py_DECREF(start);
+ return NULL;
+ }
+ res = PySlice_New(start, end, NULL);
+ Py_DECREF(start);
+ Py_DECREF(end);
+ return res;
+}
+
+
+static PyObject *
instance_slice(PyInstanceObject *inst, int i, int j)
{
PyObject *func, *arg, *res;
@@ -980,9 +1001,19 @@ instance_slice(PyInstanceObject *inst, int i, int j)
if (getslicestr == NULL)
getslicestr = PyString_InternFromString("__getslice__");
func = instance_getattr(inst, getslicestr);
- if (func == NULL)
- return NULL;
- arg = Py_BuildValue("(ii)", i, j);
+
+ if (func == NULL) {
+ PyErr_Clear();
+
+ if (getitemstr == NULL)
+ getitemstr = PyString_InternFromString("__getitem__");
+ func = instance_getattr(inst, getitemstr);
+ if (func == NULL)
+ return NULL;
+ arg = Py_BuildValue("(N)", sliceobj_from_intint(i, j));
+ } else
+ arg = Py_BuildValue("(ii)", i, j);
+
if (arg == NULL) {
Py_DECREF(func);
return NULL;
@@ -1038,19 +1069,39 @@ instance_ass_slice(PyInstanceObject *inst, int i, int j, PyObject *value)
delslicestr =
PyString_InternFromString("__delslice__");
func = instance_getattr(inst, delslicestr);
+ if (func == NULL) {
+ PyErr_Clear();
+ if (delitemstr == NULL)
+ delitemstr =
+ PyString_InternFromString("__delitem__");
+ func = instance_getattr(inst, delitemstr);
+ if (func == NULL)
+ return -1;
+
+ arg = Py_BuildValue("(N)",
+ sliceobj_from_intint(i, j));
+ } else
+ arg = Py_BuildValue("(ii)", i, j);
}
else {
if (setslicestr == NULL)
setslicestr =
PyString_InternFromString("__setslice__");
func = instance_getattr(inst, setslicestr);
+ if (func == NULL) {
+ PyErr_Clear();
+ if (setitemstr == NULL)
+ setitemstr =
+ PyString_InternFromString("__setitem__");
+ func = instance_getattr(inst, setitemstr);
+ if (func == NULL)
+ return -1;
+
+ arg = Py_BuildValue("(NO)",
+ sliceobj_from_intint(i, j), value);
+ } else
+ arg = Py_BuildValue("(iiO)", i, j, value);
}
- if (func == NULL)
- return -1;
- if (value == NULL)
- arg = Py_BuildValue("(ii)", i, j);
- else
- arg = Py_BuildValue("(iiO)", i, j, value);
if (arg == NULL) {
Py_DECREF(func);
return -1;