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
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import collections
2import os
3import sys
4import warnings
6import PIL
8from . import Image
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}
19def check_module(feature):
20 """
21 Checks if a module is available.
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}")
30 module, ver = modules[feature]
32 try:
33 __import__(module)
34 return True
35 except ImportError:
36 return False
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
49 module, ver = modules[feature]
51 if ver is None:
52 return None
54 return getattr(__import__(module, fromlist=[ver]), ver)
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)]
64codecs = {
65 "jpg": ("jpeg", "jpeglib"),
66 "jpg_2000": ("jpeg2k", "jp2klib"),
67 "zlib": ("zip", "zlib"),
68 "libtiff": ("libtiff", "libtiff"),
69}
72def check_codec(feature):
73 """
74 Checks if a codec is available.
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}")
83 codec, lib = codecs[feature]
85 return codec + "_encoder" in dir(Image.core)
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
99 codec, lib = codecs[feature]
101 version = getattr(Image.core, lib + "_version")
103 if feature == "libtiff":
104 return version.split("\n")[0].split("Version ")[1]
106 return version
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)]
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}
129def check_feature(feature):
130 """
131 Checks if a feature is available.
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}")
140 module, flag, ver = features[feature]
142 try:
143 imported_module = __import__(module, fromlist=["PIL"])
144 return getattr(imported_module, flag)
145 except ImportError:
146 return None
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
158 module, flag, ver = features[feature]
160 if ver is None:
161 return None
163 return getattr(__import__(module, fromlist=[ver]), ver)
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)]
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 """
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
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
207def get_supported():
208 """
209 :returns: A list of all supported modules, features, and codecs.
210 """
212 ret = get_supported_modules()
213 ret.extend(get_supported_features())
214 ret.extend(get_supported_codecs())
215 return ret
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``.
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 """
229 if out is None:
230 out = sys.stdout
232 Image.init()
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)
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)
291 if supported_formats:
292 extensions = collections.defaultdict(list)
293 for ext, i in Image.EXTENSION.items():
294 extensions[i].append(ext)
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)
302 if i in extensions:
303 print(
304 "Extensions: {}".format(", ".join(sorted(extensions[i]))), file=out
305 )
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")
319 print("Features: {}".format(", ".join(features)), file=out)
320 print("-" * 68, file=out)