]> granicus.if.org Git - python/commitdiff
Add a reset_name argument to importlib.util.module_to_load in order to
authorBrett Cannon <brett@python.org>
Fri, 31 May 2013 22:11:17 +0000 (18:11 -0400)
committerBrett Cannon <brett@python.org>
Fri, 31 May 2013 22:11:17 +0000 (18:11 -0400)
control whether to reset the module's __name__ attribute in case a
reload is being done.

Doc/library/importlib.rst
Lib/importlib/_bootstrap.py
Lib/test/test_importlib/test_util.py

index 976451c2f0dd755620597cd607555b18ea550179..35336b1251c876154b82bbc0c30a2a4416837a0c 100644 (file)
@@ -788,7 +788,7 @@ an :term:`importer`.
 
    .. versionadded:: 3.3
 
-.. function:: module_to_load(name)
+.. function:: module_to_load(name, *, reset_name=True)
 
     Returns a :term:`context manager` which provides the module to load. The
     module will either come from :attr:`sys.modules` in the case of reloading or
@@ -796,6 +796,10 @@ an :term:`importer`.
     :attr:`sys.modules` occurs if the module was new and an exception was
     raised.
 
+    If **reset_name** is true and the module requested is being reloaded then
+    the module's :attr:`__name__` attribute will
+    be reset to **name**, else it will be left untouched.
+
     .. versionadded:: 3.4
 
 .. decorator:: module_for_loader
index f5b71baf486f8e4846bf31979e6dcf986271e4dc..cd6a2639118cbbf780e59b18a78b96bab6a43e85 100644 (file)
@@ -493,8 +493,14 @@ class _ModuleManager:
 
     """
 
-    def __init__(self, name):
+    def __init__(self, name, *, reset_name=True):
+        """Prepare the context manager.
+
+        The reset_name argument specifies whether to unconditionally reset
+        the __name__ attribute if the module is found to be a reload.
+        """
         self._name = name
+        self._reset_name = reset_name
 
     def __enter__(self):
         self._module = sys.modules.get(self._name)
@@ -508,6 +514,12 @@ class _ModuleManager:
             # (otherwise an optimization shortcut in import.c becomes wrong)
             self._module.__initializing__ = True
             sys.modules[self._name] = self._module
+        elif self._reset_name:
+            try:
+                self._module.__name__ = self._name
+            except AttributeError:
+                pass
+
         return self._module
 
     def __exit__(self, *args):
index 7646b34b89eb43e718fa502a0bca70d573a9f4eb..9897def804bcc5484f552eac0300857655083b0b 100644 (file)
@@ -55,6 +55,18 @@ class ModuleToLoadTests(unittest.TestCase):
         else:
             self.fail('importlib.util.module_to_load swallowed an exception')
 
+    def test_reset_name(self):
+        # If reset_name is true then module.__name__ = name, else leave it be.
+        odd_name = 'not your typical name'
+        created_module = imp.new_module(self.module_name)
+        created_module.__name__ = odd_name
+        sys.modules[self.module_name] = created_module
+        with util.module_to_load(self.module_name) as module:
+            self.assertEqual(module.__name__, self.module_name)
+        created_module.__name__ = odd_name
+        with util.module_to_load(self.module_name, reset_name=False) as module:
+            self.assertEqual(module.__name__, odd_name)
+
 
 class ModuleForLoaderTests(unittest.TestCase):