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 |    .. 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 @@ def __enter__(self): | ||||||
|             # (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 @@ def test_reload_failed(self): | ||||||
|         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
	
	 Brett Cannon
						Brett Cannon