nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchFromGitHub,
6 python,
7 toPythonModule,
8
9 # build-system
10 libclang,
11 psutil,
12 setuptools,
13 swig,
14
15 # native dependencies
16 freetype,
17 harfbuzz,
18 openjpeg,
19 jbig2dec,
20 libjpeg_turbo,
21 gumbo,
22
23 # dependencies
24 mupdf,
25
26 # tests
27 pytestCheckHook,
28 fonttools,
29 pillow,
30 pymupdf-fonts,
31}:
32
33let
34 # PyMuPDF needs the C++ bindings generated
35 mupdf-cxx = mupdf.override {
36 enableOcr = true;
37 enableCxx = true;
38 enablePython = true;
39 enableBarcode = true;
40 python3 = python;
41 };
42 mupdf-cxx-lib = toPythonModule (lib.getLib mupdf-cxx);
43 mupdf-cxx-dev = lib.getDev mupdf-cxx;
44in
45buildPythonPackage rec {
46 pname = "pymupdf";
47 version = "1.26.7";
48 pyproject = true;
49
50 src = fetchFromGitHub {
51 owner = "pymupdf";
52 repo = "PyMuPDF";
53 tag = version;
54 hash = "sha256-7OidTOG3KAx7EaQ3Bu4i1Fw007oXVAipBHeYNkmbIcA=";
55 };
56
57 patches = [
58 # `conftest.py` tries to run `pip install` to install test dependencies.
59 ./conftest-dont-pip-install.patch
60 ];
61
62 # swig is not wrapped as Python package
63 postPatch = ''
64 substituteInPlace setup.py \
65 --replace-fail "ret.append('swig')" "pass" \
66 --replace-fail "ret.append('swig==4.3.1')" "pass"
67 '';
68
69 # `build_extension` passes arguments to `$LD` that are meant for `c++`.
70 # When `LD` is not set, `build_extension` falls back to using `c++` in `PATH`.
71 # See https://github.com/pymupdf/PyMuPDF/blob/1.26.6/pipcl.py#L1998 for details.
72 preConfigure = ''
73 unset LD
74 '';
75
76 build-system = [
77 libclang
78 swig
79 setuptools
80 ];
81
82 dependencies = [
83 mupdf-cxx-lib
84 ];
85
86 buildInputs = [
87 freetype
88 harfbuzz
89 openjpeg
90 jbig2dec
91 libjpeg_turbo
92 gumbo
93 ];
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 fonttools
115 pillow
116 psutil
117 pymupdf-fonts
118 ];
119
120 disabledTests = [
121 # Do not lint code
122 "test_codespell"
123 "test_pylint"
124 "test_flake8"
125 # Upstream recommends disabling these when not using bundled MuPDF build
126 "test_color_count"
127 "test_3050"
128 "test_textbox3"
129 "test_3493"
130 "test_4180"
131 # Requires downloads
132 "test_4457"
133 "test_4445"
134 "test_4533"
135 "test_4702"
136 # Not a git repository, so git ls-files fails
137 "test_open2"
138 ];
139
140 disabledTestPaths = [
141 # mad about markdown table formatting
142 "tests/test_tables.py::test_markdown"
143 ]
144 ++ lib.optional stdenv.hostPlatform.isDarwin [
145 # Trace/BPT trap: 5 when getting widget options
146 "tests/test_4505.py"
147 "tests/test_widgets.py"
148 ];
149
150 pythonImportsCheck = [
151 "pymupdf"
152 "fitz"
153 ];
154
155 preCheck = ''
156 export PATH="$out/bin:$PATH";
157
158 # Fixes at least one test; see:
159 # * <https://github.com/pymupdf/PyMuPDF/blob/refs/tags/1.25.1/scripts/sysinstall.py#L390>
160 # * <https://github.com/pymupdf/PyMuPDF/blob/refs/tags/1.25.1/tests/test_pixmap.py#L425-L428>
161 export PYMUPDF_SYSINSTALL_TEST=1
162 '';
163
164 meta = {
165 description = "Python bindings for MuPDF's rendering library";
166 homepage = "https://github.com/pymupdf/PyMuPDF";
167 changelog = "https://github.com/pymupdf/PyMuPDF/releases/tag/${src.tag}";
168 license = lib.licenses.agpl3Only;
169 maintainers = with lib.maintainers; [ sarahec ];
170 platforms = lib.platforms.unix;
171 };
172}