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