diff options
Diffstat (limited to 'Python/import.c')
| -rw-r--r-- | Python/import.c | 76 | 
1 files changed, 55 insertions, 21 deletions
| diff --git a/Python/import.c b/Python/import.c index 0b843da..6d71f2a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -38,14 +38,6 @@ module _imp  #include "clinic/import.c.h" -/*[python input] -class fs_unicode_converter(CConverter): -    type = 'PyObject *' -    converter = 'PyUnicode_FSDecoder' - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=9d6786230166006e]*/ -  /* Initialize things */  void @@ -320,7 +312,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 +322,7 @@ static char* sys_deletes[] = {      NULL  }; -static char* sys_files[] = { +static const char * const sys_files[] = {      "stdin", "__stdin__",      "stdout", "__stdout__",      "stderr", "__stderr__", @@ -347,7 +339,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 +875,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_XSETREF(co->co_filename, newname);      constants = co->co_consts;      n = PyTuple_GET_SIZE(constants); @@ -1331,10 +1321,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_XSETREF(*outer_link, next);              prev_link = outer_link;          }          else { @@ -1367,6 +1355,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 +1412,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 +1487,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); | 
