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