Issue #3080: Add PyImport_AddModuleObject() and PyImport_ExecCodeModuleObject()
This commit is contained in:
parent
0639b56672
commit
27ee089c35
|
@ -86,7 +86,7 @@ Importing Modules
|
|||
an exception set on failure (the module still exists in this case).
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_AddModule(const char *name)
|
||||
.. c:function:: PyObject* PyImport_AddModuleObject(PyObject *name)
|
||||
|
||||
Return the module object corresponding to a module name. The *name* argument
|
||||
may be of the form ``package.module``. First check the modules dictionary if
|
||||
|
@ -100,6 +100,14 @@ Importing Modules
|
|||
or one of its variants to import a module. Package structures implied by a
|
||||
dotted name for *name* are not created if not already present.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_AddModule(const char *name)
|
||||
|
||||
Similar to :c:func:`PyImport_AddModuleObject`, but the name is an UTF-8
|
||||
encoded string instead of a Unicode object.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_ExecCodeModule(char *name, PyObject *co)
|
||||
|
||||
|
@ -136,14 +144,23 @@ Importing Modules
|
|||
See also :c:func:`PyImport_ExecCodeModuleWithPathnames`.
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname, char *cpathname)
|
||||
.. c:function:: PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname)
|
||||
|
||||
Like :c:func:`PyImport_ExecCodeModuleEx`, but the :attr:`__cached__`
|
||||
attribute of the module object is set to *cpathname* if it is
|
||||
non-``NULL``. Of the three functions, this is the preferred one to use.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
|
||||
.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname, char *cpathname)
|
||||
|
||||
Like :c:func:`PyImport_ExecCodeModuleObject`, but *name*, *pathname* and
|
||||
*cpathname* are UTF-8 encoded strings.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
|
||||
.. c:function:: long PyImport_GetMagicNumber()
|
||||
|
||||
Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` and
|
||||
|
|
|
@ -24,7 +24,16 @@ PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames(
|
|||
char *pathname, /* decoded from the filesystem encoding */
|
||||
char *cpathname /* decoded from the filesystem encoding */
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject(
|
||||
PyObject *name,
|
||||
PyObject *co,
|
||||
PyObject *pathname,
|
||||
PyObject *cpathname
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
||||
PyAPI_FUNC(PyObject *) PyImport_AddModuleObject(
|
||||
PyObject *name
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_AddModule(
|
||||
const char *name /* UTF-8 encoded string */
|
||||
);
|
||||
|
|
|
@ -698,18 +698,18 @@ _PyImport_FindBuiltin(const char *name)
|
|||
'NEW' REFERENCE! */
|
||||
|
||||
PyObject *
|
||||
PyImport_AddModule(const char *name)
|
||||
PyImport_AddModuleObject(PyObject *name)
|
||||
{
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
PyObject *m;
|
||||
|
||||
if ((m = PyDict_GetItemString(modules, name)) != NULL &&
|
||||
if ((m = PyDict_GetItem(modules, name)) != NULL &&
|
||||
PyModule_Check(m))
|
||||
return m;
|
||||
m = PyModule_New(name);
|
||||
m = PyModule_NewObject(name);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(modules, name, m) != 0) {
|
||||
if (PyDict_SetItem(modules, name, m) != 0) {
|
||||
Py_DECREF(m);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -718,14 +718,27 @@ PyImport_AddModule(const char *name)
|
|||
return m;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyImport_AddModule(const char *name)
|
||||
{
|
||||
PyObject *nameobj, *module;
|
||||
nameobj = PyUnicode_FromString(name);
|
||||
if (nameobj == NULL)
|
||||
return NULL;
|
||||
module = PyImport_AddModuleObject(nameobj);
|
||||
Py_DECREF(nameobj);
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
/* Remove name from sys.modules, if it's there. */
|
||||
static void
|
||||
remove_module(const char *name)
|
||||
remove_module(PyObject *name)
|
||||
{
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
if (PyDict_GetItemString(modules, name) == NULL)
|
||||
if (PyDict_GetItem(modules, name) == NULL)
|
||||
return;
|
||||
if (PyDict_DelItemString(modules, name) < 0)
|
||||
if (PyDict_DelItem(modules, name) < 0)
|
||||
Py_FatalError("import: deleting existing key in"
|
||||
"sys.modules failed");
|
||||
}
|
||||
|
@ -762,11 +775,43 @@ PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
|
|||
PyObject *
|
||||
PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
|
||||
char *cpathname)
|
||||
{
|
||||
PyObject *m = NULL;
|
||||
PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL;
|
||||
|
||||
nameobj = PyUnicode_FromString(name);
|
||||
if (nameobj == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pathname != NULL) {
|
||||
pathobj = PyUnicode_DecodeFSDefault(pathname);
|
||||
if (pathobj == NULL)
|
||||
goto error;
|
||||
} else
|
||||
pathobj = NULL;
|
||||
if (cpathname != NULL) {
|
||||
cpathobj = PyUnicode_DecodeFSDefault(cpathname);
|
||||
if (cpathobj == NULL)
|
||||
goto error;
|
||||
} else
|
||||
cpathobj = NULL;
|
||||
m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj);
|
||||
error:
|
||||
Py_DECREF(nameobj);
|
||||
Py_XDECREF(pathobj);
|
||||
Py_XDECREF(cpathobj);
|
||||
return m;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
|
||||
PyObject *cpathname)
|
||||
{
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
PyObject *m, *d, *v;
|
||||
PyObject *pathbytes;
|
||||
|
||||
m = PyImport_AddModule(name);
|
||||
m = PyImport_AddModuleObject(name);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
/* If the module is being reloaded, we get the old module back
|
||||
|
@ -778,12 +823,18 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
|
|||
goto error;
|
||||
}
|
||||
/* Remember the filename as the __file__ attribute */
|
||||
v = NULL;
|
||||
if (pathname != NULL) {
|
||||
v = get_sourcefile(pathname);
|
||||
pathbytes = PyUnicode_EncodeFSDefault(pathname);
|
||||
if (pathbytes != NULL) {
|
||||
v = get_sourcefile(PyBytes_AS_STRING(pathbytes));
|
||||
Py_DECREF(pathbytes);
|
||||
} else
|
||||
v = NULL;
|
||||
if (v == NULL)
|
||||
PyErr_Clear();
|
||||
}
|
||||
else
|
||||
v = NULL;
|
||||
if (v == NULL) {
|
||||
v = ((PyCodeObject *)co)->co_filename;
|
||||
Py_INCREF(v);
|
||||
|
@ -793,27 +844,21 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
|
|||
Py_DECREF(v);
|
||||
|
||||
/* Remember the pyc path name as the __cached__ attribute. */
|
||||
if (cpathname == NULL) {
|
||||
if (cpathname != NULL)
|
||||
v = cpathname;
|
||||
else
|
||||
v = Py_None;
|
||||
Py_INCREF(v);
|
||||
}
|
||||
else if ((v = PyUnicode_FromString(cpathname)) == NULL) {
|
||||
PyErr_Clear(); /* Not important enough to report */
|
||||
v = Py_None;
|
||||
Py_INCREF(v);
|
||||
}
|
||||
if (PyDict_SetItemString(d, "__cached__", v) != 0)
|
||||
PyErr_Clear(); /* Not important enough to report */
|
||||
Py_DECREF(v);
|
||||
|
||||
v = PyEval_EvalCode(co, d, d);
|
||||
if (v == NULL)
|
||||
goto error;
|
||||
Py_DECREF(v);
|
||||
|
||||
if ((m = PyDict_GetItemString(modules, name)) == NULL) {
|
||||
if ((m = PyDict_GetItem(modules, name)) == NULL) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Loaded module %.200s not found in sys.modules",
|
||||
"Loaded module %R not found in sys.modules",
|
||||
name);
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue