1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 pythonOlder,
6 fetchFromGitHub,
7 fetchpatch,
8 python,
9
10 # build-system
11 libclang,
12 psutil,
13 setuptools,
14 swig,
15
16 # native dependencies
17 freetype,
18 harfbuzz,
19 openjpeg,
20 jbig2dec,
21 libjpeg_turbo,
22 gumbo,
23
24 # dependencies
25 mupdf,
26
27 # tests
28 pytestCheckHook,
29 fonttools,
30 pillow,
31 pymupdf-fonts,
32}:
33
34let
35 # PyMuPDF needs the C++ bindings generated
36 mupdf-cxx = mupdf.override {
37 enableOcr = true;
38 enableCxx = true;
39 enablePython = true;
40 python3 = python;
41 };
42in
43buildPythonPackage rec {
44 pname = "pymupdf";
45 version = "1.25.2";
46 pyproject = true;
47
48 disabled = pythonOlder "3.7";
49
50 src = fetchFromGitHub {
51 owner = "pymupdf";
52 repo = "PyMuPDF";
53 tag = version;
54 hash = "sha256-6XbHQ8PE9IF0kngUhYkFSGjwgt+r+19v+PeDAQin2Ko=";
55 };
56
57 patches = [
58 # Fix build against mupdf-1.25.3:
59 # https://github.com/pymupdf/PyMuPDF/pull/4248
60 (fetchpatch {
61 name = "mupdf-1.25.3.patch";
62 url = "https://github.com/pymupdf/PyMuPDF/commit/f42ef85058fee087d3f5e565f34a7657aad11240.patch";
63 hash = "sha256-X5JF8nPLj4uubdEdvUJ5aEf0yZkW+ks99pzua0vCrZc=";
64 })
65 ];
66
67 # swig is not wrapped as Python package
68 # libclang calls itself just clang in wheel metadata
69 postPatch = ''
70 substituteInPlace setup.py \
71 --replace-fail "ret.append( 'swig')" "pass" \
72 '';
73
74 nativeBuildInputs = [
75 libclang
76 swig
77 psutil
78 setuptools
79 ];
80
81 buildInputs = [
82 freetype
83 harfbuzz
84 openjpeg
85 jbig2dec
86 libjpeg_turbo
87 gumbo
88 ];
89
90 propagatedBuildInputs = [ mupdf-cxx ];
91
92 env = {
93 # force using system MuPDF (must be defined in environment and empty)
94 PYMUPDF_SETUP_MUPDF_BUILD = "";
95 # Setup the name of the package away from the default 'libclang'
96 PYMUPDF_SETUP_LIBCLANG = "clang";
97 # provide MuPDF paths
98 PYMUPDF_MUPDF_LIB = "${lib.getLib mupdf-cxx}/lib";
99 PYMUPDF_MUPDF_INCLUDE = "${lib.getDev mupdf-cxx}/include";
100 };
101
102 # TODO: manually add mupdf rpath until upstream fixes it
103 postInstall = lib.optionalString stdenv.hostPlatform.isDarwin ''
104 for lib in */*.so $out/${python.sitePackages}/*/*.so; do
105 install_name_tool -add_rpath ${lib.getLib mupdf-cxx}/lib "$lib"
106 done
107 '';
108
109 nativeCheckInputs = [
110 pytestCheckHook
111 ];
112
113 checkInputs = [
114 fonttools
115 pillow
116 pymupdf-fonts
117 ];
118
119 disabledTests = [
120 # Do not lint code
121 "test_codespell"
122 "test_pylint"
123 "test_flake8"
124 # Upstream recommends disabling these when not using bundled MuPDF build
125 "test_color_count"
126 "test_3050"
127 "test_textbox3"
128 ];
129
130 pythonImportsCheck = [
131 "pymupdf"
132 "fitz"
133 ];
134
135 preCheck = ''
136 export PATH="$out/bin:$PATH";
137
138 # Fixes at least one test; see:
139 # * <https://github.com/pymupdf/PyMuPDF/blob/refs/tags/1.25.1/scripts/sysinstall.py#L390>
140 # * <https://github.com/pymupdf/PyMuPDF/blob/refs/tags/1.25.1/tests/test_pixmap.py#L425-L428>
141 export PYMUPDF_SYSINSTALL_TEST=1
142 '';
143
144 meta = {
145 description = "Python bindings for MuPDF's rendering library";
146 homepage = "https://github.com/pymupdf/PyMuPDF";
147 changelog = "https://github.com/pymupdf/PyMuPDF/releases/tag/${src.tag}";
148 license = lib.licenses.agpl3Only;
149 maintainers = [ ];
150 platforms = lib.platforms.unix;
151 };
152}