Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/PIL/features.py: 12%

139 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1import collections 

2import os 

3import sys 

4import warnings 

5 

6import PIL 

7 

8from . import Image 

9 

10modules = { 

11 "pil": ("PIL._imaging", "PILLOW_VERSION"), 

12 "tkinter": ("PIL._tkinter_finder", "tk_version"), 

13 "freetype2": ("PIL._imagingft", "freetype2_version"), 

14 "littlecms2": ("PIL._imagingcms", "littlecms_version"), 

15 "webp": ("PIL._webp", "webpdecoder_version"), 

16} 

17 

18 

19def check_module(feature): 

20 """ 

21 Checks if a module is available. 

22 

23 :param feature: The module to check for. 

24 :returns: ``True`` if available, ``False`` otherwise. 

25 :raises ValueError: If the module is not defined in this version of Pillow. 

26 """ 

27 if not (feature in modules): 

28 raise ValueError(f"Unknown module {feature}") 

29 

30 module, ver = modules[feature] 

31 

32 try: 

33 __import__(module) 

34 return True 

35 except ImportError: 

36 return False 

37 

38 

39def version_module(feature): 

40 """ 

41 :param feature: The module to check for. 

42 :returns: 

43 The loaded version number as a string, or ``None`` if unknown or not available. 

44 :raises ValueError: If the module is not defined in this version of Pillow. 

45 """ 

46 if not check_module(feature): 

47 return None 

48 

49 module, ver = modules[feature] 

50 

51 if ver is None: 

52 return None 

53 

54 return getattr(__import__(module, fromlist=[ver]), ver) 

55 

56 

57def get_supported_modules(): 

58 """ 

59 :returns: A list of all supported modules. 

60 """ 

61 return [f for f in modules if check_module(f)] 

62 

63 

64codecs = { 

65 "jpg": ("jpeg", "jpeglib"), 

66 "jpg_2000": ("jpeg2k", "jp2klib"), 

67 "zlib": ("zip", "zlib"), 

68 "libtiff": ("libtiff", "libtiff"), 

69} 

70 

71 

72def check_codec(feature): 

73 """ 

74 Checks if a codec is available. 

75 

76 :param feature: The codec to check for. 

77 :returns: ``True`` if available, ``False`` otherwise. 

78 :raises ValueError: If the codec is not defined in this version of Pillow. 

79 """ 

80 if feature not in codecs: 80 ↛ 81line 80 didn't jump to line 81, because the condition on line 80 was never true

81 raise ValueError(f"Unknown codec {feature}") 

82 

83 codec, lib = codecs[feature] 

84 

85 return codec + "_encoder" in dir(Image.core) 

86 

87 

88def version_codec(feature): 

89 """ 

90 :param feature: The codec to check for. 

91 :returns: 

92 The version number as a string, or ``None`` if not available. 

93 Checked at compile time for ``jpg``, run-time otherwise. 

94 :raises ValueError: If the codec is not defined in this version of Pillow. 

95 """ 

96 if not check_codec(feature): 

97 return None 

98 

99 codec, lib = codecs[feature] 

100 

101 version = getattr(Image.core, lib + "_version") 

102 

103 if feature == "libtiff": 

104 return version.split("\n")[0].split("Version ")[1] 

105 

106 return version 

107 

108 

109def get_supported_codecs(): 

110 """ 

111 :returns: A list of all supported codecs. 

112 """ 

113 return [f for f in codecs if check_codec(f)] 

114 

115 

116features = { 

117 "webp_anim": ("PIL._webp", "HAVE_WEBPANIM", None), 

118 "webp_mux": ("PIL._webp", "HAVE_WEBPMUX", None), 

119 "transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY", None), 

120 "raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"), 

121 "fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"), 

122 "harfbuzz": ("PIL._imagingft", "HAVE_HARFBUZZ", "harfbuzz_version"), 

123 "libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO", "libjpeg_turbo_version"), 

124 "libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT", "imagequant_version"), 

125 "xcb": ("PIL._imaging", "HAVE_XCB", None), 

126} 

127 

128 

129def check_feature(feature): 

130 """ 

131 Checks if a feature is available. 

132 

133 :param feature: The feature to check for. 

134 :returns: ``True`` if available, ``False`` if unavailable, ``None`` if unknown. 

135 :raises ValueError: If the feature is not defined in this version of Pillow. 

136 """ 

137 if feature not in features: 

138 raise ValueError(f"Unknown feature {feature}") 

139 

140 module, flag, ver = features[feature] 

141 

142 try: 

143 imported_module = __import__(module, fromlist=["PIL"]) 

144 return getattr(imported_module, flag) 

145 except ImportError: 

146 return None 

147 

148 

149def version_feature(feature): 

150 """ 

151 :param feature: The feature to check for. 

152 :returns: The version number as a string, or ``None`` if not available. 

153 :raises ValueError: If the feature is not defined in this version of Pillow. 

154 """ 

155 if not check_feature(feature): 

156 return None 

157 

158 module, flag, ver = features[feature] 

159 

160 if ver is None: 

161 return None 

162 

163 return getattr(__import__(module, fromlist=[ver]), ver) 

164 

165 

166def get_supported_features(): 

167 """ 

168 :returns: A list of all supported features. 

169 """ 

170 return [f for f in features if check_feature(f)] 

