summaryrefslogtreecommitdiffstats
path: root/Python/import.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c143
1 files changed, 60 insertions, 83 deletions
diff --git a/Python/import.c b/Python/import.c
index d4c358f..0b843da 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -38,6 +38,14 @@ 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
@@ -312,7 +320,7 @@ PyImport_GetModuleDict(void)
/* List of names to clear in sys */
-static const char * const sys_deletes[] = {
+static char* sys_deletes[] = {
"path", "argv", "ps1", "ps2",
"last_type", "last_value", "last_traceback",
"path_hooks", "path_importer_cache", "meta_path",
@@ -322,7 +330,7 @@ static const char * const sys_deletes[] = {
NULL
};
-static const char * const sys_files[] = {
+static char* sys_files[] = {
"stdin", "__stdin__",
"stdout", "__stdout__",
"stderr", "__stderr__",
@@ -339,7 +347,7 @@ PyImport_Cleanup(void)
PyInterpreterState *interp = PyThreadState_GET()->interp;
PyObject *modules = interp->modules;
PyObject *weaklist = NULL;
- const char * const *p;
+ char **p;
if (modules == NULL)
return; /* Already done */
@@ -875,8 +883,10 @@ update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
if (PyUnicode_Compare(co->co_filename, oldname))
return;
- Py_INCREF(newname);
- Py_XSETREF(co->co_filename, newname);
+ tmp = co->co_filename;
+ co->co_filename = newname;
+ Py_INCREF(co->co_filename);
+ Py_DECREF(tmp);
constants = co->co_consts;
n = PyTuple_GET_SIZE(constants);
@@ -1321,8 +1331,10 @@ 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_XSETREF(*outer_link, next);
+ Py_DECREF(tmp);
prev_link = outer_link;
}
else {
@@ -1349,12 +1361,12 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
_Py_IDENTIFIER(_find_and_load);
_Py_IDENTIFIER(_handle_fromlist);
_Py_IDENTIFIER(_lock_unlock_module);
+ _Py_static_string(single_dot, ".");
PyObject *abs_name = NULL;
PyObject *builtins_import = NULL;
PyObject *final_mod = NULL;
PyObject *mod = NULL;
PyObject *package = NULL;
- PyObject *spec = NULL;
PyObject *globals = NULL;
PyObject *fromlist = NULL;
PyInterpreterState *interp = PyThreadState_GET()->interp;
@@ -1411,93 +1423,42 @@ 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;
}
-
- Py_INCREF(package);
- if (!PyUnicode_Check(package)) {
+ else 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) {
- Py_ssize_t dot;
-
- if (PyUnicode_READY(package) < 0) {
+ PyObject *partition = NULL;
+ PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot);
+ if (borrowed_dot == NULL) {
goto error;
}
-
- dot = PyUnicode_FindChar(package, '.',
- 0, PyUnicode_GET_LENGTH(package), -1);
- if (dot == -2) {
+ partition = PyUnicode_RPartition(package, borrowed_dot);
+ Py_DECREF(package);
+ if (partition == NULL) {
goto error;
}
-
- if (dot >= 0) {
- PyObject *substr = PyUnicode_Substring(package, 0, dot);
- if (substr == NULL) {
- goto error;
- }
- Py_SETREF(package, substr);
- }
+ package = PyTuple_GET_ITEM(partition, 0);
+ Py_INCREF(package);
+ Py_DECREF(partition);
}
}
- 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) {
+ if (PyDict_GetItem(interp->modules, package) == NULL) {
PyErr_Format(PyExc_SystemError,
"Parent module %R not loaded, cannot perform relative "
"import", package);
@@ -1536,8 +1497,17 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
goto error;
if (PyUnicode_GET_LENGTH(name) > 0) {
- abs_name = PyUnicode_FromFormat("%U.%U", base, name);
+ PyObject *borrowed_dot, *seq = NULL;
+
+ borrowed_dot = _PyUnicode_FromId(&single_dot);
+ seq = PyTuple_Pack(2, base, name);
Py_DECREF(base);
+ if (borrowed_dot == NULL || seq == NULL) {
+ goto error;
+ }
+
+ abs_name = PyUnicode_Join(borrowed_dot, seq);
+ Py_DECREF(seq);
if (abs_name == NULL) {
goto error;
}
@@ -1635,36 +1605,43 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
if (has_from < 0)
goto error;
if (!has_from) {
- Py_ssize_t len = PyUnicode_GET_LENGTH(name);
- if (level == 0 || len > 0) {
- Py_ssize_t dot;
+ if (level == 0 || PyUnicode_GET_LENGTH(name) > 0) {
+ PyObject *front = NULL;
+ PyObject *partition = NULL;
+ PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot);
+
+ if (borrowed_dot == NULL) {
+ goto error;
+ }
- dot = PyUnicode_FindChar(name, '.', 0, len, 1);
- if (dot == -2) {
+ partition = PyUnicode_Partition(name, borrowed_dot);
+ if (partition == NULL) {
goto error;
}
- if (dot == -1) {
+ if (PyUnicode_GET_LENGTH(PyTuple_GET_ITEM(partition, 1)) == 0) {
/* No dot in module name, simple exit */
+ Py_DECREF(partition);
final_mod = mod;
Py_INCREF(mod);
goto error;
}
- if (level == 0) {
- PyObject *front = PyUnicode_Substring(name, 0, dot);
- if (front == NULL) {
- goto error;
- }
+ front = PyTuple_GET_ITEM(partition, 0);
+ Py_INCREF(front);
+ Py_DECREF(partition);
+ if (level == 0) {
final_mod = PyObject_CallFunctionObjArgs(builtins_import, front, NULL);
Py_DECREF(front);
}
else {
- Py_ssize_t cut_off = len - dot;
+ Py_ssize_t cut_off = PyUnicode_GET_LENGTH(name) -
+ PyUnicode_GET_LENGTH(front);
Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name);
PyObject *to_return = PyUnicode_Substring(abs_name, 0,
abs_name_len - cut_off);
+ Py_DECREF(front);
if (to_return == NULL) {
goto error;
}