[Python-ideas] Is there a reason some of the PyLong_As* functions don't call an object's __int__?

Serhiy Storchaka storchaka at gmail.com
Fri Dec 8 06:26:48 EST 2017

08.12.17 12:41, Erik Bray пише:
> IIUC, it seems to be carry-over from Python 2's PyLong API, but I
> don't see an obvious reason for it.  In every case there's an explicit
> PyLong_Check first anyways, so not calling __int__ doesn't help for
> the common case of exact int objects; adding the fallback costs
> nothing in that case.

There is also a case of int subclasses. It is expected that 
PyLong_AsLong is atomic, and calling __int__ can lead to crashes or 
similar consequences.

> I ran into this because I was passing an object that implements
> __int__ to the maxlen argument to deque().  On Python 2 this used
> PyInt_AsSsize_t which does fall back to calling __int__, whereas
> PyLong_AsSsize_t does not.

PyLong_* functions provide an interface to PyLong objects. If they don't 
return the content of a PyLong object, how can it be retrieved? If you 
want to work with general numbers you should use PyNumber_* functions.

In your particular case it is more reasonable to fallback to __index__ 
rather than __int__. Unlikely maxlen=4.2 makes sense.

> Currently the following functions fall back on __int__ where available:
> PyLong_AsLong
> PyLong_AsLongAndOverflow
> PyLong_AsLongLong
> PyLong_AsLongLongAndOverflow
> PyLong_AsUnsignedLongMask
> PyLong_AsUnsignedLongLongMask

I think this should be deprecated (and there should be an open issue for 
this). Calling __int__ is just a Python 2 legacy.

More information about the Python-ideas mailing list