Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Factor out _PyImport_RunDynamicModule().
  • Loading branch information
ericsnowcurrently committed Apr 2, 2024
commit 723c6fc97db6ae31235533ab458a2d9d151ee6c4
25 changes: 23 additions & 2 deletions Include/internal/pycore_importdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,31 @@ 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 *path;
PyObject *name;
PyObject *name_encoded;
const char *hook_prefix;
};
extern void _Py_ext_module_loader_info_clear(
struct _Py_ext_module_loader_info *info);
extern int _Py_ext_module_loader_info_from_spec(
PyObject *spec,
struct _Py_ext_module_loader_info *info);

struct _Py_ext_module_loader_result {
PyModuleDef *def;
PyObject *module;
};
extern int _PyImport_RunDynamicModule(
struct _Py_ext_module_loader_info *info,
FILE *fp,
struct _Py_ext_module_loader_result *res);

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

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

Expand Down
222 changes: 148 additions & 74 deletions Python/importdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,58 +93,91 @@ get_encoded_name(PyObject *name, const char **hook_prefix) {
return NULL;
}

PyObject *
_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
void
_Py_ext_module_loader_info_clear(struct _Py_ext_module_loader_info *info)
{
#ifndef MS_WINDOWS
PyObject *pathbytes = NULL;
#endif
PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL;
const char *name_buf, *hook_prefix;
const char *oldcontext, *newcontext;
dl_funcptr exportfunc;
PyModuleDef *def;
PyModInitFunction p0;
Py_CLEAR(info->path);
Py_CLEAR(info->name);
Py_CLEAR(info->name_encoded);
}

int
_Py_ext_module_loader_info_from_spec(PyObject *spec,
struct _Py_ext_module_loader_info *info)
{
PyObject *name_unicode = NULL, *name = NULL, *path = NULL;
const char *hook_prefix;

name_unicode = PyObject_GetAttrString(spec, "name");
if (name_unicode == NULL) {
return NULL;
return -1;
}
if (!PyUnicode_Check(name_unicode)) {
PyErr_SetString(PyExc_TypeError,
"spec.name must be a string");
goto error;
}
newcontext = PyUnicode_AsUTF8(name_unicode);
if (newcontext == NULL) {
goto error;
Py_DECREF(name_unicode);
return -1;
}

name = get_encoded_name(name_unicode, &hook_prefix);
if (name == NULL) {
goto error;
Py_DECREF(name_unicode);
return -1;
}
name_buf = PyBytes_AS_STRING(name);

path = PyObject_GetAttrString(spec, "origin");
if (path == NULL)
goto error;
if (path == NULL) {
Py_DECREF(name_unicode);
Py_DECREF(name);
return -1;
}

*info = (struct _Py_ext_module_loader_info){
.path=path,
.name=name_unicode,
.name_encoded=name,
.hook_prefix=hook_prefix,
};
return 0;
}

int
_PyImport_RunDynamicModule(struct _Py_ext_module_loader_info *info,
FILE *fp,
struct _Py_ext_module_loader_result *res)
{
#ifndef MS_WINDOWS
PyObject *pathbytes = NULL;
const char *path_buf;
#endif
PyObject *m = NULL;
const char *name_buf = PyBytes_AS_STRING(info->name_encoded);
const char *oldcontext, *newcontext;
dl_funcptr exportfunc;
PyModInitFunction p0;
PyModuleDef *def;

newcontext = PyUnicode_AsUTF8(info->name);
if (newcontext == NULL) {
return -1;
}

if (PySys_Audit("import", "OOOOO", name_unicode, path,
if (PySys_Audit("import", "OOOOO", info->name, info->path,
Py_None, Py_None, Py_None) < 0) {
goto error;
return -1;
}

#ifdef MS_WINDOWS
exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf,
path, fp);
exportfunc = _PyImport_FindSharedFuncptrWindows(
info->hook_prefix, name_buf, info->path, fp);
#else
pathbytes = PyUnicode_EncodeFSDefault(path);
if (pathbytes == NULL)
goto error;
exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf,
PyBytes_AS_STRING(pathbytes),
fp);
pathbytes = PyUnicode_EncodeFSDefault(info->path);
if (pathbytes == NULL) {
return -1;
}
path_buf = PyBytes_AS_STRING(pathbytes);
exportfunc = _PyImport_FindSharedFuncptr(
info->hook_prefix, name_buf, path_buf, fp);
Py_DECREF(pathbytes);
#endif

Expand All @@ -154,13 +187,13 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
msg = PyUnicode_FromFormat(
"dynamic module does not define "
"module export function (%s_%s)",
hook_prefix, name_buf);
if (msg == NULL)
goto error;
PyErr_SetImportError(msg, name_unicode, path);
Py_DECREF(msg);
info->hook_prefix, name_buf);
if (msg != NULL) {
PyErr_SetImportError(msg, info->name, info->path);
Py_DECREF(msg);
}
}
goto error;
return -1;
}

