summaryrefslogtreecommitdiffstats
path: root/Python/import.c
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2016-01-15 21:33:03 (GMT)
committerBrett Cannon <brett@python.org>2016-01-15 21:33:03 (GMT)
commit63b8505281f9c26f7304b3e00d658b429b862d5b (patch)
tree07a4d20ed327d8493aa7105bec9ca1d598cc6b7c /Python/import.c
parent43cfd8240c274b2f4cf0588f3defae83e7379a55 (diff)
downloadcpython-63b8505281f9c26f7304b3e00d658b429b862d5b.zip
cpython-63b8505281f9c26f7304b3e00d658b429b862d5b.tar.gz
cpython-63b8505281f9c26f7304b3e00d658b429b862d5b.tar.bz2
Issue #25791: Raise an ImportWarning when __spec__ or __package__ are
not defined for a relative import. This is the start of work to try and clean up import semantics to rely more on a module's spec than on the myriad attributes that get set on a module. Thanks to Rose Ames for the patch.
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/Python/import.c b/Python/import.c
index 325b936..c1071c0 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1359,6 +1359,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;
@@ -1414,39 +1415,60 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
goto error;
}
else if (level > 0) {
- package = _PyDict_GetItemId(globals, &PyId___package__);
+ spec = _PyDict_GetItemId(globals, &PyId___spec__);
+ if (spec != NULL) {
+ package = PyObject_GetAttrString(spec, "parent");
+ }
if (package != NULL && package != Py_None) {
- Py_INCREF(package);
if (!PyUnicode_Check(package)) {
- PyErr_SetString(PyExc_TypeError, "package must be a string");
+ PyErr_SetString(PyExc_TypeError,
+ "__spec__.parent must be a string");
goto error;
}
}
else {
- package = _PyDict_GetItemId(globals, &PyId___name__);
- if (package == NULL) {
- PyErr_SetString(PyExc_KeyError, "'__name__' not in globals");
- goto error;
- }
- else if (!PyUnicode_Check(package)) {
- PyErr_SetString(PyExc_TypeError, "__name__ must be a string");
+ package = _PyDict_GetItemId(globals, &PyId___package__);
+ if (package != NULL && package != Py_None) {
+ Py_INCREF(package);
+ if (!PyUnicode_Check(package)) {
+ PyErr_SetString(PyExc_TypeError, "package must be a string");
+ goto error;
+ }
}
- Py_INCREF(package);
-
- if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) {
- PyObject *partition = NULL;
- PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot);
- if (borrowed_dot == NULL) {
+ else {
+ if (PyErr_WarnEx(PyExc_ImportWarning,
+ "can't resolve package from __spec__ or __package__, "
+ "falling back on __name__ and __path__", 1) < 0) {
goto error;
}
- partition = PyUnicode_RPartition(package, borrowed_dot);
- Py_DECREF(package);
- if (partition == NULL) {
+
+ package = _PyDict_GetItemId(globals, &PyId___name__);
+ if (package == NULL) {
+ PyErr_SetString(PyExc_KeyError, "'__name__' not in globals");
goto error;
}
- package = PyTuple_GET_ITEM(partition, 0);
+
Py_INCREF(package);
- Py_DECREF(partition);
+ if (!PyUnicode_Check(package)) {
+ PyErr_SetString(PyExc_TypeError, "__name__ must be a string");
+ goto error;
+ }
+
+ if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) {
+ PyObject *partition = NULL;
+ PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot);
+ if (borrowed_dot == NULL) {
+ goto error;
+ }
+ partition = PyUnicode_RPartition(package, borrowed_dot);
+ Py_DECREF(package);
+ if (partition == NULL) {
+ goto error;
+ }
+ package = PyTuple_GET_ITEM(partition, 0);
+ Py_INCREF(package);
+ Py_DECREF(partition);
+ }
}
}