171 

172 

173def check(feature): 

174 """ 

175 :param feature: A module, codec, or feature name. 

176 :returns: 

177 ``True`` if the module, codec, or feature is available, 

178 ``False`` or ``None`` otherwise. 

179 """ 

180 

181 if feature in modules: 

182 return check_module(feature) 

183 if feature in codecs: 

184 return check_codec(feature) 

185 if feature in features: 

186 return check_feature(feature) 

187 warnings.warn(f"Unknown feature '{feature}'.", stacklevel=2) 

188 return False 

189 

190 

191def version(feature): 

192 """ 

193 :param feature: 

194 The module, codec, or feature to check for. 

195 :returns: 

196 The version number as a string, or ``None`` if unknown or not available. 

197 """ 

198 if feature in modules: 

199 return version_module(feature) 

200 if feature in codecs: 

201 return version_codec(feature) 

202 if feature in features: 

203 return version_feature(feature) 

204 return None 

205 

206 

207def get_supported(): 

208 """ 

209 :returns: A list of all supported modules, features, and codecs. 

210 """ 

211 

212 ret = get_supported_modules() 

213 ret.extend(get_supported_features()) 

214 ret.extend(get_supported_codecs()) 

215 return ret 

216 

217 

218def pilinfo(out=None, supported_formats=True): 

219 """ 

220 Prints information about this installation of Pillow. 

221 This function can be called with ``python3 -m PIL``. 

222 

223 :param out: 

224 The output stream to print to. Defaults to ``sys.stdout`` if ``None``. 

225 :param supported_formats: 

226 If ``True``, a list of all supported image file formats will be printed. 

227 """ 

228 

229 if out is None: 

230 out = sys.stdout 

231 

232 Image.init() 

233 

234 print("-" * 68, file=out) 

235 print(f"Pillow {PIL.__version__}", file=out) 

236 py_version = sys.version.splitlines() 

237 print(f"Python {py_version[0].strip()}", file=out) 

238 for py_version in py_version[1:]: 

239 print(f" {py_version.strip()}", file=out) 

240 print("-" * 68, file=out) 

241 print( 

242 f"Python modules loaded from {os.path.dirname(Image.__file__)}", 

243 file=out, 

244 ) 

245 print( 

246 f"Binary modules loaded from {os.path.dirname(Image.core.__file__)}", 

247 file=out, 

248 ) 

249 print("-" * 68, file=out) 

250 

251 for name, feature in [ 

252 ("pil", "PIL CORE"), 

253 ("tkinter", "TKINTER"), 

254 ("freetype2", "FREETYPE2"), 

255 ("littlecms2", "LITTLECMS2"), 

256 ("webp", "WEBP"), 

257 ("transp_webp", "WEBP Transparency"), 

258 ("webp_mux", "WEBPMUX"), 

259 ("webp_anim", "WEBP Animation"), 

260 ("jpg", "JPEG"), 

261 ("jpg_2000", "OPENJPEG (JPEG2000)"), 

262 ("zlib", "ZLIB (PNG/ZIP)"), 

263 ("libtiff", "LIBTIFF"), 

264 ("raqm", "RAQM (Bidirectional Text)"), 

265 ("libimagequant", "LIBIMAGEQUANT (Quantization method)"), 

266 ("xcb", "XCB (X protocol)"), 

267 ]: 

268 if check(name): 

269 if name == "jpg" and check_feature("libjpeg_turbo"): 

270 v = "libjpeg-turbo " + version_feature("libjpeg_turbo") 

271 else: 

272 v = version(name) 

273 if v is not None: 

274 version_static = name in ("pil", "jpg") 

275 if name == "littlecms2": 

276 # this check is also in src/_imagingcms.c:setup_module() 

277 version_static = tuple(int(x) for x in v.split(".")) < (2, 7) 

278 t = "compiled for" if version_static else "loaded" 

279 if name == "raqm": 

280 for f in ("fribidi", "harfbuzz"): 

281 v2 = version_feature(f) 

282 if v2 is not None: 

283 v += f", {f} {v2}" 

284 print("---", feature, "support ok,", t, v, file=out) 

285 else: 

286 print("---", feature, "support ok", file=out) 

287 else: 

288 print("***", feature, "support not installed", file=out) 

289 print("-" * 68, file=out) 

290 

291 if supported_formats: 

292 extensions = collections.defaultdict(list) 

293 for ext, i in Image.EXTENSION.items(): 

294 extensions[i].append(ext) 

295 

296 for i in sorted(Image.ID): 

297 line = f"{i}" 

298 if i in Image.MIME: 

299 line = f"{line} {Image.MIME[i]}" 

300 print(line, file=out) 

301 

302 if i in extensions: 

303 print( 

304 "Extensions: {}".format(", ".join(sorted(extensions[i]))), file=out 

305 ) 

306 

307 features = [] 

308 if i in Image.OPEN: 

309 features.append("open") 

310 if i in Image.SAVE: 

311 features.append("save") 

312 if i in Image.SAVE_ALL: 

313 features.append("save_all") 

314 if i in Image.DECODERS: 

315 features.append("decode") 

316 if i in Image.ENCODERS: 

317 features.append("encode") 

318 

319 print("Features: {}".format(", ".join(features)), file=out) 

320 print("-" * 68, file=out)