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_w_long = _bootstrap_external._w_long 52_r_long = _bootstrap_external._r_long 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('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 if not module or not isinstance(module, types.ModuleType): 139 raise TypeError("reload() argument must be module") 140 try: 141 name = module.__spec__.name 142 except AttributeError: 143 name = module.__name__ 144 145 if sys.modules.get(name) is not module: 146 msg = "module {} not in sys.modules" 147 raise ImportError(msg.format(name), name=name) 148 if name in _RELOADING: 149 return _RELOADING[name] 150 _RELOADING[name] = module 151 try: 152 parent_name = name.rpartition('.')[0] 153 if parent_name: 154 try: 155 parent = sys.modules[parent_name] 156 except KeyError: 157 msg = "parent {!r} not in sys.modules" 158 raise ImportError(msg.format(parent_name), 159 name=parent_name) from None 160 else: 161 pkgpath = parent.__path__ 162 else: 163 pkgpath = None 164 target = module 165 spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) 166 _bootstrap._exec(spec, module) 167 # The module may have replaced itself in sys.modules! 168 return sys.modules[name] 169 finally: 170 try: 171 del _RELOADING[name] 172 except KeyError: 173 pass 174