#
11 PEP 357: The '__index__' method

The NumPy developers had a problem that could only be solved by adding a new special method, `__index__`. When using slice notation, as in `[start:stop:step]`, the values of the start, stop, and step indexes must all be either integers or long integers. NumPy defines a variety of specialized integer types corresponding to unsigned and signed integers of 8, 16, 32, and 64 bits, but there was no way to signal that these types could be used as slice indexes.

Slicing can't just use the existing `__int__` method because that method is also used to implement coercion to integers. If slicing used `__int__`, floating-point numbers would also become legal slice indexes and that's clearly an undesirable behaviour.

Instead, a new special method called `__index__` was added. It takes no arguments and returns an integer giving the slice index to use. For example:

    class C:
        def __index__ (self):
            return self.value

The return value must be either a Python integer or long integer. The interpreter will check that the type returned is correct, and raises a `TypeError` if this requirement isn't met.

A corresponding `nb_index` slot was added to the C-level `PyNumberMethods` structure to let C extensions implement this protocol. `PyNumber_Index(obj)` can be used in extension code to call the `__index__` function and retrieve its result.

See Also:

PEP 357, Allowing Any Object to be Used for Slicing
  PEP written and implemented by Travis Oliphant.