FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-117953: Add Internal struct _Py_ext_module_loader_info by ericsnowcurrently · Pull Request #118194 · python/cpython · GitHub

/ cpython Public
30 changes: 29 additions & 1 deletion Include/internal/pycore_importdl.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,38 @@ extern "C" {

extern const char *_PyImport_DynLoadFiletab[];

extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *);

typedef PyObject *(*PyModInitFunction)(void);

struct _Py_ext_module_loader_info {
PyObject *filename;
#ifndef MS_WINDOWS
PyObject *filename_encoded;
#endif
PyObject *name;
PyObject *name_encoded;
/* path is always a borrowed ref of name or filename,
* depending on if it's builtin or not. */
PyObject *path;
const char *hook_prefix;
const char *newcontext;
};
extern void _Py_ext_module_loader_info_clear(
struct _Py_ext_module_loader_info *info);
extern int _Py_ext_module_loader_info_init(
struct _Py_ext_module_loader_info *info,
PyObject *name,
PyObject *filename);
extern int _Py_ext_module_loader_info_init_from_spec(
struct _Py_ext_module_loader_info *info,
PyObject *spec);

extern PyObject *_PyImport_LoadDynamicModuleWithSpec(
struct _Py_ext_module_loader_info *info,
PyObject *spec,
FILE *fp);


/* Max length of module suffix searched for -- accommodates "module.slb" */
#define MAXSUFFIXSIZE 12

Expand Down
94 changes: 54 additions & 40 deletions Python/import.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1328,19 +1328,19 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name,


static PyObject *
import_find_extension(PyThreadState *tstate, PyObject *name,
PyObject *path)
import_find_extension(PyThreadState *tstate,
struct _Py_ext_module_loader_info *info)
{
/* Only single-phase init modules will be in the cache. */
PyModuleDef *def = _extensions_cache_get(path, name);
PyModuleDef *def = _extensions_cache_get(info->path, info->name);
if (def == NULL) {
return NULL;
}

/* It may have been successfully imported previously
in an interpreter that allows legacy modules
but is not allowed in the current interpreter. */
const char *name_buf = PyUnicode_AsUTF8(name);
const char *name_buf = PyUnicode_AsUTF8(info->name);
assert(name_buf != NULL);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
return NULL;
Expand All @@ -1355,12 +1355,13 @@ import_find_extension(PyThreadState *tstate, PyObject *name,
if (m_copy == NULL) {
/* It might be a core module (e.g. sys & builtins),
for which we don't set m_copy. */
m_copy = get_core_module_dict(tstate->interp, name, path);
m_copy = get_core_module_dict(
tstate->interp, info->name, info->path);
if (m_copy == NULL) {
return NULL;
}
}
mod = import_add_module(tstate, name);
mod = import_add_module(tstate, info->name);
if (mod == NULL) {
return NULL;
}
Expand All @@ -1378,23 +1379,24 @@ import_find_extension(PyThreadState *tstate, PyObject *name,
if (def->m_base.m_init == NULL)
return NULL;
mod = def->m_base.m_init();
if (mod == NULL)
if (mod == NULL) {
return NULL;
if (PyObject_SetItem(modules, name, mod) == -1) {
}
if (PyObject_SetItem(modules, info->name, mod) == -1) {
Py_DECREF(mod);
return NULL;
}
}
if (_modules_by_index_set(tstate->interp, def, mod) < 0) {
PyMapping_DelItem(modules, name);
PyMapping_DelItem(modules, info->name);
Py_DECREF(mod);
return NULL;
}

int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
if (verbose) {
PySys_FormatStderr("import %U # previously loaded (%R)\n",
name, path);
info->name, info->path);
}
return mod;
}
Expand Down Expand Up @@ -1505,44 +1507,56 @@ static PyObject*
create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
{
PyModuleDef *def = NULL;
PyObject *mod = import_find_extension(tstate, name, name);

struct _Py_ext_module_loader_info info;
if (_Py_ext_module_loader_info_init(&info, name, NULL) < 0) {
return NULL;
}

PyObject *mod = import_find_extension(tstate, &info);
if (mod || _PyErr_Occurred(tstate)) {
return mod;
goto finally;
}

struct _inittab *found = NULL;
for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
if (_PyUnicode_EqualToASCIIString(name, p->name)) {
if (_PyUnicode_EqualToASCIIString(info.name, p->name)) {
found = p;
}
}
if (found == NULL) {
// not found
Py_RETURN_NONE;
mod = Py_NewRef(Py_None);
goto finally;
}

PyModInitFunction p0 = (PyModInitFunction)found->initfunc;
if (p0 == NULL) {
/* Cannot re-init internal module ("sys" or "builtins") */
assert(is_core_module(tstate->interp, name, name));
return import_add_module(tstate, name);
assert(is_core_module(tstate->interp, info.name, info.path));
mod = import_add_module(tstate, info.name);
goto finally;
}

mod = p0();
if (mod == NULL) {
return NULL;
goto finally;
}

if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) {
def = (PyModuleDef*)mod;
assert(!is_singlephase(def));
return PyModule_FromDefAndSpec(def, spec);
mod = PyModule_FromDefAndSpec(def, spec);
if (mod == NULL) {
goto finally;
}
}
else {
assert(PyModule_Check(mod));
def = PyModule_GetDef(mod);
if (def == NULL) {
return NULL;
Py_CLEAR(mod);
goto finally;
}
assert(is_singlephase(def));

Expand All @@ -1553,22 +1567,29 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
// 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, name, name))
&& !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, name, name, def, &singlephase) < 0)
tstate, info.name, info.path, def, &singlephase) < 0)
{
return NULL;
Py_CLEAR(mod);
goto finally;
}
PyObject *modules = get_modules_dict(tstate, true);
if (finish_singlephase_extension(tstate, mod, def, name, modules) < 0) {
return NULL;
if (finish_singlephase_extension(
tstate, mod, def, info.name, modules) < 0)
{
Py_CLEAR(mod);
goto finally;
}
return mod;
}

