Skip to content

Commit

Permalink
Factor out import_run_extension().
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsnowcurrently committed Apr 24, 2024
1 parent f651b52 commit 32a319a
Showing 1 changed file with 85 additions and 102 deletions.
187 changes: 85 additions & 102 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,84 @@ import_find_extension(PyThreadState *tstate,
return mod;
}

static PyObject *
import_run_extension(PyThreadState *tstate, PyModInitFunction p0,
struct _Py_ext_module_loader_info *info,
PyObject *spec, PyObject *modules)
{
PyObject *mod = NULL;
PyModuleDef *def = NULL;

struct _Py_ext_module_loader_result res;
if (_PyImport_RunModInitFunc(p0, info, &res) < 0) {
/* We discard res.def. */
assert(res.module == NULL);
assert(PyErr_Occurred());
goto finally;
}
assert(!PyErr_Occurred());

mod = res.module;
res.module = NULL;
def = res.def;
assert(def != NULL);

if (mod == NULL) {
//assert(!is_singlephase(def));
assert(mod == NULL);
mod = PyModule_FromDefAndSpec(def, spec);
if (mod == NULL) {
goto finally;
}
}
else {
assert(is_singlephase(def));
assert(PyModule_Check(mod));
mod = Py_NewRef(mod);

const char *name_buf = PyBytes_AS_STRING(info->name_encoded);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
Py_CLEAR(mod);
goto finally;
}

if (info->filename != NULL) {
/* Remember the filename as the __file__ attribute */
if (PyModule_AddObjectRef(mod, "__file__", info->filename) < 0) {
PyErr_Clear(); /* Not important enough to report */
}
}

struct singlephase_global_update singlephase = {0};
// gh-88216: Extensions and def->m_base.m_copy can be updated
// when the extension module doesn't support sub-interpreters.
if (def->m_size == -1
&& !is_core_module(tstate->interp, info->name, info->path))
{
singlephase.m_dict = PyModule_GetDict(mod);
assert(singlephase.m_dict != NULL);
}
if (update_global_state_for_extension(
tstate, info->path, info->name, def, &singlephase) < 0)
{
Py_CLEAR(mod);
goto finally;
}

PyObject *modules = get_modules_dict(tstate, true);
if (finish_singlephase_extension(
tstate, mod, def, info->name, modules) < 0)
{
Py_CLEAR(mod);
goto finally;
}
}

finally:
return mod;
}


static int
clear_singlephase_extension(PyInterpreterState *interp,
PyObject *name, PyObject *path)
Expand Down Expand Up @@ -1491,8 +1569,6 @@ is_builtin(PyObject *name)
static PyObject*
create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
{
PyModuleDef *def = NULL;

struct _Py_ext_module_loader_info info;
if (_Py_ext_module_loader_info_init_for_builtin(&info, name) < 0) {
return NULL;
Expand Down Expand Up @@ -1528,49 +1604,9 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
goto finally;
}

struct _Py_ext_module_loader_result res;
if (_PyImport_RunModInitFunc(p0, &info, &res) < 0) {
goto finally;
}

mod = res.module;
res.module = NULL;
def = res.def;
assert(def != NULL);

if (mod == NULL) {
assert(!is_singlephase(def));
mod = PyModule_FromDefAndSpec(def, spec);
if (mod == NULL) {
goto finally;
}
}
else {
assert(is_singlephase(def));

struct singlephase_global_update singlephase = {0};
// gh-88216: Extensions and def->m_base.m_copy can be updated
// when the extension module doesn't support sub-interpreters.
if (def->m_size == -1
&& !is_core_module(tstate->interp, info.name, info.path))
{
singlephase.m_dict = PyModule_GetDict(mod);
assert(singlephase.m_dict != NULL);
}
if (update_global_state_for_extension(
tstate, info.name, info.path, def, &singlephase) < 0)
{
Py_CLEAR(mod);
goto finally;
}
PyObject *modules = get_modules_dict(tstate, true);
if (finish_singlephase_extension(
tstate, mod, def, info.name, modules) < 0)
{
Py_CLEAR(mod);
goto finally;
}
}
/* Now load it. */
mod = import_run_extension(
tstate, p0, &info, spec, get_modules_dict(tstate, true));

finally:
_Py_ext_module_loader_info_clear(&info);
Expand Down Expand Up @@ -3885,7 +3921,6 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
{
PyObject *mod = NULL;
PyModuleDef *def = NULL;
PyThreadState *tstate = _PyThreadState_GET();

struct _Py_ext_module_loader_info info;
Expand Down Expand Up @@ -3929,65 +3964,13 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
goto finally;
}

struct _Py_ext_module_loader_result res;
if (_PyImport_RunModInitFunc(p0, &info, &res) < 0) {
assert(PyErr_Occurred());
goto finally;
}

mod = res.module;
res.module = NULL;
def = res.def;
assert(def != NULL);

mod = import_run_extension(
tstate, p0, &info, spec, get_modules_dict(tstate, true));
if (mod == NULL) {
//assert(!is_singlephase(def));
mod = PyModule_FromDefAndSpec(def, spec);
if (mod == NULL) {
goto finally;
}
}
else {
assert(is_singlephase(def));
assert(!is_core_module(tstate->interp, info.name, info.filename));
assert(!is_core_module(tstate->interp, info.name, info.name));
mod = Py_NewRef(mod);

const char *name_buf = PyBytes_AS_STRING(info.name_encoded);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
Py_CLEAR(mod);
goto finally;
}

/* Remember the filename as the __file__ attribute */
if (PyModule_AddObjectRef(mod, "__file__", info.filename) < 0) {
PyErr_Clear(); /* Not important enough to report */
}

struct singlephase_global_update singlephase = {0};
// gh-88216: Extensions and def->m_base.m_copy can be updated
// when the extension module doesn't support sub-interpreters.
if (def->m_size == -1) {
singlephase.m_dict = PyModule_GetDict(mod);
assert(singlephase.m_dict != NULL);
}
if (update_global_state_for_extension(
tstate, info.filename, info.name, def, &singlephase) < 0)
{
Py_CLEAR(mod);
goto finally;
}

PyObject *modules = get_modules_dict(tstate, true);
if (finish_singlephase_extension(
tstate, mod, def, info.name, modules) < 0)
{
Py_CLEAR(mod);
goto finally;
}
goto finally;
}

// XXX Shouldn't this happen in the error cases too.
// XXX Shouldn't this happen in the error cases too (i.e. in "finally")?
if (fp) {
fclose(fp);
}
Expand Down

0 comments on commit 32a319a

Please sign in to comment.