mirror of https://github.com/python/cpython
gh-106320: Remove private _PyErr_ChainExceptions() (#108713)
Remove _PyErr_ChainExceptions(), _PyErr_ChainExceptions1() and _PyErr_SetFromPyStatus() functions from the public C API. * Move the private _PyErr_ChainExceptions() and _PyErr_ChainExceptions1() function to the internal C API (pycore_pyerrors.h). * Move the private _PyErr_SetFromPyStatus() to the internal C API (pycore_initconfig.h). * No longer export the _PyErr_ChainExceptions() function. * Move run_in_subinterp_with_config() from _testcapi to _testinternalcapi.
This commit is contained in:
parent
059bd4d299
commit
79823c103b
|
@ -25,7 +25,6 @@ PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode);
|
||||||
PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
|
PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
|
||||||
PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
|
PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
|
||||||
PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
|
PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
|
||||||
PyAPI_FUNC(PyObject *) _PyErr_SetFromPyStatus(PyStatus status);
|
|
||||||
|
|
||||||
/* --- PyWideStringList ------------------------------------------------ */
|
/* --- PyWideStringList ------------------------------------------------ */
|
||||||
|
|
||||||
|
|
|
@ -88,11 +88,6 @@ typedef PyOSErrorObject PyEnvironmentErrorObject;
|
||||||
typedef PyOSErrorObject PyWindowsErrorObject;
|
typedef PyOSErrorObject PyWindowsErrorObject;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Context manipulation (PEP 3134) */
|
|
||||||
|
|
||||||
Py_DEPRECATED(3.12) PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *);
|
|
||||||
|
|
||||||
/* In exceptions.c */
|
/* In exceptions.c */
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar(
|
PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar(
|
||||||
|
|
|
@ -44,6 +44,10 @@ struct pyruntimestate;
|
||||||
#define _PyStatus_UPDATE_FUNC(err) \
|
#define _PyStatus_UPDATE_FUNC(err) \
|
||||||
do { (err).func = _PyStatus_GET_FUNC(); } while (0)
|
do { (err).func = _PyStatus_GET_FUNC(); } while (0)
|
||||||
|
|
||||||
|
// Export for '_testinternalcapi' shared extension
|
||||||
|
PyAPI_FUNC(PyObject *) _PyErr_SetFromPyStatus(PyStatus status);
|
||||||
|
|
||||||
|
|
||||||
/* --- PyWideStringList ------------------------------------------------ */
|
/* --- PyWideStringList ------------------------------------------------ */
|
||||||
|
|
||||||
#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL}
|
#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL}
|
||||||
|
|
|
@ -163,6 +163,13 @@ PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b,
|
||||||
|
|
||||||
void _PyErr_FormatNote(const char *format, ...);
|
void _PyErr_FormatNote(const char *format, ...);
|
||||||
|
|
||||||
|
/* Context manipulation (PEP 3134) */
|
||||||
|
|
||||||
|
Py_DEPRECATED(3.12) extern void _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
|
||||||
|
|
||||||
|
// Export for '_zoneinfo' shared extension
|
||||||
|
PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1821,11 +1821,11 @@ def run_in_subinterp_with_config(code, *, own_gil=None, **config):
|
||||||
module is enabled.
|
module is enabled.
|
||||||
"""
|
"""
|
||||||
_check_tracemalloc()
|
_check_tracemalloc()
|
||||||
import _testcapi
|
import _testinternalcapi
|
||||||
if own_gil is not None:
|
if own_gil is not None:
|
||||||
assert 'gil' not in config, (own_gil, config)
|
assert 'gil' not in config, (own_gil, config)
|
||||||
config['gil'] = 2 if own_gil else 1
|
config['gil'] = 2 if own_gil else 1
|
||||||
return _testcapi.run_in_subinterp_with_config(code, **config)
|
return _testinternalcapi.run_in_subinterp_with_config(code, **config)
|
||||||
|
|
||||||
|
|
||||||
def _check_tracemalloc():
|
def _check_tracemalloc():
|
||||||
|
|
|
@ -1805,12 +1805,12 @@ class SubinterpImportTests(unittest.TestCase):
|
||||||
check_multi_interp_extensions=strict,
|
check_multi_interp_extensions=strict,
|
||||||
)
|
)
|
||||||
_, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f'''
|
_, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f'''
|
||||||
import _testcapi, sys
|
import _testinternalcapi, sys
|
||||||
assert (
|
assert (
|
||||||
{name!r} in sys.builtin_module_names or
|
{name!r} in sys.builtin_module_names or
|
||||||
{name!r} not in sys.modules
|
{name!r} not in sys.modules
|
||||||
), repr({name!r})
|
), repr({name!r})
|
||||||
ret = _testcapi.run_in_subinterp_with_config(
|
ret = _testinternalcapi.run_in_subinterp_with_config(
|
||||||
{self.import_script(name, "sys.stdout.fileno()")!r},
|
{self.import_script(name, "sys.stdout.fileno()")!r},
|
||||||
**{kwargs},
|
**{kwargs},
|
||||||
)
|
)
|
||||||
|
@ -1829,9 +1829,9 @@ class SubinterpImportTests(unittest.TestCase):
|
||||||
check_multi_interp_extensions=True,
|
check_multi_interp_extensions=True,
|
||||||
)
|
)
|
||||||
_, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f'''
|
_, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f'''
|
||||||
import _testcapi, sys
|
import _testinternalcapi, sys
|
||||||
assert {name!r} not in sys.modules, {name!r}
|
assert {name!r} not in sys.modules, {name!r}
|
||||||
ret = _testcapi.run_in_subinterp_with_config(
|
ret = _testinternalcapi.run_in_subinterp_with_config(
|
||||||
{self.import_script(name, "sys.stdout.fileno()")!r},
|
{self.import_script(name, "sys.stdout.fileno()")!r},
|
||||||
**{kwargs},
|
**{kwargs},
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_abstract.h" // _PyNumber_Index()
|
#include "pycore_abstract.h" // _PyNumber_Index()
|
||||||
#include "pycore_initconfig.h" // _PyStatus_OK()
|
#include "pycore_initconfig.h" // _PyStatus_OK()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
|
|
||||||
#include "_iomodule.h"
|
#include "_iomodule.h"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
|
#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
|
||||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||||
#include "pycore_long.h" // _PyLong_GetOne()
|
#include "pycore_long.h" // _PyLong_GetOne()
|
||||||
#include "pycore_object.h" // _PyType_HasFeature()
|
#include "pycore_object.h" // _PyType_HasFeature()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
|
|
||||||
#include <stddef.h> // offsetof()
|
#include <stddef.h> // offsetof()
|
||||||
#include "_iomodule.h"
|
#include "_iomodule.h"
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||||
#include "pycore_codecs.h" // _PyCodecInfo_GetIncrementalDecoder()
|
#include "pycore_codecs.h" // _PyCodecInfo_GetIncrementalDecoder()
|
||||||
|
#include "pycore_fileutils.h" // _Py_GetLocaleEncoding()
|
||||||
#include "pycore_interp.h" // PyInterpreterState.fs_codec
|
#include "pycore_interp.h" // PyInterpreterState.fs_codec
|
||||||
#include "pycore_long.h" // _PyLong_GetZero()
|
#include "pycore_long.h" // _PyLong_GetZero()
|
||||||
#include "pycore_fileutils.h" // _Py_GetLocaleEncoding()
|
|
||||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
|
|
||||||
#include "_iomodule.h"
|
#include "_iomodule.h"
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "prepare_protocol.h"
|
#include "prepare_protocol.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include "pycore_import.h" // _PyImport_GetModuleAttrString()
|
#include "pycore_import.h" // _PyImport_GetModuleAttrString()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
|
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
|
||||||
#include "pycore_weakref.h" // _PyWeakref_IS_DEAD()
|
#include "pycore_weakref.h" // _PyWeakref_IS_DEAD()
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_fileutils.h" // _PyIsSelectable_fd()
|
#include "pycore_fileutils.h" // _PyIsSelectable_fd()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
|
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
|
||||||
|
|
||||||
/* Include symbols from _socket module */
|
/* Include symbols from _socket module */
|
||||||
|
|
|
@ -1434,104 +1434,6 @@ run_in_subinterp(PyObject *self, PyObject *args)
|
||||||
return PyLong_FromLong(r);
|
return PyLong_FromLong(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To run some code in a sub-interpreter. */
|
|
||||||
static PyObject *
|
|
||||||
run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
|
|
||||||
{
|
|
||||||
const char *code;
|
|
||||||
int use_main_obmalloc = -1;
|
|
||||||
int allow_fork = -1;
|
|
||||||
int allow_exec = -1;
|
|
||||||
int allow_threads = -1;
|
|
||||||
int allow_daemon_threads = -1;
|
|
||||||
int check_multi_interp_extensions = -1;
|
|
||||||
int gil = -1;
|
|
||||||
int r;
|
|
||||||
PyThreadState *substate, *mainstate;
|
|
||||||
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
|
|
||||||
PyCompilerFlags cflags = {0};
|
|
||||||
|
|
||||||
static char *kwlist[] = {"code",
|
|
||||||
"use_main_obmalloc",
|
|
||||||
"allow_fork",
|
|
||||||
"allow_exec",
|
|
||||||
"allow_threads",
|
|
||||||
"allow_daemon_threads",
|
|
||||||
"check_multi_interp_extensions",
|
|
||||||
"gil",
|
|
||||||
NULL};
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
|
||||||
"s$ppppppi:run_in_subinterp_with_config", kwlist,
|
|
||||||
&code, &use_main_obmalloc,
|
|
||||||
&allow_fork, &allow_exec,
|
|
||||||
&allow_threads, &allow_daemon_threads,
|
|
||||||
&check_multi_interp_extensions,
|
|
||||||
&gil)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (use_main_obmalloc < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing use_main_obmalloc");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (allow_fork < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing allow_fork");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (allow_exec < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing allow_exec");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (allow_threads < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing allow_threads");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (gil < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing gil");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (allow_daemon_threads < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing allow_daemon_threads");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (check_multi_interp_extensions < 0) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "missing check_multi_interp_extensions");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mainstate = PyThreadState_Get();
|
|
||||||
|
|
||||||
PyThreadState_Swap(NULL);
|
|
||||||
|
|
||||||
const PyInterpreterConfig config = {
|
|
||||||
.use_main_obmalloc = use_main_obmalloc,
|
|
||||||
.allow_fork = allow_fork,
|
|
||||||
.allow_exec = allow_exec,
|
|
||||||
.allow_threads = allow_threads,
|
|
||||||
.allow_daemon_threads = allow_daemon_threads,
|
|
||||||
.check_multi_interp_extensions = check_multi_interp_extensions,
|
|
||||||
.gil = gil,
|
|
||||||
};
|
|
||||||
PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
|
|
||||||
if (PyStatus_Exception(status)) {
|
|
||||||
/* Since no new thread state was created, there is no exception to
|
|
||||||
propagate; raise a fresh one after swapping in the old thread
|
|
||||||
state. */
|
|
||||||
PyThreadState_Swap(mainstate);
|
|
||||||
_PyErr_SetFromPyStatus(status);
|
|
||||||
PyObject *exc = PyErr_GetRaisedException();
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed");
|
|
||||||
_PyErr_ChainExceptions1(exc);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
assert(substate != NULL);
|
|
||||||
r = PyRun_SimpleStringFlags(code, &cflags);
|
|
||||||
Py_EndInterpreter(substate);
|
|
||||||
|
|
||||||
PyThreadState_Swap(mainstate);
|
|
||||||
|
|
||||||
return PyLong_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_xid_capsule_destructor(PyObject *capsule)
|
_xid_capsule_destructor(PyObject *capsule)
|
||||||
{
|
{
|
||||||
|
@ -3376,9 +3278,6 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"crash_no_current_thread", crash_no_current_thread, METH_NOARGS},
|
{"crash_no_current_thread", crash_no_current_thread, METH_NOARGS},
|
||||||
{"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS},
|
{"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS},
|
||||||
{"run_in_subinterp", run_in_subinterp, METH_VARARGS},
|
{"run_in_subinterp", run_in_subinterp, METH_VARARGS},
|
||||||
{"run_in_subinterp_with_config",
|
|
||||||
_PyCFunction_CAST(run_in_subinterp_with_config),
|
|
||||||
METH_VARARGS | METH_KEYWORDS},
|
|
||||||
{"get_crossinterp_data", get_crossinterp_data, METH_VARARGS},
|
{"get_crossinterp_data", get_crossinterp_data, METH_VARARGS},
|
||||||
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
|
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
|
||||||
{"create_cfunction", create_cfunction, METH_NOARGS},
|
{"create_cfunction", create_cfunction, METH_NOARGS},
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
|
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
|
||||||
#include "pycore_object.h" // _PyObject_IsFreed()
|
#include "pycore_object.h" // _PyObject_IsFreed()
|
||||||
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
|
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost()
|
#include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
|
||||||
|
@ -1593,6 +1594,105 @@ dict_getitem_knownhash(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* To run some code in a sub-interpreter. */
|
||||||
|
static PyObject *
|
||||||
|
run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
const char *code;
|
||||||
|
int use_main_obmalloc = -1;
|
||||||
|
int allow_fork = -1;
|
||||||
|
int allow_exec = -1;
|
||||||
|
int allow_threads = -1;
|
||||||
|
int allow_daemon_threads = -1;
|
||||||
|
int check_multi_interp_extensions = -1;
|
||||||
|
int gil = -1;
|
||||||
|
int r;
|
||||||
|
PyThreadState *substate, *mainstate;
|
||||||
|
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
|
||||||
|
PyCompilerFlags cflags = {0};
|
||||||
|
|
||||||
|
static char *kwlist[] = {"code",
|
||||||
|
"use_main_obmalloc",
|
||||||
|
"allow_fork",
|
||||||
|
"allow_exec",
|
||||||
|
"allow_threads",
|
||||||
|
"allow_daemon_threads",
|
||||||
|
"check_multi_interp_extensions",
|
||||||
|
"gil",
|
||||||
|
NULL};
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||||
|
"s$ppppppi:run_in_subinterp_with_config", kwlist,
|
||||||
|
&code, &use_main_obmalloc,
|
||||||
|
&allow_fork, &allow_exec,
|
||||||
|
&allow_threads, &allow_daemon_threads,
|
||||||
|
&check_multi_interp_extensions,
|
||||||
|
&gil)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (use_main_obmalloc < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing use_main_obmalloc");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (allow_fork < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing allow_fork");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (allow_exec < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing allow_exec");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (allow_threads < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing allow_threads");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (gil < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing gil");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (allow_daemon_threads < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing allow_daemon_threads");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (check_multi_interp_extensions < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "missing check_multi_interp_extensions");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainstate = PyThreadState_Get();
|
||||||
|
|
||||||
|
PyThreadState_Swap(NULL);
|
||||||
|
|
||||||
|
const PyInterpreterConfig config = {
|
||||||
|
.use_main_obmalloc = use_main_obmalloc,
|
||||||
|
.allow_fork = allow_fork,
|
||||||
|
.allow_exec = allow_exec,
|
||||||
|
.allow_threads = allow_threads,
|
||||||
|
.allow_daemon_threads = allow_daemon_threads,
|
||||||
|
.check_multi_interp_extensions = check_multi_interp_extensions,
|
||||||
|
.gil = gil,
|
||||||
|
};
|
||||||
|
PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
|
||||||
|
if (PyStatus_Exception(status)) {
|
||||||
|
/* Since no new thread state was created, there is no exception to
|
||||||
|
propagate; raise a fresh one after swapping in the old thread
|
||||||
|
state. */
|
||||||
|
PyThreadState_Swap(mainstate);
|
||||||
|
_PyErr_SetFromPyStatus(status);
|
||||||
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed");
|
||||||
|
_PyErr_ChainExceptions1(exc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
assert(substate != NULL);
|
||||||
|
r = PyRun_SimpleStringFlags(code, &cflags);
|
||||||
|
Py_EndInterpreter(substate);
|
||||||
|
|
||||||
|
PyThreadState_Swap(mainstate);
|
||||||
|
|
||||||
|
return PyLong_FromLong(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef module_functions[] = {
|
static PyMethodDef module_functions[] = {
|
||||||
{"get_configs", get_configs, METH_NOARGS},
|
{"get_configs", get_configs, METH_NOARGS},
|
||||||
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
||||||
|
@ -1659,6 +1759,9 @@ static PyMethodDef module_functions[] = {
|
||||||
{"get_object_dict_values", get_object_dict_values, METH_O},
|
{"get_object_dict_values", get_object_dict_values, METH_O},
|
||||||
{"hamt", new_hamt, METH_NOARGS},
|
{"hamt", new_hamt, METH_NOARGS},
|
||||||
{"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},
|
{"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},
|
||||||
|
{"run_in_subinterp_with_config",
|
||||||
|
_PyCFunction_CAST(run_in_subinterp_with_config),
|
||||||
|
METH_VARARGS | METH_KEYWORDS},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
/* interpreters module */
|
/* interpreters module */
|
||||||
/* low-level access to interpreter primitives */
|
/* low-level access to interpreter primitives */
|
||||||
|
|
||||||
|
#ifndef Py_BUILD_CORE_BUILTIN
|
||||||
|
# define Py_BUILD_CORE_MODULE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "pycore_initconfig.h" // _PyErr_SetFromPyStatus()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "interpreteridobject.h"
|
#include "interpreteridobject.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_long.h" // _PyLong_GetOne()
|
#include "pycore_long.h" // _PyLong_GetOne()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
|
@ -465,10 +465,11 @@ later:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
|
|
||||||
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
||||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
|
||||||
#include "pycore_dict.h" // _Py_dict_lookup()
|
#include "pycore_dict.h" // _Py_dict_lookup()
|
||||||
|
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include <stddef.h> // offsetof()
|
#include <stddef.h> // offsetof()
|
||||||
|
|
||||||
#include "clinic/odictobject.c.h"
|
#include "clinic/odictobject.c.h"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_modsupport.h" // _PyArg_NoKwnames()
|
#include "pycore_modsupport.h" // _PyArg_NoKwnames()
|
||||||
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR()
|
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR()
|
||||||
|
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
|
||||||
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
|
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue