There are two ways to export/import data from Python objects:
- Expose the internal structures and expect C extensions to correctly extract the data, not to hold references to it, or otherwise mess things up.
- Expect C extensions to provide buffers that CPython then exports the data to, or imports the data from.
PEP 757 chooses approach 1. Why? The PEP doesn’t say.
Using approach 2, the API would be smaller and the risk of messing up internal data structures lower. It should be easier for extension authors as well.
Here’s a possible API:
struct PyLongLayout {
uint8_t bits_per_digit;
uint8_t digit_size;
bool big_endian;
};
size_t PyLong_GetDigitsNeeded(PyLongObject *obj, PyLongLayout layout);
int PyLong_Export(PyLongObject *obj, PyLongLayout layout, char *buffer);
PyLongObject *PyLong_Import(PyLongLayout layout, char *buffer);
Some comments
- Don’t pass
PyLongLayout
by reference; pass it by value. - I don’t think
endian
is unnecessary. Digits are not composed of bytes, but of larger machine integers, so they don’t really have endianness.
The “Optimize small integers” section.
- Differentiate between exporting and importing small ints. Presumably there is no need for a new API for importing small ints.
- For exporting, a list of functions is recommended. Just recommend
PyUnstable_Long_IsCompact()
andPyUnstable_Long_CompactValue()
. Everything else will be slower. Maybe we should add them to the stable API?
The “Benchmarks” section
What is the example code being compared to?
Both versions need to be listed. Maybe not in the PEP, but in a supporting document.