Checking in the code for PEP 357.
This was mostly written by Travis Oliphant.
I've inspected it all; Neal Norwitz and MvL have also looked at it
(in an earlier incarnation).
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 9837e38..681fb21 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3051,6 +3051,9 @@
COPYNUM(nb_inplace_true_divide);
COPYNUM(nb_inplace_floor_divide);
}
+ if (base->tp_flags & Py_TPFLAGS_HAVE_INDEX) {
+ COPYNUM(nb_index);
+ }
}
if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
@@ -4344,6 +4347,44 @@
return result;
}
+
+static Py_ssize_t
+slot_nb_index(PyObject *self)
+{
+ PyObject *func, *args;
+ static PyObject *index_str;
+ Py_ssize_t result = -1;
+
+ func = lookup_maybe(self, "__index__", &index_str);
+ if (func == NULL) {
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "object cannot be interpreted as an index");
+ }
+ return -1;
+ }
+ args = PyTuple_New(0);
+ if (args != NULL) {
+ PyObject *temp = PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ if (temp != NULL) {
+ if (PyInt_Check(temp) || PyLong_Check(temp)) {
+ result =
+ temp->ob_type->tp_as_number->nb_index(temp);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "__index__ must return an int or a long");
+ result = -1;
+ }
+ Py_DECREF(temp);
+ }
+ }
+ Py_DECREF(func);
+ return result;
+}
+
+
SLOT0(slot_nb_invert, "__invert__")
SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__")
@@ -5069,6 +5110,8 @@
"oct(x)"),
UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
"hex(x)"),
+ NBSLOT("__index__", nb_index, slot_nb_index, wrap_lenfunc,
+ "x[y:z] <==> x[y.__index__():z.__index__()]"),
IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
wrap_binaryfunc, "+"),
IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,