summaryrefslogtreecommitdiffstats
path: root/Python/import.c
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2016-01-22 23:25:50 (GMT)
committerBrett Cannon <brett@python.org>2016-01-22 23:25:50 (GMT)
commit849113af6ba96c36ffaaa9896c9a337eb3253b89 (patch)
treecbcbf462841260fbe63c30ed11776028c39ba74e /Python/import.c
parent52c854a83819f1e5ec4aa907cdcc875b02a7ea07 (diff)
downloadcpython-849113af6ba96c36ffaaa9896c9a337eb3253b89.zip
cpython-849113af6ba96c36ffaaa9896c9a337eb3253b89.tar.gz
cpython-849113af6ba96c36ffaaa9896c9a337eb3253b89.tar.bz2
Issue #25791: Warn when __package__ != __spec__.parent.
In a previous change, __spec__.parent was prioritized over __package__. That is a backwards-compatibility break, but we do eventually want __spec__ to be the ground truth for module details. So this change reverts the change in semantics and instead raises an ImportWarning when __package__ != __spec__.parent to give people time to adjust to using spec objects.
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c97
1 files changed, 58 insertions, 39 deletions
diff --git a/Python/import.c b/Python/import.c
index c1071c0..22f9d21 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1415,60 +1415,79 @@ 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");
+ goto error;
+ }
+ else if (spec != NULL) {
+ 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) {
+ 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 {
- 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;
- }
+ if (PyErr_WarnEx(PyExc_ImportWarning,
+ "can't resolve package from __spec__ or __package__, "
+ "falling back on __name__ and __path__", 1) < 0) {
+ 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;
- }
+ 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)) {
- PyErr_SetString(PyExc_TypeError, "__name__ must be a string");
+ Py_INCREF(package);
+ 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;
}
-
- 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);
+ 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);
}
}