Description
The C-API has built up over 30 years, in a haphazard way. So, it is no surprise that it is a bit of a mess.
What makes it worse is that it is based around the C long
type, which is varies in size between architectures and operating systems in odd ways.
C long
s are 32 bit on (almost?) all 32 bit machines, 64 bit on most 64 bit machines, except Windows when C long
s are 32 bits on 64 bit machines. In other words, it is not a useful fixed size, like int32_t
, nor does match the machine word size, like intptr_t
.
We need a more consistent API for converting from Python integers to C integers and back again.
We should support both 32 bit and word size C integers. 32 bit, because we often want to store 32 bit values to save space on 64 bit machines, or for portability. We also want to support word size integers for performance and ease of coding.
This means we want 4 functions (2 sizes, 2 directions) to convert between C and Python integers.
Currently we have:
Width | Py -> C | C -> Py |
---|---|---|
32 bit | Missing* | Missing |
Machine word | Missing* | PyLong_FromSsize_t |
The C API has a function to convert Python ints to intptr_t
, but it is missing efficient overflow handling.
It also has a function with efficient overflow handling, PyLong_AsLongAndOverflow
, but that returns a long
.
Here's what we want:
Width | Py -> C | C -> Py |
---|---|---|
32 bit | PyInt_AsInt32 |
PyInt_FromInt32 |
Machine word | PyInt_AsSsize_t |
PyInt_FromSsize_t |
I'm using PyInt
prefix, now that Python 2 is history. It makes it clearer what is the new API.
Note that I'm not handling unsigned values. I think the extra bit of precision is not worth the complexity of a larger API.
And if we decide that they are, we can always add them later.
Linked PRs
- gh-102471, PEP 757: Add PyLong import and export API #121339
- gh-127937: convert decimal module to use import API for ints (PEP 757) #127925
- gh-102471: convert decimal module to use PyLong_Export API (PEP 757) #128267
- gh-102471: Credit Sergey B Kirpichev for PEP 757 #129338
- gh-102471: Change PyLongWriter_Discard(NULL) to do nothing #129339