mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-44717: improve AttributeError on circular imports of submodules (GH-27338)
This commit is contained in:
		
							parent
							
								
									717f608c4a
								
							
						
					
					
						commit
						0a8ae8a50a
					
				
					 9 changed files with 1809 additions and 1734 deletions
				
			
		|  | @ -361,6 +361,7 @@ def __init__(self, name, loader, *, origin=None, loader_state=None, | |||
|         self.origin = origin | ||||
|         self.loader_state = loader_state | ||||
|         self.submodule_search_locations = [] if is_package else None | ||||
|         self._uninitialized_submodules = [] | ||||
| 
 | ||||
|         # file-location attributes | ||||
|         self._set_fileattr = False | ||||
|  | @ -987,6 +988,7 @@ def _sanity_check(name, package, level): | |||
| def _find_and_load_unlocked(name, import_): | ||||
|     path = None | ||||
|     parent = name.rpartition('.')[0] | ||||
|     parent_spec = None | ||||
|     if parent: | ||||
|         if parent not in sys.modules: | ||||
|             _call_with_frames_removed(import_, parent) | ||||
|  | @ -999,15 +1001,24 @@ def _find_and_load_unlocked(name, import_): | |||
|         except AttributeError: | ||||
|             msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) | ||||
|             raise ModuleNotFoundError(msg, name=name) from None | ||||
|         parent_spec = parent_module.__spec__ | ||||
|         child = name.rpartition('.')[2] | ||||
|     spec = _find_spec(name, path) | ||||
|     if spec is None: | ||||
|         raise ModuleNotFoundError(_ERR_MSG.format(name), name=name) | ||||
|     else: | ||||
|         module = _load_unlocked(spec) | ||||
|         if parent_spec: | ||||
|             # Temporarily add child we are currently importing to parent's | ||||
|             # _uninitialized_submodules for circular import tracking. | ||||
|             parent_spec._uninitialized_submodules.append(child) | ||||
|         try: | ||||
|             module = _load_unlocked(spec) | ||||
|         finally: | ||||
|             if parent_spec: | ||||
|                 parent_spec._uninitialized_submodules.pop() | ||||
|     if parent: | ||||
|         # Set the module as an attribute on its parent. | ||||
|         parent_module = sys.modules[parent] | ||||
|         child = name.rpartition('.')[2] | ||||
|         try: | ||||
|             setattr(parent_module, child, module) | ||||
|         except AttributeError: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Filipe Laíns
						Filipe Laíns