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.

See About this document... for information on suggesting changes.