Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/jedi-0.20.0-py3.11.egg/jedi/inference/compiled/subprocess/functions.py: 21%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

151 statements  

1import sys 

2import os 

3import inspect 

4import importlib 

5from pathlib import Path 

6from zipfile import ZipFile 

7from zipimport import zipimporter, ZipImportError 

8from importlib.machinery import all_suffixes 

9 

10from jedi.inference.compiled import access 

11from jedi import debug 

12from jedi import parser_utils 

13from jedi.file_io import KnownContentFileIO, ZipFileIO 

14 

15 

16def get_sys_path(): 

17 return sys.path 

18 

19 

20def load_module(inference_state, **kwargs): 

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

22 

23 

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

25 handle = inference_state.compiled_subprocess.get_access_handle(id) 

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

27 

28 

29def create_simple_object(inference_state, obj): 

30 return access.create_access_path(inference_state, obj) 

31 

32 

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

34 """ 

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

36 """ 

37 if sys_path is not None: 

38 sys.path, temp = sys_path, sys.path 

39 try: 

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

41 except ImportError: 

42 return None, None 

43 finally: 

44 if sys_path is not None: 

45 sys.path = temp 

46 

47 

48def get_builtin_module_names(inference_state): 

49 return sys.builtin_module_names 

50 

51 

52def _test_raise_error(inference_state, exception_type): 

53 """ 

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

55 """ 

56 raise exception_type 

57 

58 

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

60 """ 

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

62 """ 

63 if stderr is not None: 

64 print(stderr, file=sys.stderr) 

65 sys.stderr.flush() 

66 if stdout is not None: 

67 print(stdout) 

68 sys.stdout.flush() 

69 

70 

71def _get_init_path(directory_path): 

72 """ 

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

74 None. 

75 """ 

76 for suffix in all_suffixes(): 

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

78 if os.path.exists(path): 

79 return path 

80 return None 

81 

82 

83def safe_literal_eval(inference_state, value): 

84 return parser_utils.safe_literal_eval(value) 

85 

86 

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

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

89 

90 

91def _iter_module_names(inference_state, paths): 

92 # Python modules/packages 

93 for path in paths: 

94 try: 

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

96 except OSError: 

97 try: 

98 zip_import_info = zipimporter(path) 

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

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

101 # custom function to iterate over the files. 

102 dir_entries = _zip_list_subdirectory( 

103 zip_import_info.archive, zip_import_info.prefix) 

104 except ZipImportError: 

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

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

107 continue 

108 for name, is_dir in dir_entries: 

109 # First Namespaces then modules/stubs 

110 if is_dir: 

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

112 # name must be a valid identifier. 

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

114 yield name 

115 else: 

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

117 modname = name[:-4] 

118 else: 

119 modname = inspect.getmodulename(name) 

120 

121 if modname and '.' not in modname: 

122 if modname != '__init__': 

123 yield modname 

124 

125 

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

127 """ 

128 Provides information about a module. 

129 

130 This function isolates the differences in importing libraries introduced with 

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

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

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

134 if the module is contained in a package. 

135 """ 

136 spec = None 

137 loader = None 

138 

139 for finder in sys.meta_path: 

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

141 p = None 

142 else: 

143 p = path 

144 try: 

145 find_spec = finder.find_spec 

146 except AttributeError: 

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

148 # ignore those. 

149 continue 

150 

151 spec = find_spec(string, p) 

152 if spec is not None: 

153 if spec.origin == "frozen": 

154 continue 

155 

156 loader = spec.loader 

157 

158 if loader is None and not spec.has_location: 

159 # This is a namespace package. 

160 full_name = string if not path else full_name 

161 implicit_ns_info = ImplicitNSInfo( 

162 full_name, 

163 spec.submodule_search_locations._path, # type: ignore[union-attr] 

164 ) 

165 return implicit_ns_info, True 

166 break 

167 

168 return _find_module_py33(string, path, loader) 

169 

170 

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

172 if not loader: 

173 spec = importlib.machinery.PathFinder.find_spec(string, path) 

174 if spec is not None: 

175 loader = spec.loader 

176 

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

178 try: 

179 spec = importlib.util.find_spec(string) 

180 if spec is not None: 

181 loader = spec.loader 

182 except ValueError as e: 

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

184 # just raise an ImportError to fix the issue. 

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

186 

187 if loader is None: 

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

189 

190 return _from_loader(loader, string) 

191 

192 

193def _from_loader(loader, string): 

194 try: 

195 is_package_method = loader.is_package 

196 except AttributeError: 

197 is_package = False 

198 else: 

199 is_package = is_package_method(string) 

200 try: 

201 get_filename = loader.get_filename 

202 except AttributeError: 

203 return None, is_package 

204 else: 

205 module_path = get_filename(string) 

206 

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

208 # possible. 

209 try: 

210 f = type(loader).get_source 

211 except AttributeError: 

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

213 

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

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

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

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

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

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

220 code = loader.get_source(string) 

221 else: 

222 code = _get_source(loader, string) 

223 

224 if code is None: 

225 return None, is_package 

226 if isinstance(loader, zipimporter): 

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

228 

229 return KnownContentFileIO(module_path, code), is_package 

230 

231 

232def _get_source(loader, fullname): 

233 """ 

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

235 method returns unicode, but we prefer bytes. 

236 """ 

237 path = loader.get_filename(fullname) 

238 try: 

239 return loader.get_data(path) 

240 except OSError: 

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

242 name=fullname) 

243 

244 

245def _zip_list_subdirectory(zip_path, zip_subdir_path): 

246 zip_file = ZipFile(zip_path) 

247 zip_subdir_path = Path(zip_subdir_path) 

248 zip_content_file_paths = zip_file.namelist() 

249 for raw_file_name in zip_content_file_paths: 

250 file_path = Path(raw_file_name) 

251 if file_path.parent == zip_subdir_path: 

252 file_path = file_path.relative_to(zip_subdir_path) 

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

254 

255 

256class ImplicitNSInfo: 

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

258 def __init__(self, name, paths): 

259 self.name = name 

260 self.paths = paths