Home | History | Annotate | Download | only in importlib
      1 """Core implementation of path-based import.
      2 
      3 This module is NOT meant to be directly imported! It has been designed such
      4 that it can be bootstrapped into Python as the implementation of import. As
      5 such it requires the injection of specific modules and attributes in order to
      6 work. One should use importlib as the public-facing version of this module.
      7 
      8 """
      9 #
     10 # IMPORTANT: Whenever making changes to this module, be sure to run
     11 # a top-level make in order to get the frozen version of the module
     12 # updated. Not doing so will result in the Makefile to fail for
     13 # all others who don't have a ./python around to freeze the module
     14 # in the early stages of compilation.
     15 #
     16 
     17 # See importlib._setup() for what is injected into the global namespace.
     18 
     19 # When editing this code be aware that code executed at import time CANNOT
     20 # reference any injected objects! This includes not only global code but also
     21 # anything specified at the class level.
     22 
     23 # Bootstrap-related code ######################################################
     24 _CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win',
     25 _CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin'
     26 _CASE_INSENSITIVE_PLATFORMS =  (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY
     27                                 + _CASE_INSENSITIVE_PLATFORMS_STR_KEY)
     28 
     29 
     30 def _make_relax_case():
     31     if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
     32         if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS_STR_KEY):
     33             key = 'PYTHONCASEOK'
     34         else:
     35             key = b'PYTHONCASEOK'
     36 
     37         def _relax_case():
     38             """True if filenames must be checked case-insensitively."""
     39             return key in _os.environ
     40     else:
     41         def _relax_case():
     42             """True if filenames must be checked case-insensitively."""
     43             return False
     44     return _relax_case
     45 
     46 
     47 def _w_long(x):
     48     """Convert a 32-bit integer to little-endian."""
     49     return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little')
     50 
     51 
     52 def _r_long(int_bytes):
     53     """Convert 4 bytes in little-endian to an integer."""
     54     return int.from_bytes(int_bytes, 'little')
     55 
     56 
     57 def _path_join(*path_parts):
     58     """Replacement for os.path.join()."""
     59     return path_sep.join([part.rstrip(path_separators)
     60                           for part in path_parts if part])
     61 
     62 
     63 def _path_split(path):
     64     """Replacement for os.path.split()."""
     65     if len(path_separators) == 1:
     66         front, _, tail = path.rpartition(path_sep)
     67         return front, tail
     68     for x in reversed(path):
     69         if x in path_separators:
     70             front, tail = path.rsplit(x, maxsplit=1)
     71             return front, tail
     72     return '', path
     73 
     74 
     75 def _path_stat(path):
     76     """Stat the path.
     77 
     78     Made a separate function to make it easier to override in experiments
     79     (e.g. cache stat results).
     80 
     81     """
     82     return _os.stat(path)
     83 
     84 
     85 def _path_is_mode_type(path, mode):
     86     """Test whether the path is the specified mode type."""
     87     try:
     88         stat_info = _path_stat(path)
     89     except OSError:
     90         return False
     91     return (stat_info.st_mode & 0o170000) == mode
     92 
     93 
     94 def _path_isfile(path):
     95     """Replacement for os.path.isfile."""
     96     return _path_is_mode_type(path, 0o100000)
     97 
     98 
     99 def _path_isdir(path):
    100     """Replacement for os.path.isdir."""
    101     if not path:
    102         path = _os.getcwd()
    103     return _path_is_mode_type(path, 0o040000)
    104 
    105 
    106 def _write_atomic(path, data, mode=0o666):
    107     """Best-effort function to write data to a path atomically.
    108     Be prepared to handle a FileExistsError if concurrent writing of the
    109     temporary file is attempted."""
    110     # id() is used to generate a pseudo-random filename.
    111     path_tmp = '{}.{}'.format(path, id(path))
    112     fd = _os.open(path_tmp,
    113                   _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666)
    114     try:
    115         # We first write data to a temporary file, and then use os.replace() to
    116         # perform an atomic rename.
    117         with _io.FileIO(fd, 'wb') as file:
    118             file.write(data)
    119         _os.replace(path_tmp, path)
    120     except OSError:
    121         try:
    122             _os.unlink(path_tmp)
    123         except OSError:
    124             pass
    125         raise
    126 
    127 
    128 _code_type = type(_write_atomic.__code__)
    129 
    130 
    131 # Finder/loader utility code ###############################################
    132 
    133 # Magic word to reject .pyc files generated by other Python versions.
    134 # It should change for each incompatible change to the bytecode.
    135 #
    136 # The value of CR and LF is incorporated so if you ever read or write
    137 # a .pyc file in text mode the magic number will be wrong; also, the
    138 # Apple MPW compiler swaps their values, botching string constants.
    139 #
    140 # There were a variety of old schemes for setting the magic number.
    141 # The current working scheme is to increment the previous value by
    142 # 10.
    143 #
    144 # Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic
    145 # number also includes a new "magic tag", i.e. a human readable string used
    146 # to represent the magic number in __pycache__ directories.  When you change
    147 # the magic number, you must also set a new unique magic tag.  Generally this
    148 # can be named after the Python major version of the magic number bump, but
    149 # it can really be anything, as long as it's different than anything else
    150 # that's come before.  The tags are included in the following table, starting
    151 # with Python 3.2a0.
    152 #
    153 # Known values:
    154 #  Python 1.5:   20121
    155 #  Python 1.5.1: 20121
    156 #     Python 1.5.2: 20121
    157 #     Python 1.6:   50428
    158 #     Python 2.0:   50823
    159 #     Python 2.0.1: 50823
    160 #     Python 2.1:   60202
    161 #     Python 2.1.1: 60202
    162 #     Python 2.1.2: 60202
    163 #     Python 2.2:   60717
    164 #     Python 2.3a0: 62011
    165 #     Python 2.3a0: 62021
    166 #     Python 2.3a0: 62011 (!)
    167 #     Python 2.4a0: 62041
    168 #     Python 2.4a3: 62051
    169 #     Python 2.4b1: 62061
    170 #     Python 2.5a0: 62071
    171 #     Python 2.5a0: 62081 (ast-branch)
    172 #     Python 2.5a0: 62091 (with)
    173 #     Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
    174 #     Python 2.5b3: 62101 (fix wrong code: for x, in ...)
    175 #     Python 2.5b3: 62111 (fix wrong code: x += yield)
    176 #     Python 2.5c1: 62121 (fix wrong lnotab with for loops and
    177 #                          storing constants that should have been removed)
    178 #     Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
    179 #     Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)
    180 #     Python 2.6a1: 62161 (WITH_CLEANUP optimization)
    181 #     Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND)
    182 #     Python 2.7a0: 62181 (optimize conditional branches:
    183 #                          introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
    184 #     Python 2.7a0  62191 (introduce SETUP_WITH)
    185 #     Python 2.7a0  62201 (introduce BUILD_SET)
    186 #     Python 2.7a0  62211 (introduce MAP_ADD and SET_ADD)
    187 #     Python 3000:   3000
    188 #                    3010 (removed UNARY_CONVERT)
    189 #                    3020 (added BUILD_SET)
    190 #                    3030 (added keyword-only parameters)
    191 #                    3040 (added signature annotations)
    192 #                    3050 (print becomes a function)
    193 #                    3060 (PEP 3115 metaclass syntax)
    194 #                    3061 (string literals become unicode)
    195 #                    3071 (PEP 3109 raise changes)
    196 #                    3081 (PEP 3137 make __file__ and __name__ unicode)
    197 #                    3091 (kill str8 interning)
    198 #                    3101 (merge from 2.6a0, see 62151)
    199 #                    3103 (__file__ points to source file)
    200 #     Python 3.0a4: 3111 (WITH_CLEANUP optimization).
    201 #     Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT)
    202 #     Python 3.1a0: 3141 (optimize list, set and dict comprehensions:
    203 #             change LIST_APPEND and SET_ADD, add MAP_ADD)
    204 #     Python 3.1a0: 3151 (optimize conditional branches:
    205 #             introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
    206 #     Python 3.2a0: 3160 (add SETUP_WITH)
    207 #                   tag: cpython-32
    208 #     Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
    209 #                   tag: cpython-32
    210 #     Python 3.2a2  3180 (add DELETE_DEREF)
    211 #     Python 3.3a0  3190 __class__ super closure changed
    212 #     Python 3.3a0  3200 (__qualname__ added)
    213 #                      3210 (added size modulo 2**32 to the pyc header)
    214 #     Python 3.3a1  3220 (changed PEP 380 implementation)
    215 #     Python 3.3a4  3230 (revert changes to implicit __class__ closure)
    216 #     Python 3.4a1  3250 (evaluate positional default arguments before
    217 #                        keyword-only defaults)
    218 #     Python 3.4a1  3260 (add LOAD_CLASSDEREF; allow locals of class to override
    219 #                        free vars)
    220 #     Python 3.4a1  3270 (various tweaks to the __class__ closure)
    221 #     Python 3.4a1  3280 (remove implicit class argument)
    222 #     Python 3.4a4  3290 (changes to __qualname__ computation)
    223 #     Python 3.4a4  3300 (more changes to __qualname__ computation)
    224 #     Python 3.4rc2 3310 (alter __qualname__ computation)
    225 #     Python 3.5a0  3320 (matrix multiplication operator)
    226 #     Python 3.5b1  3330 (PEP 448: Additional Unpacking Generalizations)
    227 #     Python 3.5b2  3340 (fix dictionary display evaluation order #11205)
    228 #     Python 3.5b2  3350 (add GET_YIELD_FROM_ITER opcode #24400)
    229 #     Python 3.5.2  3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
    230 #     Python 3.6a0  3360 (add FORMAT_VALUE opcode #25483
    231 #     Python 3.6a0  3361 (lineno delta of code.co_lnotab becomes signed)
    232 #     Python 3.6a1  3370 (16 bit wordcode)
    233 #     Python 3.6a1  3371 (add BUILD_CONST_KEY_MAP opcode #27140)
    234 #     Python 3.6a1  3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE
    235 #                         #27095)
    236 #     Python 3.6b1  3373 (add BUILD_STRING opcode #27078)
    237 #     Python 3.6b1  3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes
    238 #                         #27985)
    239 #     Python 3.6b1  3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL)
    240 #     Python 3.6b1  3377 (set __class__ cell from type.__new__ #23722)
    241 #     Python 3.6b2  3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257)
    242 #     Python 3.6rc1 3379 (more thorough __class__ validation #23722)
    243 #
    244 # MAGIC must change whenever the bytecode emitted by the compiler may no
    245 # longer be understood by older implementations of the eval loop (usually
    246 # due to the addition of new opcodes).
    247 #
    248 # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
    249 # in PC/launcher.c must also be updated.
    250 
    251 MAGIC_NUMBER = (3379).to_bytes(2, 'little') + b'\r\n'
    252 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
    253 
    254 _PYCACHE = '__pycache__'
    255 _OPT = 'opt-'
    256 
    257 SOURCE_SUFFIXES = ['.py']  # _setup() adds .pyw as needed.
    258 
    259 BYTECODE_SUFFIXES = ['.pyc']
    260 # Deprecated.
    261 DEBUG_BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES = BYTECODE_SUFFIXES
    262 
    263 def cache_from_source(path, debug_override=None, *, optimization=None):
    264     """Given the path to a .py file, return the path to its .pyc file.
    265 
    266     The .py file does not need to exist; this simply returns the path to the
    267     .pyc file calculated as if the .py file were imported.
    268 
    269     The 'optimization' parameter controls the presumed optimization level of
    270     the bytecode file. If 'optimization' is not None, the string representation
    271     of the argument is taken and verified to be alphanumeric (else ValueError
    272     is raised).
    273 
    274     The debug_override parameter is deprecated. If debug_override is not None,
    275     a True value is the same as setting 'optimization' to the empty string
    276     while a False value is equivalent to setting 'optimization' to '1'.
    277 
    278     If sys.implementation.cache_tag is None then NotImplementedError is raised.
    279 
    280     """
    281     if debug_override is not None:
    282         _warnings.warn('the debug_override parameter is deprecated; use '
    283                        "'optimization' instead", DeprecationWarning)
    284         if optimization is not None:
    285             message = 'debug_override or optimization must be set to None'
    286             raise TypeError(message)
    287         optimization = '' if debug_override else 1
    288     path = _os.fspath(path)
    289     head, tail = _path_split(path)
    290     base, sep, rest = tail.rpartition('.')
    291     tag = sys.implementation.cache_tag
    292     if tag is None:
    293         raise NotImplementedError('sys.implementation.cache_tag is None')
    294     almost_filename = ''.join([(base if base else rest), sep, tag])
    295     if optimization is None:
    296         if sys.flags.optimize == 0:
    297             optimization = ''
    298         else:
    299             optimization = sys.flags.optimize
    300     optimization = str(optimization)
    301     if optimization != '':
    302         if not optimization.isalnum():
    303             raise ValueError('{!r} is not alphanumeric'.format(optimization))
    304         almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization)
    305     return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0])
    306 
    307 
    308 def source_from_cache(path):
    309     """Given the path to a .pyc. file, return the path to its .py file.
    310 
    311     The .pyc file does not need to exist; this simply returns the path to
    312     the .py file calculated to correspond to the .pyc file.  If path does
    313     not conform to PEP 3147/488 format, ValueError will be raised. If
    314     sys.implementation.cache_tag is None then NotImplementedError is raised.
    315 
    316     """
    317     if sys.implementation.cache_tag is None:
    318         raise NotImplementedError('sys.implementation.cache_tag is None')
    319     path = _os.fspath(path)
    320     head, pycache_filename = _path_split(path)
    321     head, pycache = _path_split(head)
    322     if pycache != _PYCACHE:
    323         raise ValueError('{} not bottom-level directory in '
    324                          '{!r}'.format(_PYCACHE, path))
    325     dot_count = pycache_filename.count('.')
    326     if dot_count not in {2, 3}:
    327         raise ValueError('expected only 2 or 3 dots in '
    328                          '{!r}'.format(pycache_filename))
    329     elif dot_count == 3:
    330         optimization = pycache_filename.rsplit('.', 2)[-2]
    331         if not optimization.startswith(_OPT):
    332             raise ValueError("optimization portion of filename does not start "
    333                              "with {!r}".format(_OPT))
    334         opt_level = optimization[len(_OPT):]
    335         if not opt_level.isalnum():
    336             raise ValueError("optimization level {!r} is not an alphanumeric "
    337                              "value".format(optimization))
    338     base_filename = pycache_filename.partition('.')[0]
    339     return _path_join(head, base_filename + SOURCE_SUFFIXES[0])
    340 
    341 
    342 def _get_sourcefile(bytecode_path):
    343     """Convert a bytecode file path to a source path (if possible).
    344 
    345     This function exists purely for backwards-compatibility for
    346     PyImport_ExecCodeModuleWithFilenames() in the C API.
    347 
    348     """
    349     if len(bytecode_path) == 0:
    350         return None
    351     rest, _, extension = bytecode_path.rpartition('.')
    352     if not rest or extension.lower()[-3:-1] != 'py':
    353         return bytecode_path
    354     try:
    355         source_path = source_from_cache(bytecode_path)
    356     except (NotImplementedError, ValueError):
    357         source_path = bytecode_path[:-1]
    358     return source_path if _path_isfile(source_path) else bytecode_path
    359 
    360 
    361 def _get_cached(filename):
    362     if filename.endswith(tuple(SOURCE_SUFFIXES)):
    363         try:
    364             return cache_from_source(filename)
    365         except NotImplementedError:
    366             pass
    367     elif filename.endswith(tuple(BYTECODE_SUFFIXES)):
    368         return filename
    369     else:
    370         return None
    371 
    372 
    373 def _calc_mode(path):
    374     """Calculate the mode permissions for a bytecode file."""
    375     try:
    376         mode = _path_stat(path).st_mode
    377     except OSError:
    378         mode = 0o666
    379     # We always ensure write access so we can update cached files
    380     # later even when the source files are read-only on Windows (#6074)
    381     mode |= 0o200
    382     return mode
    383 
    384 
    385 def _check_name(method):
    386     """Decorator to verify that the module being requested matches the one the
    387     loader can handle.
    388 
    389     The first argument (self) must define _name which the second argument is
    390     compared against. If the comparison fails then ImportError is raised.
    391 
    392     """
    393     def _check_name_wrapper(self, name=None, *args, **kwargs):
    394         if name is None:
    395             name = self.name
    396         elif self.name != name:
    397             raise ImportError('loader for %s cannot handle %s' %
    398                                 (self.name, name), name=name)
    399         return method(self, name, *args, **kwargs)
    400     try:
    401         _wrap = _bootstrap._wrap
    402     except NameError:
    403         # XXX yuck
    404         def _wrap(new, old):
    405             for replace in ['__module__', '__name__', '__qualname__', '__doc__']:
    406                 if hasattr(old, replace):
    407                     setattr(new, replace, getattr(old, replace))
    408             new.__dict__.update(old.__dict__)
    409     _wrap(_check_name_wrapper, method)
    410     return _check_name_wrapper
    411 
    412 
    413 def _find_module_shim(self, fullname):
    414     """Try to find a loader for the specified module by delegating to
    415     self.find_loader().
    416 
    417     This method is deprecated in favor of finder.find_spec().
    418 
    419     """
    420     # Call find_loader(). If it returns a string (indicating this
    421     # is a namespace package portion), generate a warning and
    422     # return None.
    423     loader, portions = self.find_loader(fullname)
    424     if loader is None and len(portions):
    425         msg = 'Not importing directory {}: missing __init__'
    426         _warnings.warn(msg.format(portions[0]), ImportWarning)
    427     return loader
    428 
    429 
    430 def _validate_bytecode_header(data, source_stats=None, name=None, path=None):
    431     """Validate the header of the passed-in bytecode against source_stats (if
    432     given) and returning the bytecode that can be compiled by compile().
    433 
    434     All other arguments are used to enhance error reporting.
    435 
    436     ImportError is raised when the magic number is incorrect or the bytecode is
    437     found to be stale. EOFError is raised when the data is found to be
    438     truncated.
    439 
    440     """
    441     exc_details = {}
    442     if name is not None:
    443         exc_details['name'] = name
    444     else:
    445         # To prevent having to make all messages have a conditional name.
    446         name = '<bytecode>'
    447     if path is not None:
    448         exc_details['path'] = path
    449     magic = data[:4]
    450     raw_timestamp = data[4:8]
    451     raw_size = data[8:12]
    452     if magic != MAGIC_NUMBER:
    453         message = 'bad magic number in {!r}: {!r}'.format(name, magic)
    454         _bootstrap._verbose_message('{}', message)
    455         raise ImportError(message, **exc_details)
    456     elif len(raw_timestamp) != 4:
    457         message = 'reached EOF while reading timestamp in {!r}'.format(name)
    458         _bootstrap._verbose_message('{}', message)
    459         raise EOFError(message)
    460     elif len(raw_size) != 4:
    461         message = 'reached EOF while reading size of source in {!r}'.format(name)
    462         _bootstrap._verbose_message('{}', message)
    463         raise EOFError(message)
    464     if source_stats is not None:
    465         try:
    466             source_mtime = int(source_stats['mtime'])
    467         except KeyError:
    468             pass
    469         else:
    470             if _r_long(raw_timestamp) != source_mtime:
    471                 message = 'bytecode is stale for {!r}'.format(name)
    472                 _bootstrap._verbose_message('{}', message)
    473                 raise ImportError(message, **exc_details)
    474         try:
    475             source_size = source_stats['size'] & 0xFFFFFFFF
    476         except KeyError:
    477             pass
    478         else:
    479             if _r_long(raw_size) != source_size:
    480                 raise ImportError('bytecode is stale for {!r}'.format(name),
    481                                   **exc_details)
    482     return data[12:]
    483 
    484 
    485 def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None):
    486     """Compile bytecode as returned by _validate_bytecode_header()."""
    487     code = marshal.loads(data)
    488     if isinstance(code, _code_type):
    489         _bootstrap._verbose_message('code object from {!r}', bytecode_path)
    490         if source_path is not None:
    491             _imp._fix_co_filename(code, source_path)
    492         return code
    493     else:
    494         raise ImportError('Non-code object in {!r}'.format(bytecode_path),
    495                           name=name, path=bytecode_path)
    496 
    497 def _code_to_bytecode(code, mtime=0, source_size=0):
    498     """Compile a code object into bytecode for writing out to a byte-compiled
    499     file."""
    500     data = bytearray(MAGIC_NUMBER)
    501     data.extend(_w_long(mtime))
    502     data.extend(_w_long(source_size))
    503     data.extend(marshal.dumps(code))
    504     return data
    505 
    506 
    507 def decode_source(source_bytes):
    508     """Decode bytes representing source code and return the string.
    509 
    510     Universal newline support is used in the decoding.
    511     """
    512     import tokenize  # To avoid bootstrap issues.
    513     source_bytes_readline = _io.BytesIO(source_bytes).readline
    514     encoding = tokenize.detect_encoding(source_bytes_readline)
    515     newline_decoder = _io.IncrementalNewlineDecoder(None, True)
    516     return newline_decoder.decode(source_bytes.decode(encoding[0]))
    517 
    518 
    519 # Module specifications #######################################################
    520 
    521 _POPULATE = object()
    522 
    523 
    524 def spec_from_file_location(name, location=None, *, loader=None,
    525                             submodule_search_locations=_POPULATE):
    526     """Return a module spec based on a file location.
    527 
    528     To indicate that the module is a package, set
    529     submodule_search_locations to a list of directory paths.  An
    530     empty list is sufficient, though its not otherwise useful to the
    531     import system.
    532 
    533     The loader must take a spec as its only __init__() arg.
    534 
    535     """
    536     if location is None:
    537         # The caller may simply want a partially populated location-
    538         # oriented spec.  So we set the location to a bogus value and
    539         # fill in as much as we can.
    540         location = '<unknown>'
    541         if hasattr(loader, 'get_filename'):
    542             # ExecutionLoader
    543             try:
    544                 location = loader.get_filename(name)
    545             except ImportError:
    546                 pass
    547     else:
    548         location = _os.fspath(location)
    549 
    550     # If the location is on the filesystem, but doesn't actually exist,
    551     # we could return None here, indicating that the location is not
    552     # valid.  However, we don't have a good way of testing since an
    553     # indirect location (e.g. a zip file or URL) will look like a
    554     # non-existent file relative to the filesystem.
    555 
    556     spec = _bootstrap.ModuleSpec(name, loader, origin=location)
    557     spec._set_fileattr = True
    558 
    559     # Pick a loader if one wasn't provided.
    560     if loader is None:
    561         for loader_class, suffixes in _get_supported_file_loaders():
    562             if location.endswith(tuple(suffixes)):
    563                 loader = loader_class(name, location)
    564                 spec.loader = loader
    565                 break
    566         else:
    567             return None
    568 
    569     # Set submodule_search_paths appropriately.
    570     if submodule_search_locations is _POPULATE:
    571         # Check the loader.
    572         if hasattr(loader, 'is_package'):
    573             try:
    574                 is_package = loader.is_package(name)
    575             except ImportError:
    576                 pass
    577             else:
    578                 if is_package:
    579                     spec.submodule_search_locations = []
    580     else:
    581         spec.submodule_search_locations = submodule_search_locations
    582     if spec.submodule_search_locations == []:
    583         if location:
    584             dirname = _path_split(location)[0]
    585             spec.submodule_search_locations.append(dirname)
    586 
    587     return spec
    588 
    589 
    590 # Loaders #####################################################################
    591 
    592 class WindowsRegistryFinder:
    593 
    594     """Meta path finder for modules declared in the Windows registry."""
    595 
    596     REGISTRY_KEY = (
    597         'Software\\Python\\PythonCore\\{sys_version}'
    598         '\\Modules\\{fullname}')
    599     REGISTRY_KEY_DEBUG = (
    600         'Software\\Python\\PythonCore\\{sys_version}'
    601         '\\Modules\\{fullname}\\Debug')
    602     DEBUG_BUILD = False  # Changed in _setup()
    603 
    604     @classmethod
    605     def _open_registry(cls, key):
    606         try:
    607             return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key)
    608         except OSError:
    609             return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
    610 
    611     @classmethod
    612     def _search_registry(cls, fullname):
    613         if cls.DEBUG_BUILD:
    614             registry_key = cls.REGISTRY_KEY_DEBUG
    615         else:
    616             registry_key = cls.REGISTRY_KEY
    617         key = registry_key.format(fullname=fullname,
    618                                   sys_version='%d.%d' % sys.version_info[:2])
    619         try:
    620             with cls._open_registry(key) as hkey:
    621                 filepath = _winreg.QueryValue(hkey, '')
    622         except OSError:
    623             return None
    624         return filepath
    625 
    626     @classmethod
    627     def find_spec(cls, fullname, path=None, target=None):
    628         filepath = cls._search_registry(fullname)
    629         if filepath is None:
    630             return None
    631         try:
    632             _path_stat(filepath)
    633         except OSError:
    634             return None
    635         for loader, suffixes in _get_supported_file_loaders():
    636             if filepath.endswith(tuple(suffixes)):
    637                 spec = _bootstrap.spec_from_loader(fullname,
    638                                                    loader(fullname, filepath),
    639                                                    origin=filepath)
    640                 return spec
    641 
    642     @classmethod
    643     def find_module(cls, fullname, path=None):
    644         """Find module named in the registry.
    645 
    646         This method is deprecated.  Use exec_module() instead.
    647 
    648         """
    649         spec = cls.find_spec(fullname, path)
    650         if spec is not None:
    651             return spec.loader
    652         else:
    653             return None
    654 
    655 
    656 class _LoaderBasics:
    657 
    658     """Base class of common code needed by both SourceLoader and
    659     SourcelessFileLoader."""
    660 
    661     def is_package(self, fullname):
    662         """Concrete implementation of InspectLoader.is_package by checking if
    663         the path returned by get_filename has a filename of '__init__.py'."""
    664         filename = _path_split(self.get_filename(fullname))[1]
    665         filename_base = filename.rsplit('.', 1)[0]
    666         tail_name = fullname.rpartition('.')[2]
    667         return filename_base == '__init__' and tail_name != '__init__'
    668 
    669     def create_module(self, spec):
    670         """Use default semantics for module creation."""
    671 
    672     def exec_module(self, module):
    673         """Execute the module."""
    674         code = self.get_code(module.__name__)
    675         if code is None:
    676             raise ImportError('cannot load module {!r} when get_code() '
    677                               'returns None'.format(module.__name__))
    678         _bootstrap._call_with_frames_removed(exec, code, module.__dict__)
    679 
    680     def load_module(self, fullname):
    681         """This module is deprecated."""
    682         return _bootstrap._load_module_shim(self, fullname)
    683 
    684 
    685 class SourceLoader(_LoaderBasics):
    686 
    687     def path_mtime(self, path):
    688         """Optional method that returns the modification time (an int) for the
    689         specified path, where path is a str.
    690 
    691         Raises IOError when the path cannot be handled.
    692         """
    693         raise IOError
    694 
    695     def path_stats(self, path):
    696         """Optional method returning a metadata dict for the specified path
    697         to by the path (str).
    698         Possible keys:
    699         - 'mtime' (mandatory) is the numeric timestamp of last source
    700           code modification;
    701         - 'size' (optional) is the size in bytes of the source code.
    702 
    703         Implementing this method allows the loader to read bytecode files.
    704         Raises IOError when the path cannot be handled.
    705         """
    706         return {'mtime': self.path_mtime(path)}
    707 
    708     def _cache_bytecode(self, source_path, cache_path, data):
    709         """Optional method which writes data (bytes) to a file path (a str).
    710 
    711         Implementing this method allows for the writing of bytecode files.
    712 
    713         The source path is needed in order to correctly transfer permissions
    714         """
    715         # For backwards compatibility, we delegate to set_data()
    716         return self.set_data(cache_path, data)
    717 
    718     def set_data(self, path, data):
    719         """Optional method which writes data (bytes) to a file path (a str).
    720 
    721         Implementing this method allows for the writing of bytecode files.
    722         """
    723 
    724 
    725     def get_source(self, fullname):
    726         """Concrete implementation of InspectLoader.get_source."""
    727         path = self.get_filename(fullname)
    728         try:
    729             source_bytes = self.get_data(path)
    730         except OSError as exc:
    731             raise ImportError('source not available through get_data()',
    732                               name=fullname) from exc
    733         return decode_source(source_bytes)
    734 
    735     def source_to_code(self, data, path, *, _optimize=-1):
    736         """Return the code object compiled from source.
    737 
    738         The 'data' argument can be any object type that compile() supports.
    739         """
    740         return _bootstrap._call_with_frames_removed(compile, data, path, 'exec',
    741                                         dont_inherit=True, optimize=_optimize)
    742 
    743     def get_code(self, fullname):
    744         """Concrete implementation of InspectLoader.get_code.
    745 
    746         Reading of bytecode requires path_stats to be implemented. To write
    747         bytecode, set_data must also be implemented.
    748 
    749         """
    750         source_path = self.get_filename(fullname)
    751         source_mtime = None
    752         try:
    753             bytecode_path = cache_from_source(source_path)
    754         except NotImplementedError:
    755             bytecode_path = None
    756         else:
    757             try:
    758                 st = self.path_stats(source_path)
    759             except IOError:
    760                 pass
    761             else:
    762                 source_mtime = int(st['mtime'])
    763                 try:
    764                     data = self.get_data(bytecode_path)
    765                 except OSError:
    766                     pass
    767                 else:
    768                     try:
    769                         bytes_data = _validate_bytecode_header(data,
    770                                 source_stats=st, name=fullname,
    771                                 path=bytecode_path)
    772                     except (ImportError, EOFError):
    773                         pass
    774                     else:
    775                         _bootstrap._verbose_message('{} matches {}', bytecode_path,
    776                                                     source_path)
    777                         return _compile_bytecode(bytes_data, name=fullname,
    778                                                  bytecode_path=bytecode_path,
    779                                                  source_path=source_path)
    780         source_bytes = self.get_data(source_path)
    781         code_object = self.source_to_code(source_bytes, source_path)
    782         _bootstrap._verbose_message('code object from {}', source_path)
    783         if (not sys.dont_write_bytecode and bytecode_path is not None and
    784                 source_mtime is not None):
    785             data = _code_to_bytecode(code_object, source_mtime,
    786                     len(source_bytes))
    787             try:
    788                 self._cache_bytecode(source_path, bytecode_path, data)
    789                 _bootstrap._verbose_message('wrote {!r}', bytecode_path)
    790             except NotImplementedError:
    791                 pass
    792         return code_object
    793 
    794 
    795 class FileLoader:
    796 
    797     """Base file loader class which implements the loader protocol methods that
    798     require file system usage."""
    799 
    800     def __init__(self, fullname, path):
    801         """Cache the module name and the path to the file found by the
    802         finder."""
    803         self.name = fullname
    804         self.path = path
    805 
    806     def __eq__(self, other):
    807         return (self.__class__ == other.__class__ and
    808                 self.__dict__ == other.__dict__)
    809 
    810     def __hash__(self):
    811         return hash(self.name) ^ hash(self.path)
    812 
    813     @_check_name
    814     def load_module(self, fullname):
    815         """Load a module from a file.
    816 
    817         This method is deprecated.  Use exec_module() instead.
    818 
    819         """
    820         # The only reason for this method is for the name check.
    821         # Issue #14857: Avoid the zero-argument form of super so the implementation
    822         # of that form can be updated without breaking the frozen module
    823         return super(FileLoader, self).load_module(fullname)
    824 
    825     @_check_name
    826     def get_filename(self, fullname):
    827         """Return the path to the source file as found by the finder."""
    828         return self.path
    829 
    830     def get_data(self, path):
    831         """Return the data from path as raw bytes."""
    832         with _io.FileIO(path, 'r') as file:
    833             return file.read()
    834 
    835 
    836 class SourceFileLoader(FileLoader, SourceLoader):
    837 
    838     """Concrete implementation of SourceLoader using the file system."""
    839 
    840     def path_stats(self, path):
    841         """Return the metadata for the path."""
    842         st = _path_stat(path)
    843         return {'mtime': st.st_mtime, 'size': st.st_size}
    844 
    845     def _cache_bytecode(self, source_path, bytecode_path, data):
    846         # Adapt between the two APIs
    847         mode = _calc_mode(source_path)
    848         return self.set_data(bytecode_path, data, _mode=mode)
    849 
    850     def set_data(self, path, data, *, _mode=0o666):
    851         """Write bytes data to a file."""
    852         parent, filename = _path_split(path)
    853         path_parts = []
    854         # Figure out what directories are missing.
    855         while parent and not _path_isdir(parent):
    856             parent, part = _path_split(parent)
    857             path_parts.append(part)
    858         # Create needed directories.
    859         for part in reversed(path_parts):
    860             parent = _path_join(parent, part)
    861             try:
    862                 _os.mkdir(parent)
    863             except FileExistsError:
    864                 # Probably another Python process already created the dir.
    865                 continue
    866             except OSError as exc:
    867                 # Could be a permission error, read-only filesystem: just forget
    868                 # about writing the data.
    869                 _bootstrap._verbose_message('could not create {!r}: {!r}',
    870                                             parent, exc)
    871                 return
    872         try:
    873             _write_atomic(path, data, _mode)
    874             _bootstrap._verbose_message('created {!r}', path)
    875         except OSError as exc:
    876             # Same as above: just don't write the bytecode.
    877             _bootstrap._verbose_message('could not create {!r}: {!r}', path,
    878                                         exc)
    879 
    880 
    881 class SourcelessFileLoader(FileLoader, _LoaderBasics):
    882 
    883     """Loader which handles sourceless file imports."""
    884 
    885     def get_code(self, fullname):
    886         path = self.get_filename(fullname)
    887         data = self.get_data(path)
    888         bytes_data = _validate_bytecode_header(data, name=fullname, path=path)
    889         return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
    890 
    891     def get_source(self, fullname):
    892         """Return None as there is no source code."""
    893         return None
    894 
    895 
    896 # Filled in by _setup().
    897 EXTENSION_SUFFIXES = []
    898 
    899 
    900 class ExtensionFileLoader(FileLoader, _LoaderBasics):
    901 
    902     """Loader for extension modules.
    903 
    904     The constructor is designed to work with FileFinder.
    905 
    906     """
    907 
    908     def __init__(self, name, path):
    909         self.name = name
    910         self.path = path
    911 
    912     def __eq__(self, other):
    913         return (self.__class__ == other.__class__ and
    914                 self.__dict__ == other.__dict__)
    915 
    916     def __hash__(self):
    917         return hash(self.name) ^ hash(self.path)
    918 
    919     def create_module(self, spec):
    920         """Create an unitialized extension module"""
    921         module = _bootstrap._call_with_frames_removed(
    922             _imp.create_dynamic, spec)
    923         _bootstrap._verbose_message('extension module {!r} loaded from {!r}',
    924                          spec.name, self.path)
    925         return module
    926 
    927     def exec_module(self, module):
    928         """Initialize an extension module"""
    929         _bootstrap._call_with_frames_removed(_imp.exec_dynamic, module)
    930         _bootstrap._verbose_message('extension module {!r} executed from {!r}',
    931                          self.name, self.path)
    932 
    933     def is_package(self, fullname):
    934         """Return True if the extension module is a package."""
    935         file_name = _path_split(self.path)[1]
    936         return any(file_name == '__init__' + suffix
    937                    for suffix in EXTENSION_SUFFIXES)
    938 
    939     def get_code(self, fullname):
    940         """Return None as an extension module cannot create a code object."""
    941         return None
    942 
    943     def get_source(self, fullname):
    944         """Return None as extension modules have no source code."""
    945         return None
    946 
    947     @_check_name
    948     def get_filename(self, fullname):
    949         """Return the path to the source file as found by the finder."""
    950         return self.path
    951 
    952 
    953 class _NamespacePath:
    954     """Represents a namespace package's path.  It uses the module name
    955     to find its parent module, and from there it looks up the parent's
    956     __path__.  When this changes, the module's own path is recomputed,
    957     using path_finder.  For top-level modules, the parent module's path
    958     is sys.path."""
    959 
    960     def __init__(self, name, path, path_finder):
    961         self._name = name
    962         self._path = path
    963         self._last_parent_path = tuple(self._get_parent_path())
    964         self._path_finder = path_finder
    965 
    966     def _find_parent_path_names(self):
    967         """Returns a tuple of (parent-module-name, parent-path-attr-name)"""
    968         parent, dot, me = self._name.rpartition('.')
    969         if dot == '':
    970             # This is a top-level module. sys.path contains the parent path.
    971             return 'sys', 'path'
    972         # Not a top-level module. parent-module.__path__ contains the
    973         #  parent path.
    974         return parent, '__path__'
    975 
    976     def _get_parent_path(self):
    977         parent_module_name, path_attr_name = self._find_parent_path_names()
    978         return getattr(sys.modules[parent_module_name], path_attr_name)
    979 
    980     def _recalculate(self):
    981         # If the parent's path has changed, recalculate _path
    982         parent_path = tuple(self._get_parent_path()) # Make a copy
    983         if parent_path != self._last_parent_path:
    984             spec = self._path_finder(self._name, parent_path)
    985             # Note that no changes are made if a loader is returned, but we
    986             #  do remember the new parent path
    987             if spec is not None and spec.loader is None:
    988                 if spec.submodule_search_locations:
    989                     self._path = spec.submodule_search_locations
    990             self._last_parent_path = parent_path     # Save the copy
    991         return self._path
    992 
    993     def __iter__(self):
    994         return iter(self._recalculate())
    995 
    996     def __setitem__(self, index, path):
    997         self._path[index] = path
    998 
    999     def __len__(self):
   1000         return len(self._recalculate())
   1001 
   1002     def __repr__(self):
   1003         return '_NamespacePath({!r})'.format(self._path)
   1004 
   1005     def __contains__(self, item):
   1006         return item in self._recalculate()
   1007 
   1008     def append(self, item):
   1009         self._path.append(item)
   1010 
   1011 
   1012 # We use this exclusively in module_from_spec() for backward-compatibility.
   1013 class _NamespaceLoader:
   1014     def __init__(self, name, path, path_finder):
   1015         self._path = _NamespacePath(name, path, path_finder)
   1016 
   1017     @classmethod
   1018     def module_repr(cls, module):
   1019         """Return repr for the module.
   1020 
   1021         The method is deprecated.  The import machinery does the job itself.
   1022 
   1023         """
   1024         return '<module {!r} (namespace)>'.format(module.__name__)
   1025 
   1026     def is_package(self, fullname):
   1027         return True
   1028 
   1029     def get_source(self, fullname):
   1030         return ''
   1031 
   1032     def get_code(self, fullname):
   1033         return compile('', '<string>', 'exec', dont_inherit=True)
   1034 
   1035     def create_module(self, spec):
   1036         """Use default semantics for module creation."""
   1037 
   1038     def exec_module(self, module):
   1039         pass
   1040 
   1041     def load_module(self, fullname):
   1042         """Load a namespace module.
   1043 
   1044         This method is deprecated.  Use exec_module() instead.
   1045 
   1046         """
   1047         # The import system never calls this method.
   1048         _bootstrap._verbose_message('namespace module loaded with path {!r}',
   1049                                     self._path)
   1050         return _bootstrap._load_module_shim(self, fullname)
   1051 
   1052 
   1053 # Finders #####################################################################
   1054 
   1055 class PathFinder:
   1056 
   1057     """Meta path finder for sys.path and package __path__ attributes."""
   1058 
   1059     @classmethod
   1060     def invalidate_caches(cls):
   1061         """Call the invalidate_caches() method on all path entry finders
   1062         stored in sys.path_importer_caches (where implemented)."""
   1063         for finder in sys.path_importer_cache.values():
   1064             if hasattr(finder, 'invalidate_caches'):
   1065                 finder.invalidate_caches()
   1066 
   1067     @classmethod
   1068     def _path_hooks(cls, path):
   1069         """Search sys.path_hooks for a finder for 'path'."""
   1070         if sys.path_hooks is not None and not sys.path_hooks:
   1071             _warnings.warn('sys.path_hooks is empty', ImportWarning)
   1072         for hook in sys.path_hooks:
   1073             try:
   1074                 return hook(path)
   1075             except ImportError:
   1076                 continue
   1077         else:
   1078             return None
   1079 
   1080     @classmethod
   1081     def _path_importer_cache(cls, path):
   1082         """Get the finder for the path entry from sys.path_importer_cache.
   1083 
   1084         If the path entry is not in the cache, find the appropriate finder
   1085         and cache it. If no finder is available, store None.
   1086 
   1087         """
   1088         if path == '':
   1089             try:
   1090                 path = _os.getcwd()
   1091             except FileNotFoundError:
   1092                 # Don't cache the failure as the cwd can easily change to
   1093                 # a valid directory later on.
   1094                 return None
   1095         try:
   1096             finder = sys.path_importer_cache[path]
   1097         except KeyError:
   1098             finder = cls._path_hooks(path)
   1099             sys.path_importer_cache[path] = finder
   1100         return finder
   1101 
   1102     @classmethod
   1103     def _legacy_get_spec(cls, fullname, finder):
   1104         # This would be a good place for a DeprecationWarning if
   1105         # we ended up going that route.
   1106         if hasattr(finder, 'find_loader'):
   1107             loader, portions = finder.find_loader(fullname)
   1108         else:
   1109             loader = finder.find_module(fullname)
   1110             portions = []
   1111         if loader is not None:
   1112             return _bootstrap.spec_from_loader(fullname, loader)
   1113         spec = _bootstrap.ModuleSpec(fullname, None)
   1114         spec.submodule_search_locations = portions
   1115         return spec
   1116 
   1117     @classmethod
   1118     def _get_spec(cls, fullname, path, target=None):
   1119         """Find the loader or namespace_path for this module/package name."""
   1120         # If this ends up being a namespace package, namespace_path is
   1121         #  the list of paths that will become its __path__
   1122         namespace_path = []
   1123         for entry in path:
   1124             if not isinstance(entry, (str, bytes)):
   1125                 continue
   1126             finder = cls._path_importer_cache(entry)
   1127             if finder is not None:
   1128                 if hasattr(finder, 'find_spec'):
   1129                     spec = finder.find_spec(fullname, target)
   1130                 else:
   1131                     spec = cls._legacy_get_spec(fullname, finder)
   1132                 if spec is None:
   1133                     continue
   1134                 if spec.loader is not None:
   1135                     return spec
   1136                 portions = spec.submodule_search_locations
   1137                 if portions is None:
   1138                     raise ImportError('spec missing loader')
   1139                 # This is possibly part of a namespace package.
   1140                 #  Remember these path entries (if any) for when we
   1141                 #  create a namespace package, and continue iterating
   1142                 #  on path.
   1143                 namespace_path.extend(portions)
   1144         else:
   1145             spec = _bootstrap.ModuleSpec(fullname, None)
   1146             spec.submodule_search_locations = namespace_path
   1147             return spec
   1148 
   1149     @classmethod
   1150     def find_spec(cls, fullname, path=None, target=None):
   1151         """Try to find a spec for 'fullname' on sys.path or 'path'.
   1152 
   1153         The search is based on sys.path_hooks and sys.path_importer_cache.
   1154         """
   1155         if path is None:
   1156             path = sys.path
   1157         spec = cls._get_spec(fullname, path, target)
   1158         if spec is None:
   1159             return None
   1160         elif spec.loader is None:
   1161             namespace_path = spec.submodule_search_locations
   1162             if namespace_path:
   1163                 # We found at least one namespace path.  Return a
   1164                 #  spec which can create the namespace package.
   1165                 spec.origin = 'namespace'
   1166                 spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec)
   1167                 return spec
   1168             else:
   1169                 return None
   1170         else:
   1171             return spec
   1172 
   1173     @classmethod
   1174     def find_module(cls, fullname, path=None):
   1175         """find the module on sys.path or 'path' based on sys.path_hooks and
   1176         sys.path_importer_cache.
   1177 
   1178         This method is deprecated.  Use find_spec() instead.
   1179 
   1180         """
   1181         spec = cls.find_spec(fullname, path)
   1182         if spec is None:
   1183             return None
   1184         return spec.loader
   1185 
   1186 
   1187 class FileFinder:
   1188 
   1189     """File-based finder.
   1190 
   1191     Interactions with the file system are cached for performance, being
   1192     refreshed when the directory the finder is handling has been modified.
   1193 
   1194     """
   1195 
   1196     def __init__(self, path, *loader_details):
   1197         """Initialize with the path to search on and a variable number of
   1198         2-tuples containing the loader and the file suffixes the loader
   1199         recognizes."""
   1200         loaders = []
   1201         for loader, suffixes in loader_details:
   1202             loaders.extend((suffix, loader) for suffix in suffixes)
   1203         self._loaders = loaders
   1204         # Base (directory) path
   1205         self.path = path or '.'
   1206         self._path_mtime = -1
   1207         self._path_cache = set()
   1208         self._relaxed_path_cache = set()
   1209 
   1210     def invalidate_caches(self):
   1211         """Invalidate the directory mtime."""
   1212         self._path_mtime = -1
   1213 
   1214     find_module = _find_module_shim
   1215 
   1216     def find_loader(self, fullname):
   1217         """Try to find a loader for the specified module, or the namespace
   1218         package portions. Returns (loader, list-of-portions).
   1219 
   1220         This method is deprecated.  Use find_spec() instead.
   1221 
   1222         """
   1223         spec = self.find_spec(fullname)
   1224         if spec is None:
   1225             return None, []
   1226         return spec.loader, spec.submodule_search_locations or []
   1227 
   1228     def _get_spec(self, loader_class, fullname, path, smsl, target):
   1229         loader = loader_class(fullname, path)
   1230         return spec_from_file_location(fullname, path, loader=loader,
   1231                                        submodule_search_locations=smsl)
   1232 
   1233     def find_spec(self, fullname, target=None):
   1234         """Try to find a spec for the specified module.
   1235 
   1236         Returns the matching spec, or None if not found.
   1237         """
   1238         is_namespace = False
   1239         tail_module = fullname.rpartition('.')[2]
   1240         try:
   1241             mtime = _path_stat(self.path or _os.getcwd()).st_mtime
   1242         except OSError:
   1243             mtime = -1
   1244         if mtime != self._path_mtime:
   1245             self._fill_cache()
   1246             self._path_mtime = mtime
   1247         # tail_module keeps the original casing, for __file__ and friends
   1248         if _relax_case():
   1249             cache = self._relaxed_path_cache
   1250             cache_module = tail_module.lower()
   1251         else:
   1252             cache = self._path_cache
   1253             cache_module = tail_module
   1254         # Check if the module is the name of a directory (and thus a package).
   1255         if cache_module in cache:
   1256             base_path = _path_join(self.path, tail_module)
   1257             for suffix, loader_class in self._loaders:
   1258                 init_filename = '__init__' + suffix
   1259                 full_path = _path_join(base_path, init_filename)
   1260                 if _path_isfile(full_path):
   1261                     return self._get_spec(loader_class, fullname, full_path, [base_path], target)
   1262             else:
   1263                 # If a namespace package, return the path if we don't
   1264                 #  find a module in the next section.
   1265                 is_namespace = _path_isdir(base_path)
   1266         # Check for a file w/ a proper suffix exists.
   1267         for suffix, loader_class in self._loaders:
   1268             full_path = _path_join(self.path, tail_module + suffix)
   1269             _bootstrap._verbose_message('trying {}', full_path, verbosity=2)
   1270             if cache_module + suffix in cache:
   1271                 if _path_isfile(full_path):
   1272                     return self._get_spec(loader_class, fullname, full_path,
   1273                                           None, target)
   1274         if is_namespace:
   1275             _bootstrap._verbose_message('possible namespace for {}', base_path)
   1276             spec = _bootstrap.ModuleSpec(fullname, None)
   1277             spec.submodule_search_locations = [base_path]
   1278             return spec
   1279         return None
   1280 
   1281     def _fill_cache(self):
   1282         """Fill the cache of potential modules and packages for this directory."""
   1283         path = self.path
   1284         try:
   1285             contents = _os.listdir(path or _os.getcwd())
   1286         except (FileNotFoundError, PermissionError, NotADirectoryError):
   1287             # Directory has either been removed, turned into a file, or made
   1288             # unreadable.
   1289             contents = []
   1290         # We store two cached versions, to handle runtime changes of the
   1291         # PYTHONCASEOK environment variable.
   1292         if not sys.platform.startswith('win'):
   1293             self._path_cache = set(contents)
   1294         else:
   1295             # Windows users can import modules with case-insensitive file
   1296             # suffixes (for legacy reasons). Make the suffix lowercase here
   1297             # so it's done once instead of for every import. This is safe as
   1298             # the specified suffixes to check against are always specified in a
   1299             # case-sensitive manner.
   1300             lower_suffix_contents = set()
   1301             for item in contents:
   1302                 name, dot, suffix = item.partition('.')
   1303                 if dot:
   1304                     new_name = '{}.{}'.format(name, suffix.lower())
   1305                 else:
   1306                     new_name = name
   1307                 lower_suffix_contents.add(new_name)
   1308             self._path_cache = lower_suffix_contents
   1309         if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
   1310             self._relaxed_path_cache = {fn.lower() for fn in contents}
   1311 
   1312     @classmethod
   1313     def path_hook(cls, *loader_details):
   1314         """A class method which returns a closure to use on sys.path_hook
   1315         which will return an instance using the specified loaders and the path
   1316         called on the closure.
   1317 
   1318         If the path called on the closure is not a directory, ImportError is
   1319         raised.
   1320 
   1321         """
   1322         def path_hook_for_FileFinder(path):
   1323             """Path hook for importlib.machinery.FileFinder."""
   1324             if not _path_isdir(path):
   1325                 raise ImportError('only directories are supported', path=path)
   1326             return cls(path, *loader_details)
   1327 
   1328         return path_hook_for_FileFinder
   1329 
   1330     def __repr__(self):
   1331         return 'FileFinder({!r})'.format(self.path)
   1332 
   1333 
   1334 # Import setup ###############################################################
   1335 
   1336 def _fix_up_module(ns, name, pathname, cpathname=None):
   1337     # This function is used by PyImport_ExecCodeModuleObject().
   1338     loader = ns.get('__loader__')
   1339     spec = ns.get('__spec__')
   1340     if not loader:
   1341         if spec:
   1342             loader = spec.loader
   1343         elif pathname == cpathname:
   1344             loader = SourcelessFileLoader(name, pathname)
   1345         else:
   1346             loader = SourceFileLoader(name, pathname)
   1347     if not spec:
   1348         spec = spec_from_file_location(name, pathname, loader=loader)
   1349     try:
   1350         ns['__spec__'] = spec
   1351         ns['__loader__'] = loader
   1352         ns['__file__'] = pathname
   1353         ns['__cached__'] = cpathname
   1354     except Exception:
   1355         # Not important enough to report.
   1356         pass
   1357 
   1358 
   1359 def _get_supported_file_loaders():
   1360     """Returns a list of file-based module loaders.
   1361 
   1362     Each item is a tuple (loader, suffixes).
   1363     """
   1364     extensions = ExtensionFileLoader, _imp.extension_suffixes()
   1365     source = SourceFileLoader, SOURCE_SUFFIXES
   1366     bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
   1367     return [extensions, source, bytecode]
   1368 
   1369 
   1370 def _setup(_bootstrap_module):
   1371     """Setup the path-based importers for importlib by importing needed
   1372     built-in modules and injecting them into the global namespace.
   1373 
   1374     Other components are extracted from the core bootstrap module.
   1375 
   1376     """
   1377     global sys, _imp, _bootstrap
   1378     _bootstrap = _bootstrap_module
   1379     sys = _bootstrap.sys
   1380     _imp = _bootstrap._imp
   1381 
   1382     # Directly load built-in modules needed during bootstrap.
   1383     self_module = sys.modules[__name__]
   1384     for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'):
   1385         if builtin_name not in sys.modules:
   1386             builtin_module = _bootstrap._builtin_from_name(builtin_name)
   1387         else:
   1388             builtin_module = sys.modules[builtin_name]
   1389         setattr(self_module, builtin_name, builtin_module)
   1390 
   1391     # Directly load the os module (needed during bootstrap).
   1392     os_details = ('posix', ['/']), ('nt', ['\\', '/'])
   1393     for builtin_os, path_separators in os_details:
   1394         # Assumption made in _path_join()
   1395         assert all(len(sep) == 1 for sep in path_separators)
   1396         path_sep = path_separators[0]
   1397         if builtin_os in sys.modules:
   1398             os_module = sys.modules[builtin_os]
   1399             break
   1400         else:
   1401             try:
   1402                 os_module = _bootstrap._builtin_from_name(builtin_os)
   1403                 break
   1404             except ImportError:
   1405                 continue
   1406     else:
   1407         raise ImportError('importlib requires posix or nt')
   1408     setattr(self_module, '_os', os_module)
   1409     setattr(self_module, 'path_sep', path_sep)
   1410     setattr(self_module, 'path_separators', ''.join(path_separators))
   1411 
   1412     # Directly load the _thread module (needed during bootstrap).
   1413     try:
   1414         thread_module = _bootstrap._builtin_from_name('_thread')
   1415     except ImportError:
   1416         # Python was built without threads
   1417         thread_module = None
   1418     setattr(self_module, '_thread', thread_module)
   1419 
   1420     # Directly load the _weakref module (needed during bootstrap).
   1421     weakref_module = _bootstrap._builtin_from_name('_weakref')
   1422     setattr(self_module, '_weakref', weakref_module)
   1423 
   1424     # Directly load the winreg module (needed during bootstrap).
   1425     if builtin_os == 'nt':
   1426         winreg_module = _bootstrap._builtin_from_name('winreg')
   1427         setattr(self_module, '_winreg', winreg_module)
   1428 
   1429     # Constants
   1430     setattr(self_module, '_relax_case', _make_relax_case())
   1431     EXTENSION_SUFFIXES.extend(_imp.extension_suffixes())
   1432     if builtin_os == 'nt':
   1433         SOURCE_SUFFIXES.append('.pyw')
   1434         if '_d.pyd' in EXTENSION_SUFFIXES:
   1435             WindowsRegistryFinder.DEBUG_BUILD = True
   1436 
   1437 
   1438 def _install(_bootstrap_module):
   1439     """Install the path-based import components."""
   1440     _setup(_bootstrap_module)
   1441     supported_loaders = _get_supported_file_loaders()
   1442     sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
   1443     sys.meta_path.append(PathFinder)
   1444