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._setup(_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 types 58import warnings 59 60 61# Public API ######################################################### 62 63from ._bootstrap import __import__ 64 65 66def invalidate_caches(): 67 """Call the invalidate_caches() method on all meta path finders stored in 68 sys.meta_path (where implemented).""" 69 for finder in sys.meta_path: 70 if hasattr(finder, 'invalidate_caches'): 71 finder.invalidate_caches() 72 73 74def find_loader(name, path=None): 75 """Return the loader for the specified module. 76 77 This is a backward-compatible wrapper around find_spec(). 78 79 This function is deprecated in favor of importlib.util.find_spec(). 80 81 """ 82 warnings.warn('Deprecated since Python 3.4. ' 83 'Use importlib.util.find_spec() instead.', 84 DeprecationWarning, stacklevel=2) 85 try: 86 loader = sys.modules[name].__loader__ 87 if loader is None: 88 raise ValueError('{}.__loader__ is None'.format(name)) 89 else: 90 return loader 91 except KeyError: 92 pass 93 except AttributeError: 94 raise ValueError('{}.__loader__ is not set'.format(name)) from None 95 96 spec = _bootstrap._find_spec(name, path) 97 # We won't worry about malformed specs (missing attributes). 98 if spec is None: 99 return None 100 if spec.loader is None: 101 if spec.submodule_search_locations is None: 102 raise ImportError('spec for {} missing loader'.format(name), 103 name=name) 104 raise ImportError('namespace packages do not have loaders', 105 name=name) 106 return spec.loader 107 108 109def import_module(name, package=None): 110 """Import a module. 111 112 The 'package' argument is required when performing a relative import. It 113 specifies the package to use as the anchor point from which to resolve the 114 relative import to an absolute import. 115 116 """ 117 level = 0 118 if name.startswith('.'): 119 if not package: 120 msg = ("the 'package' argument is required to perform a relative " 121 "import for {!r}") 122 raise TypeError(msg.format(name)) 123 for character in name: 124 if character != '.': 125 break 126 level += 1 127 return _bootstrap._gcd_import(name[level:], package, level) 128 129 130_RELOADING = {} 131 132 133def reload(module): 134 """Reload the module and return it. 135 136 The module must have been successfully imported before. 137 138 """ 139 if not module or not isinstance(module, types.ModuleType): 140 raise TypeError("reload() argument must be a module") 141 try: 142 name = module.__spec__.name 143 except AttributeError: 144 name = module.__name__ 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