[docs] [issue17576] PyNumber_Index() is not int-subclass friendly
Barry A. Warsaw
report at bugs.python.org
Fri Mar 29 23:25:11 CET 2013
New submission from Barry A. Warsaw:
operator.index() is just a thin wrapper around PyNumber_Index(). The documentation for operator.index() claims that it is equivalent to calling obj.__index__() but for subclasses of int, this is not true. In fact, PyNumber_Index() first does (e.g. in Python 3.3) a PyLong_Check() and if that succeeds, the original object is returned *without* doing the moral equivalent in C of calling obj.__index__(). An example:
return int(self) + 1
>>> x = myint(7)
>>> from operator import index
The C API documents PyNumber_Index() as: "Returns the o converted to a Python int on success or NULL with a TypeError exception raised on failure."
Because this has been the behavior of PyNumber_Index() since at least 2.7 (I didn't check farther back), this probably cannot be classified as a bug deserving to be fixed in the code for older Pythons. It might be worth fixing for Python 3.4, i.e. by moving the index check before the type check. In the meantime, this is probably a documentation bug.
The C API implies, but should be clearer that if o is an int subtype (int and long in Python 2), it is returned unchanged. The operator.index() documentation should be amended to describe this behavior for int/long subclasses.
A different alternative would be to leave PyNumber_Index() unchanged, but with the doco fix, and to augment operator.index() to do the PyIndex_Check() first, before calling PyNumber_Index(). That's a little more redundant, but would provide the documented behavior without changing the C API.
assignee: docs at python
nosy: barry, docs at python
title: PyNumber_Index() is not int-subclass friendly
versions: Python 2.7, Python 3.1, Python 3.2, Python 3.3, Python 3.4
Python tracker <report at bugs.python.org>
More information about the docs