Le mer. 24 juin 2020 à 16:20, Stefan Behnel firstname.lastname@example.org a écrit :
Note, I understand the difference between ABI and API. Keeping PyTuple_GET_ITEM() a macro or inline function can break the ABI at some point once PyTupleObject changes in an incompatible way in Py3.14, and it may do different things in PyPy entirely at some point. That's fine. We have a policy of allowing ABI breakage between CPython minor releases.
In the short term, I agree that it's ok that PyFloat_AS_DOUBLE() continues to read directly PyFloatObject.ob_fval. There is no *need* to enforce a function call at the ABI level for now.
My practical problem is how to prevent C extensions accessing the PyFloatObject.ob_fval member directly. In my tests, I renamed PyObject members. For example, rename PyObject.ob_type to PyObject._ob_type, and update Py_TYPE() and Py_SET_TYPE(). If a C function accesses directly PyObject.ob_type, a compilation error is issued.
One option would be to have a different stricter build mode where PyFloat_AS_DOUBLE() becomes a function call. Example:
#ifndef Py_LIMITED_API # ifdef OPAQUE_STRUCTURE # define PyFloat_AS_DOUBLE(op) PyFloat_AsDouble(op) # else # define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) # endif #endif
The function is not available in the Py_LIMITED_API, so other Python implementations don't have to implement it.
But an OPAQUE_STRUCTRE macro would declare the macro as a function call: alias to PyFloat_AsDouble().
Or maybe it's time to extend the limited C API: add PyFloat_AS_DOUBLE() macro as a function call. Extending the limited C API has multiple advantages:
* It eases the transition of C extensions to the limited C API * Py_LIMITED_API already exists, there is no need to add yet another build mode or any new macro * Most structures are *already* opaque in the limited C API.
The question becomes: how to promote the limited C API? Should it become the default, rather than an opt-in option?
That's what I mean by "public CPython 3.X C-API". Don't discourage its use, don't hide away details. Just make it clear what is CPython specific and what isn't, but without judging. It's a good thing for extensions to be fast on CPython.
I modified "make install" in Python 3.8 to install the internal C API to make it possible to use it outside CPython.