On Sun, Oct 28, 2018, at 09:20, Victor Stinner wrote:
Python C API has no strict separation between the 3 levels of API:
- core: Py_BUILD_CORE define
- stable: Py_LIMITED_API define (it has a value)
- regular: no define
IMHO the current design of header files is done backward: by default, everything is public. To exclude an API from core or stable, "#ifdef Py_BUILD_CORE" and "#ifndef Py_LIMITED_API" are used. This design caused issues in the past: functions, variables or something else exposed whereas they were supposed to be "private".
I propose a practical solution for that: Include/*.h files would only be be public API. The "core" API would live in a new subdirectory: Include/pycore/*.h. Moreover, files of this subdirectory would have the prefix "pycore_". For example, Include/objimpl.h would have a twin: Include/pycore/pycore_objimpl.h which extend the public API with "core" APIs.
I also propose to automatically load the twin: Include/objimpl.h would load Include/pycore/pycore_objimpl.h if Py_BUILD_CORE is defined:
#ifdef Py_BUILD_CORE # include "pycore/pycore_objimpl.h" #endif
I don't think more or less API should be magically included based on whether Py_BUILD_CORE is defined or not. If we want to have private headers, we should include them where needed and not install them. Really, Py_BUILD_CORE should go away. We should be moving away from monolithic includes like Python.h to having each C file include exactly what it uses, private or not.