mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	gh-117182: Allow lazily loaded modules to modify their own __class__
This commit is contained in:
		
							parent
							
								
									ac45766673
								
							
						
					
					
						commit
						19a2202067
					
				
					 3 changed files with 38 additions and 4 deletions
				
			
		|  | @ -178,15 +178,17 @@ def __getattribute__(self, attr): | |||
|             # Only the first thread to get the lock should trigger the load | ||||
|             # and reset the module's class. The rest can now getattr(). | ||||
|             if object.__getattribute__(self, '__class__') is _LazyModule: | ||||
|                 __class__ = loader_state['__class__'] | ||||
| 
 | ||||
|                 # Reentrant calls from the same thread must be allowed to proceed without | ||||
|                 # triggering the load again. | ||||
|                 # exec_module() and self-referential imports are the primary ways this can | ||||
|                 # happen, but in any case we must return something to avoid deadlock. | ||||
|                 if loader_state['is_loading']: | ||||
|                     return object.__getattribute__(self, attr) | ||||
|                     return __class__.__getattribute__(self, attr) | ||||
|                 loader_state['is_loading'] = True | ||||
| 
 | ||||
|                 __dict__ = object.__getattribute__(self, '__dict__') | ||||
|                 __dict__ = __class__.__getattribute__(self, '__dict__') | ||||
| 
 | ||||
|                 # All module metadata must be gathered from __spec__ in order to avoid | ||||
|                 # using mutated values. | ||||
|  | @ -216,8 +218,10 @@ def __getattribute__(self, attr): | |||
|                 # Update after loading since that's what would happen in an eager | ||||
|                 # loading situation. | ||||
|                 __dict__.update(attrs_updated) | ||||
|                 # Finally, stop triggering this method. | ||||
|                 self.__class__ = types.ModuleType | ||||
|                 # Finally, stop triggering this method, if the module did not | ||||
|                 # already update its own __class__. | ||||
|                 if isinstance(self, _LazyModule): | ||||
|                     object.__setattr__(self, '__class__', __class__) | ||||
| 
 | ||||
|         return getattr(self, attr) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chris Markiewicz
						Chris Markiewicz