1"""A pure Python implementation of import.""" 2__all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] 3 4# Bootstrap help ##################################################### 5 6# Until bootstrapping is complete, DO NOT import any modules that attempt 7# to import importlib._bootstrap (directly or indirectly). Since this 8# partially initialised package would be present in sys.modules, those 9# modules would get an uninitialised copy of the source version, instead 10# of a fully initialised version (either the frozen one or the one 11# initialised below if the frozen one is not available). 12import _imp # Just the builtin component, NOT the full Python module 13import sys 14 15try: 16 import _frozen_importlib as _bootstrap 17except ImportError: 18 from . import _bootstrap 19 _bootstrap._setup(sys, _imp) 20else: 21 # importlib._bootstrap is the built-in import, ensure we don't create 22 # a second copy of the module. 23 _bootstrap.__name__ = 'importlib._bootstrap' 24 _bootstrap.__package__ = 'importlib' 25 try: 26 _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') 27 except NameError: 28 # __file__ is not guaranteed to be defined, e.g. if this code gets 29 # frozen by a tool like cx_Freeze. 30 pass 31 sys.modules['importlib._bootstrap'] = _bootstrap 32 33try: 34 import _frozen_importlib_external as _bootstrap_external 35except ImportError: 36 from . import _bootstrap_external 37 _bootstrap_external._set_bootstrap_module(_bootstrap) 38 _bootstrap._bootstrap_external = _bootstrap_external 39else: 40 _bootstrap_external.__name__ = 'importlib._bootstrap_external' 41 _bootstrap_external.__package__ = 'importlib' 42 try: 43 _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') 44 except NameError: 45 # __file__ is not guaranteed to be defined, e.g. if this code gets 46 # frozen by a tool like cx_Freeze. 47 pass 48 sys.modules['importlib._bootstrap_external'] = _bootstrap_external 49 50# To simplify imports in test code 51_pack_uint32 = _bootstrap_external._pack_uint32 52_unpack_uint32 = _bootstrap_external._unpack_uint32 53 54# Fully bootstrapped at this point, import whatever you like, circular 55# dependencies and startup overhead minimisation permitting :) 56 57import warnings 58 59 60# Public API ######################################################### 61 62from ._bootstrap import __import__ 63 64 65def invalidate_caches(): 66 """Call the invalidate_caches() method on all meta path finders stored in 67 sys.meta_path (where implemented).""" 68 for finder in sys.meta_path: 69 if hasattr(finder, 'invalidate_caches'): 70 finder.invalidate_caches() 71 72 73def find_loader(name, path=None): 74 """Return the loader for the specified module. 75 76 This is a backward-compatible wrapper around find_spec(). 77 78 This function is deprecated in favor of importlib.util.find_spec(). 79 80 """ 81 warnings.warn('Deprecated since Python 3.4 and slated for removal in ' 82 'Python 3.12; use importlib.util.find_spec() instead', 83 DeprecationWarning, stacklevel=2) 84 try: 85 loader = sys.modules[name].__loader__ 86 if loader is None: 87 raise ValueError('{}.__loader__ is None'.format(name)) 88 else: 89 return loader 90 except KeyError: 91 pass 92 except AttributeError: 93 raise ValueError('{}.__loader__ is not set'.format(name)) from None 94 95 spec = _bootstrap._find_spec(name, path) 96 # We won't worry about malformed specs (missing attributes). 97 if spec is None: 98 return None 99 if spec.loader is None: 100 if spec.submodule_search_locations is None: 101 raise ImportError('spec for {} missing loader'.format(name), 102 name=name) 103 raise ImportError('namespace packages do not have loaders', 104 name=name) 105 return spec.loader 106 107 108def import_module(name, package=None): 109 """Import a module. 110 111 The 'package' argument is required when performing a relative import. It 112 specifies the package to use as the anchor point from which to resolve the 113 relative import to an absolute import. 114 115 """ 116 level = 0 117 if name.startswith('.'): 118 if not package: 119 msg = ("the 'package' argument is required to perform a relative " 120 "import for {!r}") 121 raise TypeError(msg.format(name)) 122 for character in name: 123 if character != '.': 124 break 125 level += 1 126 return _bootstrap._gcd_import(name[level:], package, level) 127 128 129_RELOADING = {} 130 131 132def reload(module): 133 """Reload the module and return it. 134 135 The module must have been successfully imported before. 136 137 """ 138 try: 139 name = module.__spec__.name 140 except AttributeError: 141 try: 142 name = module.__name__ 143 except AttributeError: 144 raise TypeError("reload() argument must be a module") 145 146 if sys.modules.get(name) is not module: 147 msg = "module {} not in sys.modules" 148 raise ImportError(msg.format(name), name=name) 149 if name in _RELOADING: 150 return _RELOADING[name] 151 _RELOADING[name] = module 152 try: 153 parent_name = name.rpartition('.')[0] 154 if parent_name: 155 try: 156 parent = sys.modules[parent_name] 157 except KeyError: 158 msg = "parent {!r} not in sys.modules" 159 raise ImportError(msg.format(parent_name), 160 name=parent_name) from None 161 else: 162 pkgpath = parent.__path__ 163 else: 164 pkgpath = None 165 target = module 166 spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) 167 if spec is None: 168 raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) 169 _bootstrap._exec(spec, module) 170 # The module may have replaced itself in sys.modules! 171 return sys.modules[name] 172 finally: 173 try: 174 del _RELOADING[name] 175 except KeyError: 176 pass 177