Suppose I am writing an extension that needs to print the floating-point number cache pool (freelist
).
To do this, I need to access the interpreter state reference, which requires the definition of struct _is
, namely PyInterpreterState
. However, this belongs to the private API and requires pycore_interop.h
.
Generally speaking, when writing a C program that embeds Python, or, a Python C extension, you don’t need to use these private APIs, but in my case, is this usage correct? To access struct _is
, I had to #define Py_BUILD_CORE
.
#define Py_BUILD_CORE
#include "Python.h"
#include "pytypedefs.h"
#include "internal/pycore_interp.h"
#include <stdio.h>
void print_list(PyFloatObject *list, int size) {
if (list == NULL) {
printf("Free List is NULL\n");
} else {
printf("%d elements in Free List\n", size);
puts("The 1st one is:");
PyObject_Print((PyObject *)&list[0], stdout, Py_PRINT_RAW);
}
while (list->ob_base.ob_type) {
list = list->ob_base.ob_type;
PyObject_Print((PyObject *)list, stdout, Py_PRINT_RAW);
puts("");
printf("(%f)\n", list->ob_fval);
}
}
int main() {
Py_Initialize();
// Creating some random dummy floats
//
PyObject *fobj_1 = PyFloat_FromDouble(233.233);
PyObject *fobj_2 = PyFloat_FromDouble(233.234);
PyObject *fobj_3 = PyNumber_Add(fobj_1, fobj_2);
Py_DECREF(fobj_1);
Py_DECREF(fobj_2);
Py_DECREF(fobj_3);
PyThreadState *ts = PyThreadState_Get();
PyInterpreterState *is = ts->interp;
printf("Free List address: %p\n", is->float_state.free_list);
print_list(is->float_state.free_list, is->float_state.numfree);
Py_Finalize();
return 0;
}
My question is, is using private APIs not recommended under any circumstances? How should they be used correctly, and what are the best practices?