[Python-checkins] cpython: Add a reset_name argument to importlib.util.module_to_load in order to

brett.cannon python-checkins at python.org
Sat Jun 1 00:11:26 CEST 2013


http://hg.python.org/cpython/rev/39cc1b04713e
changeset:   83998:39cc1b04713e
user:        Brett Cannon <brett at python.org>
date:        Fri May 31 18:11:17 2013 -0400
summary:
  Add a reset_name argument to importlib.util.module_to_load in order to
control whether to reset the module's __name__ attribute in case a
reload is being done.

files:
  Doc/library/importlib.rst            |   6 +++++-
  Lib/importlib/_bootstrap.py          |  14 +++++++++++++-
  Lib/test/test_importlib/test_util.py |  12 ++++++++++++
  3 files changed, 30 insertions(+), 2 deletions(-)


diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -788,7 +788,7 @@
 
    .. 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 @@
     :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
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -493,8 +493,14 @@
 
     """
 
-    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 @@
             # (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):
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -55,6 +55,18 @@
         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):
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list