codekingpro/portable-devtools
114k
1
2try:
3 # this works on Python < 3.12
4 from imp import *
5
6except ImportError:
7 # this is a limited emulation for Python >= 3.12.
8 # Note that this is used only for tests or for the old ffi.verify().
9 # This is copied from the source code of Python 3.11.
10
11 from _imp import (acquire_lock, release_lock,
12 is_builtin, is_frozen)
13
14 from importlib._bootstrap import _load
15
16 from importlib import machinery
17 import os
18 import sys
19 import tokenize
20
21 SEARCH_ERROR = 0
22 PY_SOURCE = 1
23 PY_COMPILED = 2
24 C_EXTENSION = 3
25 PY_RESOURCE = 4
26 PKG_DIRECTORY = 5
27 C_BUILTIN = 6
28 PY_FROZEN = 7
29 PY_CODERESOURCE = 8
30 IMP_HOOK = 9
31
32 def get_suffixes():
33 extensions = [(s, 'rb', C_EXTENSION)
34 for s in machinery.EXTENSION_SUFFIXES]
35 source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
36 bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
37 return extensions + source + bytecode
38
39 def find_module(name, path=None):
40 if not isinstance(name, str):
41 raise TypeError("'name' must be a str, not {}".format(type(name)))
42 elif not isinstance(path, (type(None), list)):
43 # Backwards-compatibility
44 raise RuntimeError("'path' must be None or a list, "
45 "not {}".format(type(path)))
46
47 if path is None:
48 if is_builtin(name):
49 return None, None, ('', '', C_BUILTIN)
50 elif is_frozen(name):
51 return None, None, ('', '', PY_FROZEN)
52 else:
53 path = sys.path
54
55 for entry in path:
56 package_directory = os.path.join(entry, name)
57 for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
58 package_file_name = '__init__' + suffix
59 file_path = os.path.join(package_directory, package_file_name)
60 if os.path.isfile(file_path):
61 return None, package_directory, ('', '', PKG_DIRECTORY)
62 for suffix, mode, type_ in get_suffixes():
63 file_name = name + suffix
64 file_path = os.path.join(entry, file_name)
65 if os.path.isfile(file_path):
66 break
67 else:
68 continue
69 break # Break out of outer loop when breaking out of inner loop.
70 else:
71 raise ImportError(name, name=name)
72
73 encoding = None
74 if 'b' not in mode:
75 with open(file_path, 'rb') as file:
76 encoding = tokenize.detect_encoding(file.readline)[0]
77 file = open(file_path, mode, encoding=encoding)
78 return file, file_path, (suffix, mode, type_)
79
80 def load_dynamic(name, path, file=None):
81 loader = machinery.ExtensionFileLoader(name, path)
82 spec = machinery.ModuleSpec(name=name, loader=loader, origin=path)
83 return _load(spec)
84 