Home | History | Annotate | Download | only in Lib
      1 """This module provides the components needed to build your own __import__
      2 function.  Undocumented functions are obsolete.
      3 
      4 In most cases it is preferred you consider using the importlib module's
      5 functionality over this module.
      6 
      7 """
      8 # (Probably) need to stay in _imp
      9 from _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)
     13 try:
     14     from _imp import create_dynamic
     15 except ImportError:
     16     # Platform doesn't support dynamic loading.
     17     create_dynamic = None
     18 
     19 from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name
     20 from importlib._bootstrap_external import SourcelessFileLoader
     21 
     22 from importlib import machinery
     23 from importlib import util
     24 import importlib
     25 import os
     26 import sys
     27 import tokenize
     28 import types
     29 import warnings
     30 
     31 warnings.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
     36 SEARCH_ERROR = 0
     37 PY_SOURCE = 1
     38 PY_COMPILED = 2
     39 C_EXTENSION = 3
     40 PY_RESOURCE = 4
     41 PKG_DIRECTORY = 5
     42 C_BUILTIN = 6
     43 PY_FROZEN = 7
     44 PY_CODERESOURCE = 8
     45 IMP_HOOK = 9
     46 
     47 
     48 def 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 
     59 def get_magic():
     60     """**DEPRECATED**
     61 
     62     Return the magic number for .pyc files.
     63     """
     64     return util.MAGIC_NUMBER
     65 
     66 
     67 def get_tag():
     68     """Return the magic tag for .pyc files."""
     69     return sys.implementation.cache_tag
     70 
     71 
     72 def 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 
     91 def 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 
    105 def 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 
    114 class 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 
    133 class _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 
    160 class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader):
    161 
    162     """Compatibility support for implementing load_source()."""
    163 
    164 
    165 def 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 
    179 class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader):
    180 
    181     """Compatibility support for implementing load_compiled()."""
    182 
    183 
    184 def 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 
    199 def 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 
    219 def 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 
    254 def 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 
    306 def 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 
    317 def 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 
    329 if 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 
    344 else:
    345     load_dynamic = None
    346