p0 = (PyModInitFunction)exportfunc;
Expand All @@ -177,14 +210,14 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
"initialization of %s failed without raising an exception",
name_buf);
}
goto error;
return -1;
} else if (PyErr_Occurred()) {
_PyErr_FormatFromCause(
PyExc_SystemError,
"initialization of %s raised unreported exception",
name_buf);
m = NULL;
goto error;
return -1;
}
if (Py_IS_TYPE(m, NULL)) {
/* This can happen when a PyModuleDef is returned without calling
Expand All @@ -194,60 +227,101 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
"init function of %s returned uninitialized object",
name_buf);
m = NULL; /* prevent segfault in DECREF */
goto error;
return -1;
}

if (PyObject_TypeCheck(m, &PyModuleDef_Type)) {
Py_DECREF(name_unicode);
Py_DECREF(name);
Py_DECREF(path);
return PyModule_FromDefAndSpec((PyModuleDef*)m, spec);
/* multi-phase init */

def = (PyModuleDef *)m;
m = NULL;

/* Run PyModule_FromDefAndSpec() to finish loading the module. */
}
else {
/* single-phase init (legacy) */

/* Fall back to single-phase init mechanism */
/* Remember pointer to module init function. */
def = PyModule_GetDef(m);
if (def == NULL) {
PyErr_Format(PyExc_SystemError,
"initialization of %s did not return an extension "
"module", name_buf);
Py_DECREF(m);
return -1;
}
def->m_base.m_init = p0;

if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
goto error;
if (info->hook_prefix == nonascii_prefix) {
/* don't allow legacy init for non-ASCII module names */
PyErr_Format(
PyExc_SystemError,
"initialization of %s did not return PyModuleDef",
name_buf);
Py_DECREF(m);
return -1;
}

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

/* Run _PyImport_FixupExtensionObject() to finish loading the module. */
}

if (hook_prefix == nonascii_prefix) {
/* don't allow legacy init for non-ASCII module names */
PyErr_Format(
PyExc_SystemError,
"initialization of %s did not return PyModuleDef",
name_buf);
goto error;
*res = (struct _Py_ext_module_loader_result){
.def=def,
.module=m,
};
return 0;
}

PyObject *
_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
{
PyObject *m = NULL;
const char *name_buf;
//dl_funcptr exportfunc;
//PyModInitFunction p0;
PyModuleDef *def;
struct _Py_ext_module_loader_info info;
struct _Py_ext_module_loader_result res;

if (_Py_ext_module_loader_info_from_spec(spec, &info) < 0) {
return NULL;
}
name_buf = PyBytes_AS_STRING(info.name_encoded);

/* Remember pointer to module init function. */
def = PyModule_GetDef(m);
if (def == NULL) {
PyErr_Format(PyExc_SystemError,
"initialization of %s did not return an extension "
"module", name_buf);
goto error;
if (_PyImport_RunDynamicModule(&info, fp, &res) < 0) {
_Py_ext_module_loader_info_clear(&info);
return NULL;
}
def->m_base.m_init = p0;
m = res.module;
def = res.def;

/* Remember the filename as the __file__ attribute */
if (PyModule_AddObjectRef(m, "__file__", path) < 0) {
PyErr_Clear(); /* Not important enough to report */
if (m == NULL) {
_Py_ext_module_loader_info_clear(&info);
return PyModule_FromDefAndSpec(def, spec);
}

PyObject *modules = PyImport_GetModuleDict();
if (_PyImport_FixupExtensionObject(m, name_unicode, path, modules) < 0)
/* Fall back to single-phase init mechanism */

if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
goto error;
}

Py_DECREF(name_unicode);
Py_DECREF(name);
Py_DECREF(path);
PyObject *modules = PyImport_GetModuleDict();
if (_PyImport_FixupExtensionObject(m, info.name, info.path, modules) < 0) {
goto error;
}

_Py_ext_module_loader_info_clear(&info);
return m;

error:
Py_DECREF(name_unicode);
Py_XDECREF(name);
Py_XDECREF(path);
Py_XDECREF(m);
_Py_ext_module_loader_info_clear(&info);
Py_DECREF(m);
return NULL;
}

Expand Down