1{ lib
2, stdenv
3, fetchFromGitHub
4, fetchpatch
5, fetchurl
6, writeText
7, python
8, pythonOlder
9, buildPythonPackage
10, cython
11, gfortran
12, meson-python
13, pkg-config
14, pythran
15, wheel
16, nose
17, pytestCheckHook
18, pytest-xdist
19, numpy
20, pybind11
21, pooch
22, libxcrypt
23, xsimd
24, blas
25, lapack
26}:
27
28let
29 pname = "scipy";
30 # DON'T UPDATE THESE ATTRIBUTES MANUALLY - USE:
31 #
32 # nix-shell maintainers/scripts/update.nix --argstr package python3.pkgs.scipy
33 #
34 # The update script uses sed regexes to replace them with the updated hashes.
35 version = "1.11.3";
36 srcHash = "sha256-swxRfFjTcKjKQv6GFdWNR6IKhdJQYhZSR7UWLtcnrXw=";
37 datasetsHashes = {
38 ascent = "1qjp35ncrniq9rhzb14icwwykqg2208hcssznn3hz27w39615kh3";
39 ecg = "1bwbjp43b7znnwha5hv6wiz3g0bhwrpqpi75s12zidxrbwvd62pj";
40 face = "11i8x29h80y7hhyqhil1fg8mxag5f827g33lhnsf44qk116hp2wx";
41 };
42 datasets = lib.mapAttrs (
43 d: hash: fetchurl {
44 url = "https://raw.githubusercontent.com/scipy/dataset-${d}/main/${d}.dat";
45 sha256 = hash;
46 }
47 ) datasetsHashes;
48 # Additional cross compilation related properties that scipy reads in scipy/meson.build
49 crossFileScipy = writeText "cross-file-scipy.conf" ''
50 [properties]
51 numpy-include-dir = '${numpy}/${python.sitePackages}/numpy/core/include'
52 pythran-include-dir = '${pythran}/${python.sitePackages}/pythran'
53 host-python-path = '${python.interpreter}'
54 host-python-version = '${python.pythonVersion}'
55 '';
56in buildPythonPackage {
57 inherit pname version;
58 format = "pyproject";
59
60 src = fetchFromGitHub {
61 owner = "scipy";
62 repo = pname;
63 rev = "v${version}";
64 hash = srcHash;
65 fetchSubmodules = true;
66 };
67
68 patches = [
69 # Helps with cross compilation, see https://github.com/scipy/scipy/pull/18167
70 (fetchpatch {
71 url = "https://github.com/scipy/scipy/commit/dd50ac9d98dbb70625333a23e3a90e493228e3be.patch";
72 hash = "sha256-Vf6/hhwu6X5s8KWhq8bUZKtSkdVu/GtEpGtj8Olxe7s=";
73 excludes = [
74 "doc/source/dev/contributor/meson_advanced.rst"
75 ];
76 })
77 ];
78
79 # Relax deps a bit
80 postPatch = ''
81 substituteInPlace pyproject.toml \
82 --replace 'meson-python>=0.12.1,<0.14.0' 'meson-python' \
83 --replace 'numpy==' 'numpy>=' \
84 --replace "pybind11>=2.10.4,<2.11.1" "pybind11>=2.10.4,<2.12.0" \
85 --replace 'wheel<0.41.0' 'wheel'
86 '';
87
88 nativeBuildInputs = [
89 cython
90 gfortran
91 meson-python
92 pythran
93 pkg-config
94 wheel
95 ];
96
97 buildInputs = [
98 blas
99 lapack
100 pybind11
101 pooch
102 xsimd
103 ] ++ lib.optionals (pythonOlder "3.9") [
104 libxcrypt
105 ];
106
107 propagatedBuildInputs = [ numpy ];
108
109 __darwinAllowLocalNetworking = true;
110
111 nativeCheckInputs = [
112 nose
113 pytestCheckHook
114 pytest-xdist
115 ];
116
117 # The following tests are broken on aarch64-darwin with newer compilers and library versions.
118 # See https://github.com/scipy/scipy/issues/18308
119 disabledTests = lib.optionals (stdenv.isDarwin && stdenv.isAarch64) [
120 "test_a_b_neg_int_after_euler_hypergeometric_transformation"
121 "test_dst4_definition_ortho"
122 "test_load_mat4_le"
123 "hyp2f1_test_case47"
124 "hyp2f1_test_case3"
125 "test_uint64_max"
126 ];
127
128 doCheck = !(stdenv.isx86_64 && stdenv.isDarwin);
129
130 preConfigure = ''
131 # Helps parallelization a bit
132 export NPY_NUM_BUILD_JOBS=$NIX_BUILD_CORES
133 # We download manually the datasets and this variable tells the pooch
134 # library where these files are cached. See also:
135 # https://github.com/scipy/scipy/pull/18518#issuecomment-1562350648 And at:
136 # https://github.com/scipy/scipy/pull/17965#issuecomment-1560759962
137 export XDG_CACHE_HOME=$PWD; export HOME=$(mktemp -d); mkdir scipy-data
138 '' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (d: dpath:
139 # Actually copy the datasets
140 "cp ${dpath} scipy-data/${d}.dat"
141 ) datasets));
142
143 mesonFlags = [
144 "-Dblas=${blas.pname}"
145 "-Dlapack=${lapack.pname}"
146 # We always run what's necessary for cross compilation, which is passing to
147 # meson the proper cross compilation related arguments. See also:
148 # https://docs.scipy.org/doc/scipy/building/cross_compilation.html
149 "--cross-file=${crossFileScipy}"
150 ];
151
152 # disable stackprotector on aarch64-darwin for now
153 #
154 # build error:
155 #
156 # /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].
157 #
158 # ldr x0, [x0, ___stack_chk_guard];momd
159 #
160 hardeningDisable = lib.optionals (stdenv.isAarch64 && stdenv.isDarwin) [ "stackprotector" ];
161
162 checkPhase = ''
163 runHook preCheck
164
165 # Adapted from pytestCheckHook because scipy uses a custom check phase.
166 # It needs to pass `$args` as a Python list to `scipy.test` rather than as
167 # arguments to pytest on the command-line.
168 args=""
169 if [ -n "$disabledTests" ]; then
170 disabledTestsString=$(_pytestComputeDisabledTestsString "''${disabledTests[@]}")
171 args+="'-k','$disabledTestsString'"
172 fi
173
174 if [ -n "''${disabledTestPaths-}" ]; then
175 eval "disabledTestPaths=($disabledTestPaths)"
176 fi
177
178 for path in ''${disabledTestPaths[@]}; do
179 if [ ! -e "$path" ]; then
180 echo "Disabled tests path \"$path\" does not exist. Aborting"
181 exit 1
182 fi
183 args+="''${args:+,}'--ignore=\"$path\"'"
184 done
185 args+="''${args:+,}$(printf \'%s\', "''${pytestFlagsArray[@]}")"
186 args=''${args%,}
187
188 pushd "$out"
189 export OMP_NUM_THREADS=$(( $NIX_BUILD_CORES / 4 ))
190 ${python.interpreter} -c "import scipy, sys; sys.exit(scipy.test(
191 'fast',
192 verbose=10,
193 extra_argv=[$args],
194 parallel=$NIX_BUILD_CORES
195 ) != True)"
196 popd
197 runHook postCheck
198 '';
199
200 requiredSystemFeatures = [ "big-parallel" ]; # the tests need lots of CPU time
201
202 passthru = {
203 inherit blas;
204 updateScript = [
205 ./update.sh
206 # Pass it this file name as argument
207 (builtins.unsafeGetAttrPos "pname" python.pkgs.scipy).file
208 ]
209 # Pass it the names of the datasets to update their hashes
210 ++ (builtins.attrNames datasetsHashes)
211 ;
212 };
213
214 SCIPY_USE_G77_ABI_WRAPPER = 1;
215
216 meta = with lib; {
217 description = "SciPy (pronounced 'Sigh Pie') is open-source software for mathematics, science, and engineering";
218 downloadPage = "https://github.com/scipy/scipy";
219 homepage = "https://www.scipy.org/";
220 license = licenses.bsd3;
221 maintainers = with maintainers; [ fridh doronbehar ];
222 };
223}