gh-104109: Expose Py_NewInterpreterFromConfig() in the Public C-API (gh-104110)

We also expose PyInterpreterConfig. This is part of the PEP 684 (per-interpreter GIL) implementation.  We will add docs as soon as we can.

FYI, I'm adding the new config field for per-interpreter GIL in gh-99114.
This commit is contained in:
Eric Snow 2023-05-02 21:40:00 -06:00 committed by GitHub
parent de64e75616
commit 292076a9aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 22 additions and 16 deletions

View File

@ -252,7 +252,7 @@ typedef struct {
int allow_threads; int allow_threads;
int allow_daemon_threads; int allow_daemon_threads;
int check_multi_interp_extensions; int check_multi_interp_extensions;
} _PyInterpreterConfig; } PyInterpreterConfig;
#define _PyInterpreterConfig_INIT \ #define _PyInterpreterConfig_INIT \
{ \ { \

View File

@ -62,9 +62,9 @@ PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn);
PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn);
PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
PyAPI_FUNC(PyStatus) _Py_NewInterpreterFromConfig( PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig(
PyThreadState **tstate_p, PyThreadState **tstate_p,
const _PyInterpreterConfig *config); const PyInterpreterConfig *config);
typedef void (*atexit_datacallbackfunc)(void *); typedef void (*atexit_datacallbackfunc)(void *);
PyAPI_FUNC(int) _Py_AtExit( PyAPI_FUNC(int) _Py_AtExit(

View File

@ -0,0 +1,5 @@
We've added ``Py_NewInterpreterFromConfig()`` and ``PyInterpreterConfig`` to
the public C-API (but not the stable ABI; not yet at least). The new
function may be used to create a new interpreter with various features
configured. The function was added to support PEP 684 (per-interpreter
GIL).

View File

@ -1538,7 +1538,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
PyThreadState_Swap(NULL); PyThreadState_Swap(NULL);
const _PyInterpreterConfig config = { const PyInterpreterConfig config = {
.use_main_obmalloc = use_main_obmalloc, .use_main_obmalloc = use_main_obmalloc,
.allow_fork = allow_fork, .allow_fork = allow_fork,
.allow_exec = allow_exec, .allow_exec = allow_exec,
@ -1546,7 +1546,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
.allow_daemon_threads = allow_daemon_threads, .allow_daemon_threads = allow_daemon_threads,
.check_multi_interp_extensions = check_multi_interp_extensions, .check_multi_interp_extensions = check_multi_interp_extensions,
}; };
PyStatus status = _Py_NewInterpreterFromConfig(&substate, &config); PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
if (PyStatus_Exception(status)) { if (PyStatus_Exception(status)) {
/* Since no new thread state was created, there is no exception to /* Since no new thread state was created, there is no exception to
propagate; raise a fresh one after swapping in the old thread propagate; raise a fresh one after swapping in the old thread

View File

@ -513,12 +513,12 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds)
// Create and initialize the new interpreter. // Create and initialize the new interpreter.
PyThreadState *save_tstate = _PyThreadState_GET(); PyThreadState *save_tstate = _PyThreadState_GET();
const _PyInterpreterConfig config = isolated const PyInterpreterConfig config = isolated
? (_PyInterpreterConfig)_PyInterpreterConfig_INIT ? (PyInterpreterConfig)_PyInterpreterConfig_INIT
: (_PyInterpreterConfig)_PyInterpreterConfig_LEGACY_INIT; : (PyInterpreterConfig)_PyInterpreterConfig_LEGACY_INIT;
// XXX Possible GILState issues? // XXX Possible GILState issues?
PyThreadState *tstate = NULL; PyThreadState *tstate = NULL;
PyStatus status = _Py_NewInterpreterFromConfig(&tstate, &config); PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
PyThreadState_Swap(save_tstate); PyThreadState_Swap(save_tstate);
if (PyStatus_Exception(status)) { if (PyStatus_Exception(status)) {
/* Since no new thread state was created, there is no exception to /* Since no new thread state was created, there is no exception to

View File

@ -546,7 +546,8 @@ pycore_init_runtime(_PyRuntimeState *runtime,
static PyStatus static PyStatus
init_interp_settings(PyInterpreterState *interp, const _PyInterpreterConfig *config) init_interp_settings(PyInterpreterState *interp,
const PyInterpreterConfig *config)
{ {
assert(interp->feature_flags == 0); assert(interp->feature_flags == 0);
@ -631,7 +632,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
return status; return status;
} }
const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; const PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
status = init_interp_settings(interp, &config); status = init_interp_settings(interp, &config);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
@ -1991,7 +1992,7 @@ Py_Finalize(void)
*/ */
static PyStatus static PyStatus
new_interpreter(PyThreadState **tstate_p, const _PyInterpreterConfig *config) new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
{ {
PyStatus status; PyStatus status;
@ -2079,8 +2080,8 @@ error:
} }
PyStatus PyStatus
_Py_NewInterpreterFromConfig(PyThreadState **tstate_p, Py_NewInterpreterFromConfig(PyThreadState **tstate_p,
const _PyInterpreterConfig *config) const PyInterpreterConfig *config)
{ {
return new_interpreter(tstate_p, config); return new_interpreter(tstate_p, config);
} }
@ -2089,8 +2090,8 @@ PyThreadState *
Py_NewInterpreter(void) Py_NewInterpreter(void)
{ {
PyThreadState *tstate = NULL; PyThreadState *tstate = NULL;
const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; const PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
PyStatus status = _Py_NewInterpreterFromConfig(&tstate, &config); PyStatus status = new_interpreter(&tstate, &config);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
Py_ExitStatusException(status); Py_ExitStatusException(status);
} }