cpython: Add a reset_name argument to importlib.util.module_to_load in order to
http://hg.python.org/cpython/rev/39cc1b04713e changeset: 83998:39cc1b04713e user: Brett Cannon <brett@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
I realize this broke the buildbots. Missed part of a diff in the commit. I'm trying to split a massive CL into reasonable commit sizes, so please be patient. On Fri, May 31, 2013 at 6:11 PM, brett.cannon <python-checkins@python.org>wrote:
http://hg.python.org/cpython/rev/39cc1b04713e changeset: 83998:39cc1b04713e user: Brett Cannon <brett@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
_______________________________________________ Python-checkins mailing list Python-checkins@python.org http://mail.python.org/mailman/listinfo/python-checkins
participants (2)
-
Brett Cannon
-
brett.cannon