1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 pythonOlder,
6 fetchFromGitHub,
7
8 # build-system
9 setuptools,
10 pkg-config,
11
12 # native dependencies
13 freetype,
14 lcms2,
15 libavif,
16 libimagequant,
17 libjpeg,
18 libraqm,
19 libtiff,
20 libwebp,
21 libxcb,
22 openjpeg,
23 zlib-ng,
24
25 # optional dependencies
26 defusedxml,
27 olefile,
28 typing-extensions,
29
30 # tests
31 numpy,
32 pytest-cov-stub,
33 pytestCheckHook,
34
35 # for passthru.tests
36 imageio,
37 matplotlib,
38 pilkit,
39 pydicom,
40 reportlab,
41 sage,
42}:
43
44buildPythonPackage rec {
45 pname = "pillow";
46 version = "11.2.1";
47 pyproject = true;
48
49 src = fetchFromGitHub {
50 owner = "python-pillow";
51 repo = "pillow";
52 tag = version;
53 hash = "sha256-eInPpCxHvo9J45t52KXZDG4KH4yf7iNMb+FpH5SEWmE=";
54 };
55
56 build-system = [ setuptools ];
57
58 nativeBuildInputs = [ pkg-config ];
59
60 # https://pillow.readthedocs.io/en/latest/installation/building-from-source.html#building-from-source
61 buildInputs = [
62 freetype
63 lcms2
64 libavif
65 libimagequant
66 libjpeg
67 libraqm
68 libtiff
69 libwebp
70 libxcb
71 openjpeg
72 zlib-ng
73 ];
74
75 pypaBuildFlags = [
76 # Disable platform guessing, which tries various FHS paths
77 "--config=setting=--disable-platform-guessing"
78 ];
79
80 preConfigure =
81 let
82 getLibAndInclude = pkg: ''"${pkg.out}/lib", "${lib.getDev pkg}/include"'';
83 in
84 ''
85 # The build process fails to find the pkg-config files for these dependencies
86 substituteInPlace setup.py \
87 --replace-fail 'AVIF_ROOT = None' 'AVIF_ROOT = ${getLibAndInclude libavif}' \
88 --replace-fail 'IMAGEQUANT_ROOT = None' 'IMAGEQUANT_ROOT = ${getLibAndInclude libimagequant}' \
89 --replace-fail 'JPEG2K_ROOT = None' 'JPEG2K_ROOT = ${getLibAndInclude openjpeg}'
90
91 # Build with X11 support
92 export LDFLAGS="$LDFLAGS -L${libxcb}/lib"
93 export CFLAGS="$CFLAGS -I${libxcb.dev}/include"
94 '';
95
96 optional-dependencies = {
97 fpx = [ olefile ];
98 mic = [ olefile ];
99 typing = lib.optionals (pythonOlder "3.10") [ typing-extensions ];
100 xmp = [ defusedxml ];
101 };
102
103 nativeCheckInputs = [
104 pytest-cov-stub
105 pytestCheckHook
106 numpy
107 ] ++ lib.flatten (lib.attrValues optional-dependencies);
108
109 pytestFlagsArray = [
110 # Checks for very precise color values on what's basically white
111 "--deselect=Tests/test_file_avif.py::TestFileAvif::test_background_from_gif"
112 ];
113
114 disabledTests =
115 [
116 # Code quality mismathch 9 vs 10
117 "test_pyroma"
118 ]
119 ++ lib.optionals stdenv.hostPlatform.isDarwin [
120 # Disable darwin tests which require executables: `iconutil` and `screencapture`
121 "test_grab"
122 "test_grabclipboard"
123 "test_save"
124 ];
125
126 disabledTestPaths = lib.optionals stdenv.hostPlatform.isDarwin [
127 # Crashes the interpreter
128 "Tests/test_imagetk.py"
129 ];
130
131 passthru.tests = {
132 inherit
133 imageio
134 matplotlib
135 pilkit
136 pydicom
137 reportlab
138 sage
139 ;
140 };
141
142 meta = with lib; {
143 homepage = "https://python-pillow.github.io/";
144 changelog = "https://pillow.readthedocs.io/en/stable/releasenotes/${version}.html";
145 description = "Friendly PIL fork (Python Imaging Library)";
146 longDescription = ''
147 The Python Imaging Library (PIL) adds image processing
148 capabilities to your Python interpreter. This library
149 supports many file formats, and provides powerful image
150 processing and graphics capabilities.
151 '';
152 license = licenses.mit-cmu;
153 maintainers = with maintainers; [ hexa ];
154 };
155
156}