Skip to content

Commit 3eae8f2

Browse files
authored
Revert "bpo-44717: improve AttributeError on circular imports of submodules (pythonGH-27299)" (pythonGH-27331)
This reverts commit 8072a11.
1 parent c836231 commit 3eae8f2

File tree

8 files changed

+1734
-1807
lines changed

8 files changed

+1734
-1807
lines changed

Lib/importlib/_bootstrap.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,6 @@ def __init__(self, name, loader, *, origin=None, loader_state=None,
361361
self.origin = origin
362362
self.loader_state = loader_state
363363
self.submodule_search_locations = [] if is_package else None
364-
self._uninitialized_submodules = []
365364

366365
# file-location attributes
367366
self._set_fileattr = False
@@ -988,7 +987,6 @@ def _sanity_check(name, package, level):
988987
def _find_and_load_unlocked(name, import_):
989988
path = None
990989
parent = name.rpartition('.')[0]
991-
parent_spec = None
992990
if parent:
993991
if parent not in sys.modules:
994992
_call_with_frames_removed(import_, parent)
@@ -1001,24 +999,15 @@ def _find_and_load_unlocked(name, import_):
1001999
except AttributeError:
10021000
msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent)
10031001
raise ModuleNotFoundError(msg, name=name) from None
1004-
parent_spec = parent_module.__spec__
1005-
child = name.rpartition('.')[2]
10061002
spec = _find_spec(name, path)
10071003
if spec is None:
10081004
raise ModuleNotFoundError(_ERR_MSG.format(name), name=name)
10091005
else:
1010-
if parent_spec:
1011-
# Temporarily add child we are currently importing to parent's
1012-
# _uninitialized_submodules for circular import tracking.
1013-
parent_spec._uninitialized_submodules.append(child)
1014-
try:
1015-
module = _load_unlocked(spec)
1016-
finally:
1017-
if parent_spec:
1018-
parent_spec._uninitialized_submodules.pop()
1006+
module = _load_unlocked(spec)
10191007
if parent:
10201008
# Set the module as an attribute on its parent.
10211009
parent_module = sys.modules[parent]
1010+
child = name.rpartition('.')[2]
10221011
try:
10231012
setattr(parent_module, child, module)
10241013
except AttributeError:

Lib/test/test_import/__init__.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,16 +1350,6 @@ def test_circular_from_import(self):
13501350
str(cm.exception),
13511351
)
13521352

1353-
def test_absolute_circular_submodule(self):
1354-
with self.assertRaises(AttributeError) as cm:
1355-
import test.test_import.data.circular_imports.subpkg2.parent
1356-
self.assertIn(
1357-
"cannot access submodule 'parent' of module "
1358-
"'test.test_import.data.circular_imports.subpkg2' "
1359-
"(most likely due to a circular import)",
1360-
str(cm.exception),
1361-
)
1362-
13631353
def test_unwritable_module(self):
13641354
self.addCleanup(unload, "test.test_import.data.unwritable")
13651355
self.addCleanup(unload, "test.test_import.data.unwritable.x")

Lib/test/test_import/data/circular_imports/subpkg2/__init__.py

Whitespace-only changes.

Lib/test/test_import/data/circular_imports/subpkg2/parent/__init__.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

Lib/test/test_import/data/circular_imports/subpkg2/parent/child.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

Misc/NEWS.d/next/Core and Builtins/2021-07-23-01-52-13.bpo-44717.-vVmAh.rst

Lines changed: 0 additions & 1 deletion
This file was deleted.

Objects/moduleobject.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -739,30 +739,6 @@ _PyModuleSpec_IsInitializing(PyObject *spec)
739739
return 0;
740740
}
741741

742-
/* Check if the submodule name is in the "_uninitialized_submodules" attribute
743-
of the module spec.
744-
*/
745-
int
746-
_PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
747-
{
748-
if (spec == NULL) {
749-
return 0;
750-
}
751-
752-
_Py_IDENTIFIER(_uninitialized_submodules);
753-
PyObject *value = _PyObject_GetAttrId(spec, &PyId__uninitialized_submodules);
754-
if (value == NULL) {
755-
return 0;
756-
}
757-
758-
int is_uninitialized = PySequence_Contains(value, name);
759-
Py_DECREF(value);
760-
if (is_uninitialized == -1) {
761-
return 0;
762-
}
763-
return is_uninitialized;
764-
}
765-
766742
static PyObject*
767743
module_getattro(PyModuleObject *m, PyObject *name)
768744
{
@@ -797,12 +773,6 @@ module_getattro(PyModuleObject *m, PyObject *name)
797773
"(most likely due to a circular import)",
798774
mod_name, name);
799775
}
800-
else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
801-
PyErr_Format(PyExc_AttributeError,
802-
"cannot access submodule '%U' of module '%U' "
803-
"(most likely due to a circular import)",
804-
name, mod_name);
805-
}
806776
else {
807777
PyErr_Format(PyExc_AttributeError,
808778
"module '%U' has no attribute '%U'",

0 commit comments

Comments
 (0)