mirror of
https://github.com/python/cpython.git
synced 2025-08-15 22:30:42 +00:00
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.
This commit is contained in:
parent
028d51236a
commit
b60a43eabf
3 changed files with 30 additions and 2 deletions
|
@ -788,7 +788,7 @@ an :term:`importer`.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. 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
|
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
|
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
|
:attr:`sys.modules` occurs if the module was new and an exception was
|
||||||
raised.
|
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
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
.. decorator:: module_for_loader
|
.. decorator:: module_for_loader
|
||||||
|
|
|
@ -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._name = name
|
||||||
|
self._reset_name = reset_name
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._module = sys.modules.get(self._name)
|
self._module = sys.modules.get(self._name)
|
||||||
|
@ -508,6 +514,12 @@ class _ModuleManager:
|
||||||
# (otherwise an optimization shortcut in import.c becomes wrong)
|
# (otherwise an optimization shortcut in import.c becomes wrong)
|
||||||
self._module.__initializing__ = True
|
self._module.__initializing__ = True
|
||||||
sys.modules[self._name] = self._module
|
sys.modules[self._name] = self._module
|
||||||
|
elif self._reset_name:
|
||||||
|
try:
|
||||||
|
self._module.__name__ = self._name
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
return self._module
|
return self._module
|
||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
|
|
|
@ -55,6 +55,18 @@ class ModuleToLoadTests(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
self.fail('importlib.util.module_to_load swallowed an exception')
|
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):
|
class ModuleForLoaderTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue