mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
Issue #18018: Raise an ImportError if a relative import is attempted
with no known parent package. Previously SystemError was raised if the parent package didn't exist (e.g., __package__ was set to ''). Thanks to Florent Xicluna and Yongzhi Pan for reporting the issue.
This commit is contained in:
parent
4b18dd339a
commit
9fa812668f
4 changed files with 20 additions and 3 deletions
|
@ -278,6 +278,10 @@ Changes in the Python API
|
||||||
to ``__spec__.parent`` then :exc:`ImportWarning` is raised.
|
to ``__spec__.parent`` then :exc:`ImportWarning` is raised.
|
||||||
(Contributed by Brett Cannon in :issue:`25791`.)
|
(Contributed by Brett Cannon in :issue:`25791`.)
|
||||||
|
|
||||||
|
* When a relative import is performed and no parent package is known, then
|
||||||
|
:exc:`ImportError` will be raised. Previously, :exc:`SystemError` could be
|
||||||
|
raised. (Contribute by Brett Cannon in :issue:`18018`.)
|
||||||
|
|
||||||
|
|
||||||
Changes in the C API
|
Changes in the C API
|
||||||
--------------------
|
--------------------
|
||||||
|
|
|
@ -213,6 +213,11 @@ class RelativeImports:
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
self.__import__('sys', level=1)
|
self.__import__('sys', level=1)
|
||||||
|
|
||||||
|
def test_relative_import_no_package(self):
|
||||||
|
with self.assertRaises(ImportError):
|
||||||
|
self.__import__('a', {'__package__': '', '__spec__': None},
|
||||||
|
level=1)
|
||||||
|
|
||||||
|
|
||||||
(Frozen_RelativeImports,
|
(Frozen_RelativeImports,
|
||||||
Source_RelativeImports
|
Source_RelativeImports
|
||||||
|
|
|
@ -10,6 +10,9 @@ Release date: tba
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #18018: Import raises ImportError instead of SystemError if a relative
|
||||||
|
import is attempted without a known parent package.
|
||||||
|
|
||||||
- Issue #25843: When compiling code, don't merge constants if they are equal
|
- Issue #25843: When compiling code, don't merge constants if they are equal
|
||||||
but have a different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0``
|
but have a different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0``
|
||||||
is now correctly compiled to two different functions: ``f1()`` returns ``1``
|
is now correctly compiled to two different functions: ``f1()`` returns ``1``
|
||||||
|
|
|
@ -1424,7 +1424,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
|
||||||
PyErr_SetString(PyExc_TypeError, "package must be a string");
|
PyErr_SetString(PyExc_TypeError, "package must be a string");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
else if (spec != NULL) {
|
else if (spec != NULL && spec != Py_None) {
|
||||||
int equal;
|
int equal;
|
||||||
PyObject *parent = PyObject_GetAttrString(spec, "parent");
|
PyObject *parent = PyObject_GetAttrString(spec, "parent");
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
|
@ -1444,7 +1444,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (spec != NULL) {
|
else if (spec != NULL && spec != Py_None) {
|
||||||
package = PyObject_GetAttrString(spec, "parent");
|
package = PyObject_GetAttrString(spec, "parent");
|
||||||
if (package == NULL) {
|
if (package == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1491,7 +1491,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,
|
PyErr_Format(PyExc_SystemError,
|
||||||
"Parent module %R not loaded, cannot perform relative "
|
"Parent module %R not loaded, cannot perform relative "
|
||||||
"import", package);
|
"import", package);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue