[Python-Dev] boxing and unboxing data types
Steven D'Aprano
steve at pearwood.info
Mon Mar 9 05:12:44 CET 2015
On Sun, Mar 08, 2015 at 08:31:30PM -0700, Ethan Furman wrote:
> When data is passed from Python to a native library (such as in an O/S
> call), how does the unboxing of data types occur?
[...]
> So the real question: anywhere in Python where an int is expected (for
> lower-level API work), but not directly received, should __int__ (or
> __index__) be called? and failure to do so is a bug?
I think the answer is in the docs:
https://docs.python.org/3/reference/datamodel.html#object.__int__
Immediately below that __index__ is described, with this note:
In order to have a coherent integer type class, when
__index__() is defined __int__() should also be defined,
and both should return the same value.
The PEP adding __index__ is also useful:
https://www.python.org/dev/peps/pep-0357/
My summary is as follows:
__int__ is used as the special method for int(), and it should coerce
the object to an integer. This may be lossy e.g. int(2.999) --> 2 or may
involve a conversion from a non-numeric type to integer e.g. int("2").
__index__ is used when the object in question actually represents an
integer of some kind, e.g. a fixed-with integer. Conversion should be
lossless and conceptually may be thought of a way of telling Python
"this value actually is an int, even though it doesn't inherit from int"
(for some definition of "is an int").
There's no built-in way of calling __index__ that I know of (no
equivalent to int(obj)), but slicing at the very least will call it,
e.g. seq[a:] will call type(a).__index__.
If you define __index__ for your class, you should also define __int__
and have the two return the same value. I would expect that an IntFlags
object should inherit from int, and if that is not possible, practical
or desirable for some reason, then it should define __index__ and
__int__.
Failure to call __index__ is not necessarily a bug. I think it is
allowed for functions to insist on an actual int, as slicing did for
many years, but it is an obvious enhancement to allow such functions to
accept arbitrary int-like objects.
Does that answer your questions?
--
Steve
More information about the Python-Dev
mailing list