diff options
Diffstat (limited to 'Python/import.c')
-rw-r--r-- | Python/import.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/Python/import.c b/Python/import.c index 0b843da..22f94f5 100644 --- a/Python/import.c +++ b/Python/import.c @@ -320,7 +320,7 @@ PyImport_GetModuleDict(void) /* List of names to clear in sys */ -static char* sys_deletes[] = { +static const char * const sys_deletes[] = { "path", "argv", "ps1", "ps2", "last_type", "last_value", "last_traceback", "path_hooks", "path_importer_cache", "meta_path", @@ -330,7 +330,7 @@ static char* sys_deletes[] = { NULL }; -static char* sys_files[] = { +static const char * const sys_files[] = { "stdin", "__stdin__", "stdout", "__stdout__", "stderr", "__stderr__", @@ -347,7 +347,7 @@ PyImport_Cleanup(void) PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; PyObject *weaklist = NULL; - char **p; + const char * const *p; if (modules == NULL) return; /* Already done */ @@ -883,10 +883,8 @@ update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) if (PyUnicode_Compare(co->co_filename, oldname)) return; - tmp = co->co_filename; - co->co_filename = newname; - Py_INCREF(co->co_filename); - Py_DECREF(tmp); + Py_INCREF(newname); + Py_SETREF(co->co_filename, newname); constants = co->co_consts; n = PyTuple_GET_SIZE(constants); @@ -1331,10 +1329,8 @@ remove_importlib_frames(void) (always_trim || PyUnicode_CompareWithASCIIString(code->co_name, remove_frames) == 0)) { - PyObject *tmp = *outer_link; - *outer_link = next; Py_XINCREF(next); - Py_DECREF(tmp); + Py_SETREF(*outer_link, next); prev_link = outer_link; } else { @@ -1367,6 +1363,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyObject *final_mod = NULL; PyObject *mod = NULL; PyObject *package = NULL; + PyObject *spec = NULL; PyObject *globals = NULL; PyObject *fromlist = NULL; PyInterpreterState *interp = PyThreadState_GET()->interp; @@ -1423,23 +1420,63 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } else if (level > 0) { package = _PyDict_GetItemId(globals, &PyId___package__); + spec = _PyDict_GetItemId(globals, &PyId___spec__); + if (package != NULL && package != Py_None) { Py_INCREF(package); if (!PyUnicode_Check(package)) { PyErr_SetString(PyExc_TypeError, "package must be a string"); goto error; } + else if (spec != NULL && spec != Py_None) { + int equal; + PyObject *parent = PyObject_GetAttrString(spec, "parent"); + if (parent == NULL) { + goto error; + } + + equal = PyObject_RichCompareBool(package, parent, Py_EQ); + Py_DECREF(parent); + if (equal < 0) { + goto error; + } + else if (equal == 0) { + if (PyErr_WarnEx(PyExc_ImportWarning, + "__package__ != __spec__.parent", 1) < 0) { + goto error; + } + } + } + } + else if (spec != NULL && spec != Py_None) { + package = PyObject_GetAttrString(spec, "parent"); + if (package == NULL) { + goto error; + } + else if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, + "__spec__.parent must be a string"); + goto error; + } } else { + if (PyErr_WarnEx(PyExc_ImportWarning, + "can't resolve package from __spec__ or __package__, " + "falling back on __name__ and __path__", 1) < 0) { + goto error; + } + package = _PyDict_GetItemId(globals, &PyId___name__); if (package == NULL) { PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); goto error; } - else if (!PyUnicode_Check(package)) { + + Py_INCREF(package); + if (!PyUnicode_Check(package)) { PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + goto error; } - Py_INCREF(package); if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) { PyObject *partition = NULL; @@ -1458,7 +1495,12 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } } - if (PyDict_GetItem(interp->modules, package) == NULL) { + if (PyUnicode_CompareWithASCIIString(package, "") == 0) { + PyErr_SetString(PyExc_ImportError, + "attempted relative import with no known parent package"); + goto error; + } + else if (PyDict_GetItem(interp->modules, package) == NULL) { PyErr_Format(PyExc_SystemError, "Parent module %R not loaded, cannot perform relative " "import", package); |