Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/jedi-0.18.2-py3.8.egg/jedi/inference/compiled/subprocess/functions.py: 22%

148 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 07:16 +0000

1import sys 

2import os 

3import inspect 

4import importlib 

5import warnings 

6from pathlib import Path 

7from zipfile import ZipFile 

8from zipimport import zipimporter, ZipImportError 

9from importlib.machinery import all_suffixes 

10 

11from jedi.inference.compiled import access 

12from jedi import debug 

13from jedi import parser_utils 

14from jedi.file_io import KnownContentFileIO, ZipFileIO 

15 

16 

17def get_sys_path(): 

18 return sys.path 

19 

20 

21def load_module(inference_state, **kwargs): 

22 return access.load_module(inference_state, **kwargs) 

23 

24 

25def get_compiled_method_return(inference_state, id, attribute, *args, **kwargs): 

26 handle = inference_state.compiled_subprocess.get_access_handle(id) 

27 return getattr(handle.access, attribute)(*args, **kwargs) 

28 

29 

30def create_simple_object(inference_state, obj): 

31 return access.create_access_path(inference_state, obj) 

32 

33 

34def get_module_info(inference_state, sys_path=None, full_name=None, **kwargs): 

35 """ 

36 Returns Tuple[Union[NamespaceInfo, FileIO, None], Optional[bool]] 

37 """ 

38 if sys_path is not None: 

39 sys.path, temp = sys_path, sys.path 

40 try: 

41 return _find_module(full_name=full_name, **kwargs) 

42 except ImportError: 

43 return None, None 

44 finally: 

45 if sys_path is not None: 

46 sys.path = temp 

47 

48 

49def get_builtin_module_names(inference_state): 

50 return sys.builtin_module_names 

51 

52 

53def _test_raise_error(inference_state, exception_type): 

54 """ 

55 Raise an error to simulate certain problems for unit tests. 

56 """ 

57 raise exception_type 

58 

59 

60def _test_print(inference_state, stderr=None, stdout=None): 

61 """ 

62 Force some prints in the subprocesses. This exists for unit tests. 

63 """ 

64 if stderr is not None: 

65 print(stderr, file=sys.stderr) 

66 sys.stderr.flush() 

67 if stdout is not None: 

68 print(stdout) 

69 sys.stdout.flush() 

70 

71 

72def _get_init_path(directory_path): 

73 """ 

74 The __init__ file can be searched in a directory. If found return it, else 

75 None. 

76 """ 

77 for suffix in all_suffixes(): 

78 path = os.path.join(directory_path, '__init__' + suffix) 

79 if os.path.exists(path): 

80 return path 

81 return None 

82 

83 

84def safe_literal_eval(inference_state, value): 

85 return parser_utils.safe_literal_eval(value) 

86 

87 

88def iter_module_names(*args, **kwargs): 

89 return list(_iter_module_names(*args, **kwargs)) 

90 

91 

92def _iter_module_names(inference_state, paths): 

93 # Python modules/packages 

94 for path in paths: 

95 try: 

96 dir_entries = ((entry.name, entry.is_dir()) for entry in os.scandir(path)) 

97 except OSError: 

98 try: 

99 zip_import_info = zipimporter(path) 

100 # Unfortunately, there is no public way to access zipimporter's 

101 # private _files member. We therefore have to use a 

102 # custom function to iterate over the files. 

103 dir_entries = _zip_list_subdirectory( 

104 zip_import_info.archive, zip_import_info.prefix) 

105 except ZipImportError: 

106 # The file might not exist or reading it might lead to an error. 

107 debug.warning("Not possible to list directory: %s", path) 

108 continue 

109 for name, is_dir in dir_entries: 

110 # First Namespaces then modules/stubs 

111 if is_dir: 

112 # pycache is obviously not an interesting namespace. Also the 

113 # name must be a valid identifier. 

114 if name != '__pycache__' and name.isidentifier(): 

115 yield name 

116 else: 

117 if name.endswith('.pyi'): # Stub files 

118 modname = name[:-4] 

119 else: 

120 modname = inspect.getmodulename(name) 

121 

122 if modname and '.' not in modname: 

123 if modname != '__init__': 

124 yield modname 

125 

126 

127def _find_module(string, path=None, full_name=None, is_global_search=True): 

128 """ 

129 Provides information about a module. 

130 

131 This function isolates the differences in importing libraries introduced with 

132 python 3.3 on; it gets a module name and optionally a path. It will return a 

133 tuple containin an open file for the module (if not builtin), the filename 

134 or the name of the module if it is a builtin one and a boolean indicating 

135 if the module is contained in a package. 

136 """ 

