1{
2 lib,
3 stdenv,
4 fetchurl,
5 writeText,
6 python,
7 buildPythonPackage,
8 fetchFromGitHub,
9 fetchpatch,
10
11 # build-system
12 cython,
13 gfortran,
14 meson-python,
15 nukeReferences,
16 pythran,
17 pkg-config,
18 setuptools,
19 xcbuild,
20
21 # buildInputs
22 # Upstream has support for using Darwin's Accelerate package. However this
23 # requires a Darwin user to work on a nice way to do that via an override.
24 # See:
25 # https://github.com/scipy/scipy/blob/v1.14.0/scipy/meson.build#L194-L211
26 blas,
27 lapack,
28 pybind11,
29 pooch,
30 xsimd,
31
32 # dependencies
33 numpy,
34
35 # tests
36 hypothesis,
37 pytest7CheckHook,
38 pytest-xdist,
39
40 # Reverse dependency
41 sage,
42}:
43
44let
45 pname = "scipy";
46 # DON'T UPDATE THESE ATTRIBUTES MANUALLY - USE:
47 #
48 # nix-shell maintainers/scripts/update.nix --argstr package python3.pkgs.scipy
49 #
50 # The update script uses sed regexes to replace them with the updated hashes.
51 version = "1.14.1";
52 srcHash = "sha256-eYuUHr9wZMXvEsIhssGR35JnRBNGaOL/j1LNM5sHuYY=";
53 datasetsHashes = {
54 ascent = "1qjp35ncrniq9rhzb14icwwykqg2208hcssznn3hz27w39615kh3";
55 ecg = "1bwbjp43b7znnwha5hv6wiz3g0bhwrpqpi75s12zidxrbwvd62pj";
56 face = "11i8x29h80y7hhyqhil1fg8mxag5f827g33lhnsf44qk116hp2wx";
57 };
58 datasets = lib.mapAttrs (
59 d: hash:
60 fetchurl {
61 url = "https://raw.githubusercontent.com/scipy/dataset-${d}/main/${d}.dat";
62 sha256 = hash;
63 }
64 ) datasetsHashes;
65 # Additional cross compilation related properties that scipy reads in scipy/meson.build
66 crossFileScipy = writeText "cross-file-scipy.conf" ''
67 [properties]
68 numpy-include-dir = '${numpy.coreIncludeDir}'
69 pythran-include-dir = '${pythran}/${python.sitePackages}/pythran'
70 host-python-path = '${python.interpreter}'
71 host-python-version = '${python.pythonVersion}'
72 '';
73in
74buildPythonPackage {
75 inherit pname version;
76 pyproject = true;
77
78 src = fetchFromGitHub {
79 owner = "scipy";
80 repo = "scipy";
81 rev = "refs/tags/v${version}";
82 hash = srcHash;
83 fetchSubmodules = true;
84 };
85
86 patches = [
87 # Helps with cross compilation, see https://github.com/scipy/scipy/pull/18167
88 (fetchpatch {
89 url = "https://github.com/scipy/scipy/commit/dd50ac9d98dbb70625333a23e3a90e493228e3be.patch";
90 hash = "sha256-Vf6/hhwu6X5s8KWhq8bUZKtSkdVu/GtEpGtj8Olxe7s=";
91 excludes = [ "doc/source/dev/contributor/meson_advanced.rst" ];
92 })
93 ];
94
95 # Upstream says in a comment in their pyproject.toml that building against
96 # both numpy 2 and numpy 1 should work, but they seem to worry about numpy
97 # incompatibilities that we here with Nixpkgs' Python ecosystem, shouldn't
98 # experience.
99 postPatch = ''
100 substituteInPlace pyproject.toml \
101 --replace-fail 'numpy>=2.0.0rc1,' 'numpy' \
102 --replace-fail "pybind11>=2.12.0,<2.13.0" "pybind11>=2.12.0" \
103 '';
104
105 build-system =
106 [
107 cython
108 gfortran
109 meson-python
110 nukeReferences
111 pythran
112 pkg-config
113 setuptools
114 ]
115 ++ lib.optionals stdenv.hostPlatform.isDarwin [
116 # Minimal version required according to:
117 # https://github.com/scipy/scipy/blob/v1.14.0/scipy/meson.build#L185-L188
118 (xcbuild.override {
119 sdkVer = "13.3";
120 })
121 ];
122
123 buildInputs = [
124 blas
125 lapack
126 pybind11
127 pooch
128 xsimd
129 ];
130
131 dependencies = [ numpy ];
132
133 __darwinAllowLocalNetworking = true;
134
135 nativeCheckInputs = [
136 hypothesis
137 # Failed: DID NOT WARN. No warnings of type (<class 'DeprecationWarning'>, <class 'PendingDeprecationWarning'>, <class 'FutureWarning'>) were emitted.
138 pytest7CheckHook
139 pytest-xdist
140 ];
141
142 # The following tests are broken on aarch64-darwin with newer compilers and library versions.
143 # See https://github.com/scipy/scipy/issues/18308
144 disabledTests = lib.optionals (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64) [
145 "test_a_b_neg_int_after_euler_hypergeometric_transformation"
146 "test_dst4_definition_ortho"
147 "test_load_mat4_le"
148 "hyp2f1_test_case47"
149 "hyp2f1_test_case3"
150 "test_uint64_max"
151 ];
152
153 doCheck = !(stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform.isDarwin);
154
155 preConfigure =
156 ''
157 # Helps parallelization a bit
158 export NPY_NUM_BUILD_JOBS=$NIX_BUILD_CORES
159 # We download manually the datasets and this variable tells the pooch
160 # library where these files are cached. See also:
161 # https://github.com/scipy/scipy/pull/18518#issuecomment-1562350648 And at:
162 # https://github.com/scipy/scipy/pull/17965#issuecomment-1560759962
163 export XDG_CACHE_HOME=$PWD; export HOME=$(mktemp -d); mkdir scipy-data
164 ''
165 + (lib.concatStringsSep "\n" (
166 lib.mapAttrsToList (
167 d: dpath:
168 # Actually copy the datasets
169 "cp ${dpath} scipy-data/${d}.dat"
170 ) datasets
171 ));
172
173 mesonFlags = [
174 "-Dblas=${blas.pname}"
175 "-Dlapack=${lapack.pname}"
176 # We always run what's necessary for cross compilation, which is passing to
177 # meson the proper cross compilation related arguments. See also:
178 # https://docs.scipy.org/doc/scipy/building/cross_compilation.html
179 "--cross-file=${crossFileScipy}"
180 ];
181
182 # disable stackprotector on aarch64-darwin for now
183 #
184 # build error:
185 #
186 # /private/tmp/nix-build-python3.9-scipy-1.6.3.drv-0/ccDEsw5U.s:109:15: error: index must be an integer in range [-256, 255].
187 #
188 # ldr x0, [x0, ___stack_chk_guard];momd
189 #
190 hardeningDisable = lib.optionals (stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isDarwin) [
191 "stackprotector"
192 ];
193
194 # remove references to dev dependencies
195 postInstall = ''
196 nuke-refs $out/${python.sitePackages}/scipy/__config__.py
197 rm $out/${python.sitePackages}/scipy/__pycache__/__config__.*.opt-1.pyc
198 '';
199
200 preCheck = ''
201 export OMP_NUM_THREADS=$(( $NIX_BUILD_CORES / 4 ))
202 cd $out
203 '';
204
205 requiredSystemFeatures = [ "big-parallel" ]; # the tests need lots of CPU time
206
207 passthru = {
208 inherit blas;
209 updateScript =
210 [
211 ./update.sh
212 # Pass it this file name as argument
213 (builtins.unsafeGetAttrPos "pname" python.pkgs.scipy).file
214 ]
215 # Pass it the names of the datasets to update their hashes
216 ++ (builtins.attrNames datasetsHashes);
217 tests = {
218 inherit sage;
219 };
220 };
221
222 SCIPY_USE_G77_ABI_WRAPPER = 1;
223
224 meta = {
225 changelog = "https://github.com/scipy/scipy/releases/tag/v${version}";
226 description = "SciPy (pronounced 'Sigh Pie') is open-source software for mathematics, science, and engineering";
227 downloadPage = "https://github.com/scipy/scipy";
228 homepage = "https://www.scipy.org/";
229 license = lib.licenses.bsd3;
230 maintainers = with lib.maintainers; [ doronbehar ];
231 };
232}