1"""This module provides the components needed to build your own __import__ 2function. Undocumented functions are obsolete. 3 4In most cases it is preferred you consider using the importlib module's 5functionality over this module. 6 7""" 8# (Probably) need to stay in _imp 9from _imp import (lock_held, acquire_lock, release_lock, 10 get_frozen_object, is_frozen_package, 11 init_frozen, is_builtin, is_frozen, 12 _fix_co_filename) 13try: 14 from _imp import create_dynamic 15except ImportError: 16 # Platform doesn't support dynamic loading. 17 create_dynamic = None 18 19from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name 20from importlib._bootstrap_external import SourcelessFileLoader 21 22from importlib import machinery 23from importlib import util 24import importlib 25import os 26import sys 27import tokenize 28import types 29import warnings 30 31warnings.warn("the imp module is deprecated in favour of importlib; " 32 "see the module's documentation for alternative uses", 33 DeprecationWarning, stacklevel=2) 34 35# DEPRECATED 36SEARCH_ERROR = 0 37PY_SOURCE = 1 38PY_COMPILED = 2 39C_EXTENSION = 3 40PY_RESOURCE = 4 41PKG_DIRECTORY = 5 42C_BUILTIN = 6 43PY_FROZEN = 7 44PY_CODERESOURCE = 8 45IMP_HOOK = 9 46 47 48def new_module(name): 49 """**DEPRECATED** 50 51 Create a new module. 52 53 The module is not entered into sys.modules. 54 55 """ 56 return types.ModuleType(name) 57 58 59def get_magic(): 60 """**DEPRECATED** 61 62 Return the magic number for .pyc files. 63 """ 64 return util.MAGIC_NUMBER 65 66 67def get_tag(): 68 """Return the magic tag for .pyc files.""" 69 return sys.implementation.cache_tag 70 71 72def cache_from_source(path, debug_override=None): 73 """**DEPRECATED** 74 75 Given the path to a .py file, return the path to its .pyc file. 76 77 The .py file does not need to exist; this simply returns the path to the 78 .pyc file calculated as if the .py file were imported. 79 80 If debug_override is not None, then it must be a boolean and is used in 81 place of sys.flags.optimize. 82 83 If sys.implementation.cache_tag is None then NotImplementedError is raised. 84 85 """ 86 with warnings.catch_warnings(): 87 warnings.simplefilter('ignore') 88 return util.cache_from_source(path, debug_override) 89 90 91def source_from_cache(path): 92 """**DEPRECATED** 93 94 Given the path to a .pyc. file, return the path to its .py file. 95 96 The .pyc file does not need to exist; this simply returns the path to 97 the .py file calculated to correspond to the .pyc file. If path does 98 not conform to PEP 3147 format, ValueError will be raised. If 99 sys.implementation.cache_tag is None then NotImplementedError is raised. 100 101 """ 102 return util.source_from_cache(path) 103 104 105def get_suffixes(): 106 """**DEPRECATED**""" 107 extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES] 108 source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] 109 bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES] 110 111 return extensions + source + bytecode 112 113 114class NullImporter: 115 116 """**DEPRECATED** 117 118 Null import object. 119 120 """ 121 122 def __init__(self, path): 123 if path == '': 124 raise ImportError('empty pathname', path='') 125 elif os.path.isdir(path): 126 raise ImportError('existing directory', path=path) 127 128 def find_module(self, fullname): 129 """Always returns None.""" 130 return None 131 132 133class _HackedGetData: 134 135 """Compatibility support for 'file' arguments of various load_*() 136 functions.""" 137 138 def __init__(self, fullname, path, file=None): 139 super().__init__(fullname, path) 140 self.file = file 141 142 def get_data(self, path): 143 """Gross hack to contort loader to deal w/ load_*()'s bad API.""" 144 if self.file and path == self.path: 145 # The contract of get_data() requires us to return bytes. Reopen the 146 # file in binary mode if needed. 147 if not self.file.closed: 148 file = self.file 149 if 'b' not in file.mode: 150 file.close() 151 if self.file.closed: 152 self.file = file = open(self.path, 'rb') 153 154 with file: 155 return file.read() 156 else: 157 return super().get_data(path) 158 159 160class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader): 161 162 """Compatibility support for implementing load_source().""" 163 164 165def load_source(name, pathname, file=None): 166 loader = _LoadSourceCompatibility(name, pathname, file) 167 spec = util.spec_from_file_location(name, pathname, loader=loader) 168 if name in sys.modules: 169 module = _exec(spec, sys.modules[name]) 170 else: 171 module = _load(spec) 172 # To allow reloading to potentially work, use a non-hacked loader which 173 # won't rely on a now-closed file object. 174 module.__loader__ = machinery.SourceFileLoader(name, pathname) 175 module.__spec__.loader = module.__loader__ 176 return module 177 178 179class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader): 180 181 """Compatibility support for implementing load_compiled().""" 182 183 184def load_compiled(name, pathname, file=None): 185 """**DEPRECATED**""" 186 loader = _LoadCompiledCompatibility(name, pathname, file) 187 spec = util.spec_from_file_location(name, pathname, loader=loader) 188 if name in sys.modules: 189 module = _exec(spec, sys.modules[name]) 190 else: 191 module = _load(spec) 192 # To allow reloading to potentially work, use a non-hacked loader which 193 # won't rely on a now-closed file object. 194 module.__loader__ = SourcelessFileLoader(name, pathname) 195 module.__spec__.loader = module.__loader__ 196 return module 197 198 199def load_package(name, path): 200 """**DEPRECATED**""" 201 if os.path.isdir(path): 202 extensions = (machinery.SOURCE_SUFFIXES[:] + 203 machinery.BYTECODE_SUFFIXES[:]) 204 for extension in extensions: 205 init_path = os.path.join(path, '__init__' + extension) 206 if os.path.exists(init_path): 207 path = init_path 208 break 209 else: 210 raise ValueError('{!r} is not a package'.format(path)) 211 spec = util.spec_from_file_location(name, path, 212 submodule_search_locations=[]) 213 if name in sys.modules: 214 return _exec(spec, sys.modules[name]) 215 else: 216 return _load(spec) 217 218 219def load_module(name, file, filename, details): 220 """**DEPRECATED** 221 222 Load a module, given information returned by find_module(). 223 224 The module name must include the full package name, if any. 225 226 """ 227 suffix, mode, type_ = details 228 if mode and (not mode.startswith(('r', 'U')) or '+' in mode): 229 raise ValueError('invalid file open mode {!r}'.format(mode)) 230 elif file is None and type_ in {PY_SOURCE, PY_COMPILED}: 231 msg = 'file object required for import (type code {})'.format(type_) 232 raise ValueError(msg) 233 elif type_ == PY_SOURCE: 234 return load_source(name, filename, file) 235 elif type_ == PY_COMPILED: 236 return load_compiled(name, filename, file) 237 elif type_ == C_EXTENSION and load_dynamic is not None: 238 if file is None: 239 with open(filename, 'rb') as opened_file: 240 return load_dynamic(name, filename, opened_file) 241 else: 242 return load_dynamic(name, filename, file) 243 elif type_ == PKG_DIRECTORY: 244 return load_package(name, filename) 245 elif type_ == C_BUILTIN: 246 return init_builtin(name) 247 elif type_ == PY_FROZEN: 248 return init_frozen(name) 249 else: 250 msg = "Don't know how to import {} (type code {})".format(name, type_) 251 raise ImportError(msg, name=name) 252 253 254def find_module(name, path=None): 255 """**DEPRECATED** 256 257 Search for a module. 258 259 If path is omitted or None, search for a built-in, frozen or special 260 module and continue search in sys.path. The module name cannot 261 contain '.'; to search for a submodule of a package, pass the 262 submodule name and the package's __path__. 263 264 """ 265 if not isinstance(name, str): 266 raise TypeError("'name' must be a str, not {}".format(type(name))) 267 elif not isinstance(path, (type(None), list)): 268 # Backwards-compatibility 269 raise RuntimeError("'path' must be None or a list, " 270 "not {}".format(type(path))) 271 272 if path is None: 273 if is_builtin(name): 274 return None, None, ('', '', C_BUILTIN) 275 elif is_frozen(name): 276 return None, None, ('', '', PY_FROZEN) 277 else: 278 path = sys.path 279 280 for entry in path: 281 package_directory = os.path.join(entry, name) 282 for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]: 283 package_file_name = '__init__' + suffix 284 file_path = os.path.join(package_directory, package_file_name) 285 if os.path.isfile(file_path): 286 return None, package_directory, ('', '', PKG_DIRECTORY) 287 for suffix, mode, type_ in get_suffixes(): 288 file_name = name + suffix 289 file_path = os.path.join(entry, file_name) 290 if os.path.isfile(file_path): 291 break 292 else: 293 continue 294 break # Break out of outer loop when breaking out of inner loop. 295 else: 296 raise ImportError(_ERR_MSG.format(name), name=name) 297 298 encoding = None 299 if 'b' not in mode: 300 with open(file_path, 'rb') as file: 301 encoding = tokenize.detect_encoding(file.readline)[0] 302 file = open(file_path, mode, encoding=encoding) 303 return file, file_path, (suffix, mode, type_) 304 305 306def reload(module): 307 """**DEPRECATED** 308 309 Reload the module and return it. 310 311 The module must have been successfully imported before. 312 313 """ 314 return importlib.reload(module) 315 316 317def init_builtin(name): 318 """**DEPRECATED** 319 320 Load and return a built-in module by name, or None is such module doesn't 321 exist 322 """ 323 try: 324 return _builtin_from_name(name) 325 except ImportError: 326 return None 327 328 329if create_dynamic: 330 def load_dynamic(name, path, file=None): 331 """**DEPRECATED** 332 333 Load an extension module. 334 """ 335 import importlib.machinery 336 loader = importlib.machinery.ExtensionFileLoader(name, path) 337 338 # Issue #24748: Skip the sys.modules check in _load_module_shim; 339 # always load new extension 340 spec = importlib.machinery.ModuleSpec( 341 name=name, loader=loader, origin=path) 342 return _load(spec) 343 344else: 345 load_dynamic = None 346