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/classobject.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/classobject.c')
-rw-r--r-- | Objects/classobject.c | 69 |
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; |