Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9fa8126

Browse files
committed
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.
1 parent 4b18dd3 commit 9fa8126

4 files changed

Lines changed: 20 additions & 3 deletions

File tree

Doc/whatsnew/3.6.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ Changes in the Python API
278278
to ``__spec__.parent`` then :exc:`ImportWarning` is raised.
279279
(Contributed by Brett Cannon in :issue:`25791`.)
280280

281+
* When a relative import is performed and no parent package is known, then
282+
:exc:`ImportError` will be raised. Previously, :exc:`SystemError` could be
283+
raised. (Contribute by Brett Cannon in :issue:`18018`.)
284+
281285

282286
Changes in the C API
283287
--------------------

Lib/test/test_importlib/import_/test_relative_imports.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ def test_relative_import_no_globals(self):
213213
with self.assertRaises(KeyError):
214214
self.__import__('sys', level=1)
215215

216+
def test_relative_import_no_package(self):
217+
with self.assertRaises(ImportError):
218+
self.__import__('a', {'__package__': '', '__spec__': None},
219+
level=1)
220+
216221

217222
(Frozen_RelativeImports,
218223
Source_RelativeImports

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Release date: tba
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #18018: Import raises ImportError instead of SystemError if a relative
14+
import is attempted without a known parent package.
15+
1316
- Issue #25843: When compiling code, don't merge constants if they are equal
1417
but have a different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0``
1518
is now correctly compiled to two different functions: ``f1()`` returns ``1``

Python/import.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
14241424
PyErr_SetString(PyExc_TypeError, "package must be a string");
14251425
goto error;
14261426
}
1427-
else if (spec != NULL) {
1427+
else if (spec != NULL && spec != Py_None) {
14281428
int equal;
14291429
PyObject *parent = PyObject_GetAttrString(spec, "parent");
14301430
if (parent == NULL) {
@@ -1444,7 +1444,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
14441444
}
14451445
}
14461446
}
1447-
else if (spec != NULL) {
1447+
else if (spec != NULL && spec != Py_None) {
14481448
package = PyObject_GetAttrString(spec, "parent");
14491449
if (package == NULL) {
14501450
goto error;
@@ -1491,7 +1491,12 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
14911491
}
14921492
}
14931493

1494-
if (PyDict_GetItem(interp->modules, package) == NULL) {
1494+
if (PyUnicode_CompareWithASCIIString(package, "") == 0) {
1495+
PyErr_SetString(PyExc_ImportError,
1496+
"attempted relative import with no known parent package");
1497+
goto error;
1498+
}
1499+
else if (PyDict_GetItem(interp->modules, package) == NULL) {
14951500
PyErr_Format(PyExc_SystemError,
14961501
"Parent module %R not loaded, cannot perform relative "
14971502
"import", package);

0 commit comments

Comments
 (0)