summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/importlib/_bootstrap.py7
-rw-r--r--Lib/test/test_import/__init__.py14
-rw-r--r--Lib/test/test_import/data/unwritable/__init__.py12
-rw-r--r--Lib/test/test_import/data/unwritable/x.py0
4 files changed, 32 insertions, 1 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 8de0e9e..7b74e88 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -978,7 +978,12 @@ def _find_and_load_unlocked(name, import_):
if parent:
# Set the module as an attribute on its parent.
parent_module = sys.modules[parent]
- setattr(parent_module, name.rpartition('.')[2], module)
+ child = name.rpartition('.')[2]
+ try:
+ setattr(parent_module, child, module)
+ except AttributeError:
+ msg = f"Cannot set an attribute on {parent!r} for child module {child!r}"
+ _warnings.warn(msg, ImportWarning)
return module
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 13d0481..482fe6a 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -26,6 +26,7 @@ from test.support import (
temp_dir, DirsOnSysPath)
from test.support import script_helper
from test.test_importlib.util import uncache
+from types import ModuleType
skip_if_dont_write_bytecode = unittest.skipIf(
@@ -1339,6 +1340,19 @@ class CircularImportTests(unittest.TestCase):
str(cm.exception),
)
+ def test_unwritable_module(self):
+ self.addCleanup(unload, "test.test_import.data.unwritable")
+ self.addCleanup(unload, "test.test_import.data.unwritable.x")
+
+ import test.test_import.data.unwritable as unwritable
+ with self.assertWarns(ImportWarning):
+ from test.test_import.data.unwritable import x
+
+ self.assertNotEqual(type(unwritable), ModuleType)
+ self.assertEqual(type(x), ModuleType)
+ with self.assertRaises(AttributeError):
+ unwritable.x = 42
+
if __name__ == '__main__':
# Test needs to be a package, so we can do relative imports.
diff --git a/Lib/test/test_import/data/unwritable/__init__.py b/Lib/test/test_import/data/unwritable/__init__.py
new file mode 100644
index 0000000..da4ddb3
--- /dev/null
+++ b/Lib/test/test_import/data/unwritable/__init__.py
@@ -0,0 +1,12 @@
+import sys
+
+class MyMod(object):
+ __slots__ = ['__builtins__', '__cached__', '__doc__',
+ '__file__', '__loader__', '__name__',
+ '__package__', '__path__', '__spec__']
+ def __init__(self):
+ for attr in self.__slots__:
+ setattr(self, attr, globals()[attr])
+
+
+sys.modules[__name__] = MyMod()
diff --git a/Lib/test/test_import/data/unwritable/x.py b/Lib/test/test_import/data/unwritable/x.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Lib/test/test_import/data/unwritable/x.py