finally:
_Py_ext_module_loader_info_clear(&info);
return mod;
}


Expand Down Expand Up @@ -3878,28 +3899,22 @@ static PyObject *
_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
{
PyObject *mod, *name, *filename;
PyObject *mod = NULL;
FILE *fp;

name = PyObject_GetAttrString(spec, "name");
if (name == NULL) {
return NULL;
}

filename = PyObject_GetAttrString(spec, "origin");
if (filename == NULL) {
Py_DECREF(name);
struct _Py_ext_module_loader_info info;
if (_Py_ext_module_loader_info_init_from_spec(&info, spec) < 0) {
return NULL;
}

PyThreadState *tstate = _PyThreadState_GET();
mod = import_find_extension(tstate, name, filename);
mod = import_find_extension(tstate, &info);
if (mod != NULL || _PyErr_Occurred(tstate)) {
assert(mod == NULL || !_PyErr_Occurred(tstate));
goto finally;
}

if (PySys_Audit("import", "OOOOO", name, filename,
if (PySys_Audit("import", "OOOOO", info.name, info.filename,
Py_None, Py_None, Py_None) < 0)
{
goto finally;
Expand All @@ -3911,7 +3926,7 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
* _PyImport_GetModInitFunc(), but it isn't clear if the intervening
* code relies on fp still being open. */
if (file != NULL) {
fp = _Py_fopen_obj(filename, "r");
fp = _Py_fopen_obj(info.filename, "r");
if (fp == NULL) {
goto finally;
}
Expand All @@ -3920,16 +3935,15 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
fp = NULL;
}

mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp);
mod = _PyImport_LoadDynamicModuleWithSpec(&info, spec, fp);

// XXX Shouldn't this happen in the error cases too.
if (fp) {
fclose(fp);
}

finally:
Py_DECREF(name);
Py_DECREF(filename);
_Py_ext_module_loader_info_clear(&info);
return mod;
}

Expand Down
Loading

Back | FazBrowse Home | New Git URL