mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +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 | ||||
| 
 | ||||
| .. 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 | ||||
|  |  | |||
|  | @ -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 @@ def __enter__(self): | |||
|             # (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): | ||||
|  |  | |||
|  | @ -55,6 +55,18 @@ def test_reload_failed(self): | |||
|         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): | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Brett Cannon
						Brett Cannon