File: test_features.py

package info (click to toggle)
pillow 12.1.0-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 72,560 kB
  • sloc: python: 49,748; ansic: 38,748; makefile: 302; sh: 168; javascript: 85
file content (161 lines) | stat: -rw-r--r-- 5,116 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
from __future__ import annotations

import io
import re

import pytest

from PIL import features

from .helper import skip_unless_feature

TYPE_CHECKING = False
if TYPE_CHECKING:
    from collections.abc import Callable


def test_check() -> None:
    # Check the correctness of the convenience function
    for module in features.modules:
        assert features.check_module(module) == features.check(module)
    for codec in features.codecs:
        assert features.check_codec(codec) == features.check(codec)
    for feature in features.features:
        assert features.check_feature(feature) == features.check(feature)


def test_version() -> None:
    # Check the correctness of the convenience function
    # and the format of version numbers

    def test(name: str, function: Callable[[str], str | None]) -> None:
        version = features.version(name)
        if not features.check(name):
            assert version is None
        else:
            assert function(name) == version
            if name != "PIL":
                if version is not None:
                    if name == "zlib" and features.check_feature("zlib_ng"):
                        version = re.sub(".zlib-ng$", "", version)
                    elif name == "libtiff":
                        version = re.sub("t$", "", version)
                assert version is None or re.search(r"\d+(\.\d+)*$", version)

    for module in features.modules:
        test(module, features.version_module)
    for codec in features.codecs:
        test(codec, features.version_codec)
    for feature in features.features:
        test(feature, features.version_feature)


@skip_unless_feature("libjpeg_turbo")
def test_libjpeg_turbo_version() -> None:
    version = features.version("libjpeg_turbo")
    assert version is not None
    assert re.search(r"\d+\.\d+\.\d+$", version)


@skip_unless_feature("libimagequant")
def test_libimagequant_version() -> None:
    version = features.version("libimagequant")
    assert version is not None
    assert re.search(r"\d+\.\d+\.\d+$", version)


@pytest.mark.parametrize("feature", features.modules)
def test_check_modules(feature: str) -> None:
    assert features.check_module(feature) in [True, False]


@pytest.mark.parametrize("feature", features.codecs)
def test_check_codecs(feature: str) -> None:
    assert features.check_codec(feature) in [True, False]


def test_check_warns_on_nonexistent() -> None:
    with pytest.warns(UserWarning, match="Unknown feature 'typo'."):
        has_feature = features.check("typo")
    assert has_feature is False


def test_supported_modules() -> None:
    assert isinstance(features.get_supported_modules(), list)
    assert isinstance(features.get_supported_codecs(), list)
    assert isinstance(features.get_supported_features(), list)
    assert isinstance(features.get_supported(), list)


def test_unsupported_codec() -> None:
    # Arrange
    codec = "unsupported_codec"
    # Act / Assert
    with pytest.raises(ValueError):
        features.check_codec(codec)
    with pytest.raises(ValueError):
        features.version_codec(codec)


def test_unsupported_module() -> None:
    # Arrange
    module = "unsupported_module"
    # Act / Assert
    with pytest.raises(ValueError):
        features.check_module(module)
    with pytest.raises(ValueError):
        features.version_module(module)


def test_unsupported_feature() -> None:
    # Arrange
    feature = "unsupported_feature"
    # Act / Assert
    with pytest.raises(ValueError):
        features.check_feature(feature)
    with pytest.raises(ValueError):
        features.version_feature(feature)


def test_unsupported_version() -> None:
    assert features.version("unsupported_version") is None


def test_modulenotfound(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(features, "features", {"test": ("PIL._test", "", "")})
    assert features.check_feature("test") is None


@pytest.mark.parametrize("supported_formats", (True, False))
def test_pilinfo(supported_formats: bool) -> None:
    buf = io.StringIO()
    features.pilinfo(buf, supported_formats=supported_formats)
    out = buf.getvalue()
    lines = out.splitlines()
    assert lines[0] == "-" * 68
    assert lines[1].startswith("Pillow ")
    assert lines[2].startswith("Python ")
    lines = lines[3:]
    while lines[0].startswith("    "):
        lines = lines[1:]
    assert lines[0] == "-" * 68
    assert lines[1].startswith("Python executable is")
    lines = lines[2:]
    if lines[0].startswith("Environment Python files loaded from"):
        lines = lines[1:]
    assert lines[0].startswith("System Python files loaded from")
    assert lines[1] == "-" * 68
    assert lines[2].startswith("Python Pillow modules loaded from ")
    assert lines[3].startswith("Binary Pillow modules loaded from ")
    assert lines[4] == "-" * 68
    jpeg = (
        "\n"
        + "-" * 68
        + "\n"
        + "JPEG image/jpeg\n"
        + "Extensions: .jfif, .jpe, .jpeg, .jpg\n"
        + "Features: open, save\n"
        + "-" * 68
        + "\n"
    )
    assert supported_formats == (jpeg in out)