137 spec = None 

138 loader = None 

139 

140 for finder in sys.meta_path: 

141 if is_global_search and finder != importlib.machinery.PathFinder: 

142 p = None 

143 else: 

144 p = path 

145 try: 

146 find_spec = finder.find_spec 

147 except AttributeError: 

148 # These are old-school clases that still have a different API, just 

149 # ignore those. 

150 continue 

151 

152 spec = find_spec(string, p) 

153 if spec is not None: 

154 if spec.origin == "frozen": 

155 continue 

156 

157 loader = spec.loader 

158 

159 if loader is None and not spec.has_location: 

160 # This is a namespace package. 

161 full_name = string if not path else full_name 

162 implicit_ns_info = ImplicitNSInfo(full_name, spec.submodule_search_locations._path) 

163 return implicit_ns_info, True 

164 break 

165 

166 return _find_module_py33(string, path, loader) 

167 

168 

169def _find_module_py33(string, path=None, loader=None, full_name=None, is_global_search=True): 

170 loader = loader or importlib.machinery.PathFinder.find_module(string, path) 

171 

172 if loader is None and path is None: # Fallback to find builtins 

173 try: 

174 with warnings.catch_warnings(record=True): 

175 # Mute "DeprecationWarning: Use importlib.util.find_spec() 

176 # instead." While we should replace that in the future, it's 

177 # probably good to wait until we deprecate Python 3.3, since 

178 # it was added in Python 3.4 and find_loader hasn't been 

179 # removed in 3.6. 

180 loader = importlib.find_loader(string) 

181 except ValueError as e: 

182 # See #491. Importlib might raise a ValueError, to avoid this, we 

183 # just raise an ImportError to fix the issue. 

184 raise ImportError("Originally " + repr(e)) 

185 

186 if loader is None: 

187 raise ImportError("Couldn't find a loader for {}".format(string)) 

188 

189 return _from_loader(loader, string) 

190 

191 

192def _from_loader(loader, string): 

193 try: 

194 is_package_method = loader.is_package 

195 except AttributeError: 

196 is_package = False 

197 else: 

198 is_package = is_package_method(string) 

199 try: 

200 get_filename = loader.get_filename 

201 except AttributeError: 

202 return None, is_package 

203 else: 

204 module_path = get_filename(string) 

205 

206 # To avoid unicode and read bytes, "overwrite" loader.get_source if 

207 # possible. 

208 try: 

209 f = type(loader).get_source 

210 except AttributeError: 

211 raise ImportError("get_source was not defined on loader") 

212 

213 if f is not importlib.machinery.SourceFileLoader.get_source: 

214 # Unfortunately we are reading unicode here, not bytes. 

215 # It seems hard to get bytes, because the zip importer 

216 # logic just unpacks the zip file and returns a file descriptor 

217 # that we cannot as easily access. Therefore we just read it as 

218 # a string in the cases where get_source was overwritten. 

219 code = loader.get_source(string) 

220 else: 

221 code = _get_source(loader, string) 

222 

223 if code is None: 

224 return None, is_package 

225 if isinstance(loader, zipimporter): 

226 return ZipFileIO(module_path, code, Path(loader.archive)), is_package 

227 

228 return KnownContentFileIO(module_path, code), is_package 

229 

230 

231def _get_source(loader, fullname): 

232 """ 

233 This method is here as a replacement for SourceLoader.get_source. That 

234 method returns unicode, but we prefer bytes. 

235 """ 

236 path = loader.get_filename(fullname) 

237 try: 

238 return loader.get_data(path) 

239 except OSError: 

240 raise ImportError('source not available through get_data()', 

241 name=fullname) 

242 

243 

244def _zip_list_subdirectory(zip_path, zip_subdir_path): 

245 zip_file = ZipFile(zip_path) 

246 zip_subdir_path = Path(zip_subdir_path) 

247 zip_content_file_paths = zip_file.namelist() 

248 for raw_file_name in zip_content_file_paths: 

249 file_path = Path(raw_file_name) 

250 if file_path.parent == zip_subdir_path: 

251 file_path = file_path.relative_to(zip_subdir_path) 

252 yield file_path.name, raw_file_name.endswith("/") 

253 

254 

255class ImplicitNSInfo: 

256 """Stores information returned from an implicit namespace spec""" 

257 def __init__(self, name, paths): 

258 self.name = name 

259 self.paths = paths