ยปCore Development>Code coverage>Lib/importlib/_bootstrap_external.py

Python code coverage for Lib/importlib/_bootstrap_external.py

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