From 44f8fba6e1ff0bec31b991c1fc11c663061f1eeb Mon Sep 17 00:00:00 2001 From: SuperSix173 Date: Sun, 4 Feb 2024 11:31:14 +0800 Subject: [PATCH] Fix scipy compile error in cython3 Signed-off-by: SuperSix173 --- ...thon_optimize.pxd-to-build-dir-18810.patch | 66 + ...cipy-to-be-compiled-in-cython3-18242.patch | 47 + ...-mark-cdef-functions-not-raising-exc.patch | 4330 +++++++++++++++++ ...nction-pointer-ctypedefs-as-noexcept.patch | 67 + scipy.spec | 10 +- 5 files changed, 4519 insertions(+), 1 deletion(-) create mode 100644 0001-BLD-copy-cython_optimize.pxd-to-build-dir-18810.patch create mode 100644 0001-MAINT-Allow-scipy-to-be-compiled-in-cython3-18242.patch create mode 100644 0001-MAINT-Explicitly-mark-cdef-functions-not-raising-exc.patch create mode 100644 0001-Mark-function-pointer-ctypedefs-as-noexcept.patch diff --git a/0001-BLD-copy-cython_optimize.pxd-to-build-dir-18810.patch b/0001-BLD-copy-cython_optimize.pxd-to-build-dir-18810.patch new file mode 100644 index 0000000..7526d19 --- /dev/null +++ b/0001-BLD-copy-cython_optimize.pxd-to-build-dir-18810.patch @@ -0,0 +1,66 @@ +From 3c89445b6439f3ce7bffc4cf11c6407c39faedc5 Mon Sep 17 00:00:00 2001 +From: Matus Valo +Date: Thu, 6 Jul 2023 16:55:25 +0200 +Subject: [PATCH] BLD: copy `cython_optimize.pxd` to build dir (#18810) + +Closes gh-18792 + +[skip cirrus] [skip circle] + +--------- + +Co-authored-by: Ralf Gommers +--- + scipy/optimize/cython_optimize.pxd | 2 +- + scipy/optimize/cython_optimize/meson.build | 1 + + scipy/optimize/meson.build | 8 +++++++- + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/scipy/optimize/cython_optimize.pxd b/scipy/optimize/cython_optimize.pxd +index d5a0bdd75..d35f8da68 100644 +--- a/scipy/optimize/cython_optimize.pxd ++++ b/scipy/optimize/cython_optimize.pxd +@@ -7,5 +7,5 @@ + # support. Changing it causes an ABI forward-compatibility break + # (gh-11793), so we currently leave it as is (no further cimport + # statements should be used in this file). +-from .cython_optimize._zeros cimport ( ++from scipy.optimize.cython_optimize._zeros cimport ( + brentq, brenth, ridder, bisect, zeros_full_output) +diff --git a/scipy/optimize/cython_optimize/meson.build b/scipy/optimize/cython_optimize/meson.build +index 359ea8418..ee8def39b 100644 +--- a/scipy/optimize/cython_optimize/meson.build ++++ b/scipy/optimize/cython_optimize/meson.build +@@ -17,6 +17,7 @@ cy_opt_gen = generator(cython, + arguments : cython_args, + output : '@BASENAME@.c', + depends : [_cython_tree, ++ cython_optimize_pxd, + _dummy_init_optimize, + _dummy_init_cyoptimize]) + +diff --git a/scipy/optimize/meson.build b/scipy/optimize/meson.build +index 26458b05c..4c5ab7983 100644 +--- a/scipy/optimize/meson.build ++++ b/scipy/optimize/meson.build +@@ -206,10 +206,16 @@ endif + + _dummy_init_optimize = fs.copyfile('__init__.py') + ++# Copying this .pxd file is only needed because of a Cython bug, see ++# discussion on SciPy PR gh-18810. ++cython_optimize_pxd = [ ++ fs.copyfile('cython_optimize.pxd'), ++] ++ + opt_gen = generator(cython, + arguments : cython_args, + output : '@BASENAME@.c', +- depends : [_cython_tree, cython_linalg, _dummy_init_optimize]) ++ depends : [_cython_tree, cython_linalg, cython_optimize_pxd, _dummy_init_optimize]) + + _bglu_dense_c = opt_gen.process('_bglu_dense.pyx') + +-- +2.23.0 + diff --git a/0001-MAINT-Allow-scipy-to-be-compiled-in-cython3-18242.patch b/0001-MAINT-Allow-scipy-to-be-compiled-in-cython3-18242.patch new file mode 100644 index 0000000..c0ffcea --- /dev/null +++ b/0001-MAINT-Allow-scipy-to-be-compiled-in-cython3-18242.patch @@ -0,0 +1,47 @@ +From a181fd5b75f2e05d1b7beafbb48157feaa468941 Mon Sep 17 00:00:00 2001 +From: Matus Valo +Date: Wed, 3 May 2023 22:22:36 +0200 +Subject: [PATCH] MAINT: Allow scipy to be compiled in cython3 (#18242) + +- Unpin Cython and use Cython master in the pre-release CI job +- Use absolute instead of relative imports in a few places +- Use `CYTHON_EXTERN_C` for C++ code exposing a C API + +[skip ci] +--- + .github/workflows/linux_meson.yml | 5 ++--- + scipy/linalg.pxd | 2 +- + scipy/special.pxd | 2 +- + scipy/special/meson.build | 2 +- + 4 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/scipy/linalg.pxd b/scipy/linalg.pxd +index 1f656b870..c7c49f9ad 100644 +--- a/scipy/linalg.pxd ++++ b/scipy/linalg.pxd +@@ -1 +1 @@ +-from .linalg cimport cython_blas, cython_lapack ++from scipy.linalg cimport cython_blas, cython_lapack +diff --git a/scipy/special.pxd b/scipy/special.pxd +index 62cb82807..1daa9fb37 100644 +--- a/scipy/special.pxd ++++ b/scipy/special.pxd +@@ -1 +1 @@ +-from .special cimport cython_special ++from scipy.special cimport cython_special +diff --git a/scipy/special/meson.build b/scipy/special/meson.build +index 334f87943..e7e25aa54 100644 +--- a/scipy/special/meson.build ++++ b/scipy/special/meson.build +@@ -371,7 +371,7 @@ py3.extension_module('_ufuncs_cxx', + [ufuncs_cxx_sources, + uf_cython_gen_cpp.process(cython_special[2]), # _ufuncs_cxx.pyx + ], +- cpp_args: cython_cpp_args, ++ cpp_args: [cython_cpp_args, '-DCYTHON_EXTERN_C=extern "C"'], + include_directories: [inc_np, '../_lib/boost', '../_lib', + '../_build_utils/src'], + link_args: version_link_args, +-- +2.23.0 + diff --git a/0001-MAINT-Explicitly-mark-cdef-functions-not-raising-exc.patch b/0001-MAINT-Explicitly-mark-cdef-functions-not-raising-exc.patch new file mode 100644 index 0000000..6debbc1 --- /dev/null +++ b/0001-MAINT-Explicitly-mark-cdef-functions-not-raising-exc.patch @@ -0,0 +1,4330 @@ +From 10df6ab4c165c2df16fc49eba924c96caf8cf27b Mon Sep 17 00:00:00 2001 +From: Matus Valo +Date: Mon, 17 Apr 2023 13:05:38 +0200 +Subject: [PATCH] MAINT: Explicitly mark `cdef` functions not raising exception + with noexcept (#18266) + +Also ping `cython==0.29.33` in the pre-release CI job, because this commit +is one of a few needed to fix SciPy building with the latest 3.0-beta Cython +releases. +--- + scipy/_lib/_ccallback_c.pyx | 2 +- + scipy/_lib/_test_deprecation_def.pyx | 4 +- + scipy/cluster/_hierarchy.pyx | 22 ++-- + scipy/cluster/_hierarchy_distance_update.pxi | 14 +-- + scipy/cluster/_optimal_leaf_ordering.pyx | 6 +- + scipy/cluster/_structures.pxi | 16 +-- + scipy/cluster/_vq.pyx | 8 +- + scipy/interpolate/_bspl.pyx | 2 +- + scipy/interpolate/_poly_common.pxi | 2 +- + scipy/interpolate/_ppoly.pyx | 8 +- + scipy/interpolate/interpnd.pyx | 4 +- + scipy/io/matlab/_mio5_utils.pyx | 16 +-- + scipy/io/matlab/_streams.pyx | 2 +- + scipy/linalg/_cythonized_array_utils.pyx | 14 +-- + scipy/linalg/_decomp_update.pyx.in | 100 +++++++++--------- + scipy/linalg/_generate_pyx.py | 46 ++++---- + scipy/linalg/_matfuncs_expm.pyx.in | 12 +-- + scipy/ndimage/src/_cytest.pxd | 6 +- + scipy/ndimage/src/_cytest.pyx | 10 +- + scipy/ndimage/src/_ni_label.pyx | 20 ++-- + scipy/optimize/_bglu_dense.pyx | 8 +- + .../_highs/cython/src/_highs_wrapper.pyx | 4 +- + scipy/optimize/cython_optimize/_zeros.pxd | 8 +- + scipy/optimize/cython_optimize/_zeros.pyx.in | 10 +- + scipy/optimize/cython_optimize/c_zeros.pxd | 2 +- + scipy/signal/_sosfilt.pyx | 2 +- + scipy/signal/_upfirdn_apply.pyx | 8 +- + scipy/sparse/csgraph/_flow.pyx | 8 +- + scipy/sparse/csgraph/_matching.pyx | 2 +- + scipy/sparse/csgraph/_min_spanning_tree.pyx | 2 +- + scipy/sparse/csgraph/_shortest_path.pyx | 34 +++--- + scipy/sparse/csgraph/_tools.pyx | 4 +- + scipy/sparse/csgraph/_traversal.pyx | 12 +-- + scipy/spatial/_ckdtree.pyx | 2 +- + scipy/spatial/_qhull.pxd | 18 ++-- + scipy/spatial/_qhull.pyx | 24 ++--- + scipy/spatial/_voronoi.pyx | 2 +- + scipy/spatial/setlist.pxd | 4 +- + scipy/spatial/transform/_rotation.pyx | 30 +++--- + scipy/special/_agm.pxd | 4 +- + scipy/special/_boxcox.pxd | 8 +- + scipy/special/_comb.pyx | 2 +- + scipy/special/_complexstuff.pxd | 32 +++--- + scipy/special/_convex_analysis.pxd | 10 +- + scipy/special/_cunity.pxd | 6 +- + scipy/special/_cython_special.pxi | 2 +- + scipy/special/_cython_special_custom.pxi | 8 +- + scipy/special/_digamma.pxd | 12 +-- + scipy/special/_ellip_harm.pxd | 6 +- + scipy/special/_ellip_harm_2.pyx | 12 +-- + scipy/special/_ellipk.pxd | 2 +- + scipy/special/_evalpoly.pxd | 2 +- + scipy/special/_exprel.pxd | 2 +- + scipy/special/_factorial.pxd | 2 +- + scipy/special/_generate_pyx.py | 24 ++--- + scipy/special/_hyp0f1.pxd | 6 +- + scipy/special/_hyp2f1.pxd | 10 +- + scipy/special/_hypergeometric.pxd | 2 +- + scipy/special/_lambertw.pxd | 8 +- + scipy/special/_legacy.pxd | 38 +++---- + scipy/special/_loggamma.pxd | 14 +-- + scipy/special/_ndtri_exp.pxd | 4 +- + scipy/special/_sici.pxd | 8 +- + scipy/special/_spence.pxd | 6 +- + scipy/special/_spherical_bessel.pxd | 38 +++---- + scipy/special/_trig.pxd | 8 +- + scipy/special/_ufuncs_extra_code_common.pxi | 4 +- + scipy/special/_wright_bessel.pxd | 18 ++-- + scipy/special/_xlogy.pxd | 4 +- + scipy/special/orthogonal_eval.pxd | 62 +++++------ + scipy/special/sf_error.pxd | 2 +- + scipy/special/sph_harm.pxd | 2 +- + scipy/stats/_biasedurn.pyx.templ | 8 +- + scipy/stats/_qmc_cy.pyx | 22 ++-- + scipy/stats/_sobol.pyx | 22 ++-- + scipy/stats/_stats.pxd | 10 +- + scipy/stats/_stats.pyx | 36 +++---- + scipy/stats/_unuran/unuran_wrapper.pyx.templ | 8 +- + 78 files changed, 486 insertions(+), 486 deletions(-) + +diff --git a/scipy/_lib/_ccallback_c.pyx b/scipy/_lib/_ccallback_c.pyx +index 0704acc6..93a7ec73 100644 +--- a/scipy/_lib/_ccallback_c.pyx ++++ b/scipy/_lib/_ccallback_c.pyx +@@ -14,7 +14,7 @@ from .ccallback cimport (ccallback_t, ccallback_prepare, ccallback_release, CCAL + # PyCapsule helpers + # + +-cdef void raw_capsule_destructor(object capsule): ++cdef void raw_capsule_destructor(object capsule) noexcept: + cdef char *name + name = PyCapsule_GetName(capsule) + free(name) +diff --git a/scipy/_lib/_test_deprecation_def.pyx b/scipy/_lib/_test_deprecation_def.pyx +index 2ef1f52f..a976d0ed 100644 +--- a/scipy/_lib/_test_deprecation_def.pyx ++++ b/scipy/_lib/_test_deprecation_def.pyx +@@ -1,7 +1,7 @@ +-cdef public int foo(): ++cdef public int foo() noexcept: + return 1 + +-cdef public int foo_deprecated(): ++cdef public int foo_deprecated() noexcept: + return 1 + + from scipy._lib.deprecation import deprecate_cython_api +diff --git a/scipy/cluster/_hierarchy.pyx b/scipy/cluster/_hierarchy.pyx +index 92c83310..8b8a00c3 100644 +--- a/scipy/cluster/_hierarchy.pyx ++++ b/scipy/cluster/_hierarchy.pyx +@@ -18,7 +18,7 @@ cdef linkage_distance_update *linkage_methods = [ + include "_structures.pxi" + + cdef inline np.npy_int64 condensed_index(np.npy_int64 n, np.npy_int64 i, +- np.npy_int64 j): ++ np.npy_int64 j) noexcept: + """ + Calculate the condensed index of element (i, j) in an n x n condensed + matrix. +@@ -29,21 +29,21 @@ cdef inline np.npy_int64 condensed_index(np.npy_int64 n, np.npy_int64 i, + return n * j - (j * (j + 1) / 2) + (i - j - 1) + + +-cdef inline int is_visited(uchar *bitset, int i): ++cdef inline int is_visited(uchar *bitset, int i) noexcept: + """ + Check if node i was visited. + """ + return bitset[i >> 3] & (1 << (i & 7)) + + +-cdef inline void set_visited(uchar *bitset, int i): ++cdef inline void set_visited(uchar *bitset, int i) noexcept: + """ + Mark node i as visited. + """ + bitset[i >> 3] |= 1 << (i & 7) + + +-cpdef void calculate_cluster_sizes(double[:, :] Z, double[:] cs, int n): ++cpdef void calculate_cluster_sizes(double[:, :] Z, double[:] cs, int n) noexcept: + """ + Calculate the size of each cluster. The result is the fourth column of + the linkage matrix. +@@ -142,7 +142,7 @@ def cluster_maxclust_dist(double[:, :] Z, int[:] T, int n, int mc): + + + cpdef void cluster_maxclust_monocrit(double[:, :] Z, double[:] MC, int[:] T, +- int n, int max_nc): ++ int n, int max_nc) noexcept: + """ + Form flat clusters by maxclust_monocrit criterion. + +@@ -228,7 +228,7 @@ cpdef void cluster_maxclust_monocrit(double[:, :] Z, double[:] MC, int[:] T, + + + cpdef void cluster_monocrit(double[:, :] Z, double[:] MC, int[:] T, +- double cutoff, int n): ++ double cutoff, int n) noexcept: + """ + Form flat clusters by monocrit criterion. + +@@ -368,7 +368,7 @@ def cophenetic_distances(double[:, :] Z, double[:] d, int n): + + + cpdef void get_max_Rfield_for_each_cluster(double[:, :] Z, double[:, :] R, +- double[:] max_rfs, int n, int rf): ++ double[:] max_rfs, int n, int rf) noexcept: + """ + Get the maximum statistic for each non-singleton cluster. For the i'th + non-singleton cluster, max_rfs[i] = max{R[j, rf] j is a descendent of i}. +@@ -431,7 +431,7 @@ cpdef void get_max_Rfield_for_each_cluster(double[:, :] Z, double[:, :] R, + PyMem_Free(visited) + + +-cpdef get_max_dist_for_each_cluster(double[:, :] Z, double[:] MD, int n): ++cpdef get_max_dist_for_each_cluster(double[:, :] Z, double[:] MD, int n) noexcept: + """ + Get the maximum inconsistency coefficient for each non-singleton cluster. + +@@ -1080,7 +1080,7 @@ cdef class LinkageUnionFind: + self.next_label = n + self.size = np.ones(2 * n - 1, dtype=np.intc) + +- cdef int merge(self, int x, int y): ++ cdef int merge(self, int x, int y) noexcept: + self.parent[x] = self.next_label + self.parent[y] = self.next_label + cdef int size = self.size[x] + self.size[y] +@@ -1088,7 +1088,7 @@ cdef class LinkageUnionFind: + self.next_label += 1 + return size + +- cdef find(self, int x): ++ cdef find(self, int x) noexcept: + cdef int p = x + + while self.parent[x] != x: +@@ -1100,7 +1100,7 @@ cdef class LinkageUnionFind: + return x + + +-cdef label(double[:, :] Z, int n): ++cdef label(double[:, :] Z, int n) noexcept: + """Correctly label clusters in unsorted dendrogram.""" + cdef LinkageUnionFind uf = LinkageUnionFind(n) + cdef int i, x, y, x_root, y_root +diff --git a/scipy/cluster/_hierarchy_distance_update.pxi b/scipy/cluster/_hierarchy_distance_update.pxi +index bd47c209..17dedb30 100644 +--- a/scipy/cluster/_hierarchy_distance_update.pxi ++++ b/scipy/cluster/_hierarchy_distance_update.pxi +@@ -28,34 +28,34 @@ ctypedef double (*linkage_distance_update)(double d_xi, double d_yi, + + + cdef double _single(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + return min(d_xi, d_yi) + + + cdef double _complete(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + return max(d_xi, d_yi) + + + cdef double _average(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + return (size_x * d_xi + size_y * d_yi) / (size_x + size_y) + + + cdef double _centroid(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + return sqrt((((size_x * d_xi * d_xi) + (size_y * d_yi * d_yi)) - + (size_x * size_y * d_xy * d_xy) / (size_x + size_y)) / + (size_x + size_y)) + + + cdef double _median(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + return sqrt(0.5 * (d_xi * d_xi + d_yi * d_yi) - 0.25 * d_xy * d_xy) + + + cdef double _ward(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + cdef double t = 1.0 / (size_x + size_y + size_i) + return sqrt((size_i + size_x) * t * d_xi * d_xi + + (size_i + size_y) * t * d_yi * d_yi - +@@ -63,5 +63,5 @@ cdef double _ward(double d_xi, double d_yi, double d_xy, + + + cdef double _weighted(double d_xi, double d_yi, double d_xy, +- int size_x, int size_y, int size_i): ++ int size_x, int size_y, int size_i) noexcept: + return 0.5 * (d_xi + d_yi) +diff --git a/scipy/cluster/_optimal_leaf_ordering.pyx b/scipy/cluster/_optimal_leaf_ordering.pyx +index d8c86230..633bf395 100644 +--- a/scipy/cluster/_optimal_leaf_ordering.pyx ++++ b/scipy/cluster/_optimal_leaf_ordering.pyx +@@ -38,7 +38,7 @@ np.import_array() + @cython.boundscheck(False) + @cython.wraparound(False) + cdef inline void dual_swap(float* darr, int* iarr, +- int i1, int i2): ++ int i1, int i2) noexcept: + """ + [Taken from Scikit-learn.] + +@@ -121,7 +121,7 @@ cdef int _simultaneous_sort(float* dist, int* idx, + + cdef inline void _sort_M_slice(float[:, ::1] M, + float* vals, int* idx, +- int dim1_min, int dim1_max, int dim2_val): ++ int dim1_min, int dim1_max, int dim2_val) noexcept: + """ + Simultaneously sort indices and values of M[{m}, u] using + `_simultaneous_sort` +@@ -144,7 +144,7 @@ cdef inline void _sort_M_slice(float[:, ::1] M, + @cython.wraparound(False) + cdef int[:] identify_swaps(int[:, ::1] sorted_Z, + double[:, ::1] sorted_D, +- int[:, ::1] cluster_ranges): ++ int[:, ::1] cluster_ranges) noexcept: + """ + Implements the Optimal Leaf Ordering algorithm described in + "Fast Optimal leaf ordering for hierarchical clustering" +diff --git a/scipy/cluster/_structures.pxi b/scipy/cluster/_structures.pxi +index 1d8f4a5f..31697ef4 100644 +--- a/scipy/cluster/_structures.pxi ++++ b/scipy/cluster/_structures.pxi +@@ -42,15 +42,15 @@ cdef class Heap: + for i in reversed(range(self.size / 2)): + self.sift_down(i) + +- cpdef Pair get_min(self): ++ cpdef Pair get_min(self) noexcept: + return Pair(self.key_by_index[0], self.values[0]) + +- cpdef void remove_min(self): ++ cpdef void remove_min(self) noexcept: + self.swap(0, self.size - 1) + self.size -= 1 + self.sift_down(0) + +- cpdef void change_value(self, int key, double value): ++ cpdef void change_value(self, int key, double value) noexcept: + cdef int index = self.index_by_key[key] + cdef double old_value = self.values[index] + self.values[index] = value +@@ -59,14 +59,14 @@ cdef class Heap: + else: + self.sift_down(index) + +- cdef void sift_up(self, int index): ++ cdef void sift_up(self, int index) noexcept: + cdef int parent = Heap.parent(index) + while index > 0 and self.values[parent] > self.values[index]: + self.swap(index, parent) + index = parent + parent = Heap.parent(index) + +- cdef void sift_down(self, int index): ++ cdef void sift_down(self, int index) noexcept: + cdef int child = Heap.left_child(index) + while child < self.size: + if (child + 1 < self.size and +@@ -81,14 +81,14 @@ cdef class Heap: + break + + @staticmethod +- cdef inline int left_child(int parent): ++ cdef inline int left_child(int parent) noexcept: + return (parent << 1) + 1 + + @staticmethod +- cdef inline int parent(int child): ++ cdef inline int parent(int child) noexcept: + return (child - 1) >> 1 + +- cdef void swap(self, int i, int j): ++ cdef void swap(self, int i, int j) noexcept: + self.values[i], self.values[j] = self.values[j], self.values[i] + cdef int key_i = self.key_by_index[i] + cdef int key_j = self.key_by_index[j] +diff --git a/scipy/cluster/_vq.pyx b/scipy/cluster/_vq.pyx +index e785ea63..d5c66d29 100644 +--- a/scipy/cluster/_vq.pyx ++++ b/scipy/cluster/_vq.pyx +@@ -32,7 +32,7 @@ DEF NFEATURES_CUTOFF=5 + np.import_array() + + +-cdef inline vq_type vec_sqr(int n, vq_type *p): ++cdef inline vq_type vec_sqr(int n, vq_type *p) noexcept: + cdef vq_type result = 0.0 + cdef int i + for i in range(n): +@@ -41,7 +41,7 @@ cdef inline vq_type vec_sqr(int n, vq_type *p): + + + cdef inline void cal_M(int nobs, int ncodes, int nfeat, vq_type *obs, +- vq_type *code_book, vq_type *M): ++ vq_type *code_book, vq_type *M) noexcept: + """ + Calculate M = obs * code_book.T + """ +@@ -137,7 +137,7 @@ cdef int _vq(vq_type *obs, vq_type *code_book, + + cdef void _vq_small_nf(vq_type *obs, vq_type *code_book, + int ncodes, int nfeat, int nobs, +- int32_t *codes, vq_type *low_dist): ++ int32_t *codes, vq_type *low_dist) noexcept: + """ + Vector quantization using naive algorithm. + This is preferred when nfeat is small. +@@ -243,7 +243,7 @@ def vq(np.ndarray obs, np.ndarray codes): + + @cython.cdivision(True) + cdef np.ndarray _update_cluster_means(vq_type *obs, int32_t *labels, +- vq_type *cb, int nobs, int nc, int nfeat): ++ vq_type *cb, int nobs, int nc, int nfeat) noexcept: + """ + The underlying function (template) of _vq.update_cluster_means. + +diff --git a/scipy/interpolate/_bspl.pyx b/scipy/interpolate/_bspl.pyx +index 347dc13b..7ca6184d 100644 +--- a/scipy/interpolate/_bspl.pyx ++++ b/scipy/interpolate/_bspl.pyx +@@ -34,7 +34,7 @@ cdef inline int find_interval(const double[::1] t, + int k, + double xval, + int prev_l, +- bint extrapolate) nogil: ++ bint extrapolate) noexcept nogil: + """ + Find an interval such that t[interval] <= xval < t[interval+1]. + +diff --git a/scipy/interpolate/_poly_common.pxi b/scipy/interpolate/_poly_common.pxi +index 7764ed95..64f36f14 100644 +--- a/scipy/interpolate/_poly_common.pxi ++++ b/scipy/interpolate/_poly_common.pxi +@@ -14,7 +14,7 @@ cdef int find_interval_ascending(const double *x, + size_t nx, + double xval, + int prev_interval=0, +- bint extrapolate=1) nogil: ++ bint extrapolate=1) noexcept nogil: + """ + Find an interval such that x[interval] <= xval < x[interval+1]. Assuming + that x is sorted in the ascending order. +diff --git a/scipy/interpolate/_ppoly.pyx b/scipy/interpolate/_ppoly.pyx +index e77230c4..12d50864 100644 +--- a/scipy/interpolate/_ppoly.pyx ++++ b/scipy/interpolate/_ppoly.pyx +@@ -564,7 +564,7 @@ cdef int find_interval_descending(const double *x, + size_t nx, + double xval, + int prev_interval=0, +- bint extrapolate=1) nogil: ++ bint extrapolate=1) noexcept nogil: + """ + Find an interval such that x[interval + 1] < xval <= x[interval], assuming + that x are sorted in the descending order. +@@ -648,7 +648,7 @@ cdef int find_interval_descending(const double *x, + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.cdivision(True) +-cdef double_or_complex evaluate_poly1(double s, double_or_complex[:,:,::1] c, int ci, int cj, int dx) nogil: ++cdef double_or_complex evaluate_poly1(double s, double_or_complex[:,:,::1] c, int ci, int cj, int dx) noexcept nogil: + """ + Evaluate polynomial, derivative, or antiderivative in a single interval. + +@@ -932,7 +932,7 @@ def _croots_poly1(double[:,:,::1] c, double_complex[:,:,::1] w, double y=0): + @cython.cdivision(True) + cdef double_or_complex evaluate_bpoly1(double_or_complex s, + double_or_complex[:,:,::1] c, +- int ci, int cj) nogil: ++ int ci, int cj) noexcept nogil: + """ + Evaluate polynomial in the Bernstein basis in a single interval. + +@@ -985,7 +985,7 @@ cdef double_or_complex evaluate_bpoly1_deriv(double_or_complex s, + double_or_complex[:,:,::1] c, + int ci, int cj, + int nu, +- double_or_complex[:,:,::1] wrk) nogil: ++ double_or_complex[:,:,::1] wrk) noexcept nogil: + """ + Evaluate the derivative of a polynomial in the Bernstein basis + in a single interval. +diff --git a/scipy/interpolate/interpnd.pyx b/scipy/interpolate/interpnd.pyx +index 06ae5124..8fda7cca 100644 +--- a/scipy/interpolate/interpnd.pyx ++++ b/scipy/interpolate/interpnd.pyx +@@ -350,7 +350,7 @@ class GradientEstimationWarning(Warning): + @cython.cdivision(True) + cdef int _estimate_gradients_2d_global(qhull.DelaunayInfo_t *d, double *data, + int maxiter, double tol, +- double *y) nogil: ++ double *y) noexcept nogil: + """ + Estimate gradients of a function at the vertices of a 2d triangulation. + +@@ -583,7 +583,7 @@ cdef double_or_complex _clough_tocher_2d_single(qhull.DelaunayInfo_t *d, + int isimplex, + double *b, + double_or_complex *f, +- double_or_complex *df) nogil: ++ double_or_complex *df) noexcept nogil: + """ + Evaluate Clough-Tocher interpolant on a 2D triangle. + +diff --git a/scipy/io/matlab/_mio5_utils.pyx b/scipy/io/matlab/_mio5_utils.pyx +index 30793a61..c742e8ca 100644 +--- a/scipy/io/matlab/_mio5_utils.pyx ++++ b/scipy/io/matlab/_mio5_utils.pyx +@@ -109,7 +109,7 @@ cdef cnp.dtype OPAQUE_DTYPE = mio5p.OPAQUE_DTYPE + cdef cnp.dtype BOOL_DTYPE = np.dtype(np.bool_) + + +-cpdef cnp.uint32_t byteswap_u4(cnp.uint32_t u4): ++cpdef cnp.uint32_t byteswap_u4(cnp.uint32_t u4) noexcept: + return ((u4 << 24) | + ((u4 << 8) & 0xff0000U) | + ((u4 >> 8 & 0xff00u)) | +@@ -406,7 +406,7 @@ cdef class VarReader5: + self.cstream.seek(8 - mod8, 1) + return 0 + +- cpdef cnp.ndarray read_numeric(self, int copy=True, size_t nnz=-1): ++ cpdef cnp.ndarray read_numeric(self, int copy=True, size_t nnz=-1) noexcept: + ''' Read numeric data element into ndarray + + Reads element, then casts to ndarray. +@@ -558,7 +558,7 @@ cdef class VarReader5: + byte_count[0] = u4s[1] + return 0 + +- cpdef VarHeader5 read_header(self, int check_stream_limit): ++ cpdef VarHeader5 read_header(self, int check_stream_limit) noexcept: + ''' Return matrix header for current stream position + + Returns matrix headers at top level and sub levels +@@ -609,7 +609,7 @@ cdef class VarReader5: + header.name = self.read_int8_string() + return header + +- cdef inline size_t size_from_header(self, VarHeader5 header): ++ cdef inline size_t size_from_header(self, VarHeader5 header) noexcept: + ''' Supporting routine for calculating array sizes from header + + Probably unnecessary optimization that uses integers stored in +@@ -750,7 +750,7 @@ cdef class VarReader5: + shape = tuple([x for x in shape if x != 1]) + return shape + +- cpdef cnp.ndarray read_real_complex(self, VarHeader5 header): ++ cpdef cnp.ndarray read_real_complex(self, VarHeader5 header) noexcept: + ''' Read real / complex matrices from stream ''' + cdef: + cnp.ndarray res, res_j +@@ -803,7 +803,7 @@ cdef class VarReader5: + (data[:nnz], rowind[:nnz], indptr), + shape=(M, N)) + +- cpdef cnp.ndarray read_char(self, VarHeader5 header): ++ cpdef cnp.ndarray read_char(self, VarHeader5 header) noexcept: + ''' Read char matrices from stream as arrays + + Matrices of char are likely to be converted to matrices of +@@ -871,7 +871,7 @@ cdef class VarReader5: + buffer=arr, + order='F') + +- cpdef cnp.ndarray read_cells(self, VarHeader5 header): ++ cpdef cnp.ndarray read_cells(self, VarHeader5 header) noexcept: + ''' Read cell array from stream ''' + cdef: + size_t i +@@ -927,7 +927,7 @@ cdef class VarReader5: + n_names_ptr[0] = n_names + return field_names + +- cpdef cnp.ndarray read_struct(self, VarHeader5 header): ++ cpdef cnp.ndarray read_struct(self, VarHeader5 header) noexcept: + ''' Read struct or object array from stream + + Objects are just structs with an extra field *classname*, +diff --git a/scipy/io/matlab/_streams.pyx b/scipy/io/matlab/_streams.pyx +index 8d93be01..8499de1e 100644 +--- a/scipy/io/matlab/_streams.pyx ++++ b/scipy/io/matlab/_streams.pyx +@@ -236,7 +236,7 @@ def _read_string(GenericStream st, size_t n): + return bytes(my_str) + + +-cpdef GenericStream make_stream(object fobj): ++cpdef GenericStream make_stream(object fobj) noexcept: + """ Make stream of correct type for file-like `fobj` + """ + if isinstance(fobj, GenericStream): +diff --git a/scipy/linalg/_cythonized_array_utils.pyx b/scipy/linalg/_cythonized_array_utils.pyx +index ea1c58de..9db71007 100644 +--- a/scipy/linalg/_cythonized_array_utils.pyx ++++ b/scipy/linalg/_cythonized_array_utils.pyx +@@ -15,7 +15,7 @@ __all__ = ['bandwidth', 'issymmetric', 'ishermitian'] + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef void swap_c_and_f_layout(lapack_t *a, lapack_t *b, int r, int c, int n) nogil: ++cdef void swap_c_and_f_layout(lapack_t *a, lapack_t *b, int r, int c, int n) noexcept nogil: + """Recursive matrix transposition for square arrays""" + cdef int i, j, ith_row, r2, c2 + cdef lapack_t *bb=b +@@ -129,7 +129,7 @@ def bandwidth_noncontig(np_numeric_t[:, :]A): + @cython.initializedcheck(False) + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline (int, int) band_check_internal_c(np_numeric_t[:, ::1]A) nogil: ++cdef inline (int, int) band_check_internal_c(np_numeric_t[:, ::1]A) noexcept nogil: + cdef Py_ssize_t n = A.shape[0], m = A.shape[1] + cdef Py_ssize_t lower_band = 0, upper_band = 0, r, c + cdef np_numeric_t zero = 0 +@@ -160,7 +160,7 @@ cdef inline (int, int) band_check_internal_c(np_numeric_t[:, ::1]A) nogil: + @cython.initializedcheck(False) + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline (int, int) band_check_internal_noncontig(np_numeric_t[:, :]A) nogil: ++cdef inline (int, int) band_check_internal_noncontig(np_numeric_t[:, :]A) noexcept nogil: + cdef Py_ssize_t n = A.shape[0], m = A.shape[1] + cdef Py_ssize_t lower_band = 0, upper_band = 0, r, c + cdef np_numeric_t zero = 0 +@@ -295,7 +295,7 @@ def is_sym_her_real_noncontig(np_numeric_t[:, :]A): + @cython.initializedcheck(False) + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline bint is_sym_her_real_c_internal(np_numeric_t[:, ::1]A) nogil: ++cdef inline bint is_sym_her_real_c_internal(np_numeric_t[:, ::1]A) noexcept nogil: + cdef Py_ssize_t n = A.shape[0], r, c + + for r in xrange(n): +@@ -308,7 +308,7 @@ cdef inline bint is_sym_her_real_c_internal(np_numeric_t[:, ::1]A) nogil: + @cython.initializedcheck(False) + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline bint is_sym_her_real_noncontig_internal(np_numeric_t[:, :]A) nogil: ++cdef inline bint is_sym_her_real_noncontig_internal(np_numeric_t[:, :]A) noexcept nogil: + cdef Py_ssize_t n = A.shape[0], r, c + + for r in xrange(n): +@@ -438,7 +438,7 @@ def is_sym_her_complex_noncontig(np_complex_numeric_t[:, :]A): + @cython.initializedcheck(False) + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline bint is_sym_her_complex_c_internal(np_complex_numeric_t[:, ::1]A) nogil: ++cdef inline bint is_sym_her_complex_c_internal(np_complex_numeric_t[:, ::1]A) noexcept nogil: + cdef Py_ssize_t n = A.shape[0], r, c + + for r in xrange(n): +@@ -450,7 +450,7 @@ cdef inline bint is_sym_her_complex_c_internal(np_complex_numeric_t[:, ::1]A) no + @cython.initializedcheck(False) + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline bint is_sym_her_complex_noncontig_internal(np_complex_numeric_t[:, :]A) nogil: ++cdef inline bint is_sym_her_complex_noncontig_internal(np_complex_numeric_t[:, :]A) noexcept nogil: + cdef Py_ssize_t n = A.shape[0], r, c + + for r in xrange(n): +diff --git a/scipy/linalg/_decomp_update.pyx.in b/scipy/linalg/_decomp_update.pyx.in +index e5801edf..2905f357 100644 +--- a/scipy/linalg/_decomp_update.pyx.in ++++ b/scipy/linalg/_decomp_update.pyx.in +@@ -84,50 +84,50 @@ ctypedef fused blas_t: + float_complex + double_complex + +-cdef inline blas_t* index2(blas_t* a, int* as, int i, int j) nogil: ++cdef inline blas_t* index2(blas_t* a, int* as, int i, int j) noexcept nogil: + return a + i*as[0] + j*as[1] + +-cdef inline blas_t* index1(blas_t* a, int* as, int i) nogil: ++cdef inline blas_t* index1(blas_t* a, int* as, int i) noexcept nogil: + return a + i*as[0] + +-cdef inline blas_t* row(blas_t* a, int* as, int i) nogil: ++cdef inline blas_t* row(blas_t* a, int* as, int i) noexcept nogil: + return a + i*as[0] + +-cdef inline blas_t* col(blas_t* a, int* as, int j) nogil: ++cdef inline blas_t* col(blas_t* a, int* as, int j) noexcept nogil: + return a + j*as[1] + +-cdef inline void copy(int n, blas_t* x, int incx, blas_t* y, int incy) nogil: ++cdef inline void copy(int n, blas_t* x, int incx, blas_t* y, int incy) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}copy(&n, x, &incx, y, &incy) + {{endfor}} + +-cdef inline void swap(int n, blas_t* x, int incx, blas_t* y, int incy) nogil: ++cdef inline void swap(int n, blas_t* x, int incx, blas_t* y, int incy) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}swap(&n, x, &incx, y, &incy) + {{endfor}} + +-cdef inline void scal(int n, blas_t a, blas_t* x, int incx) nogil: ++cdef inline void scal(int n, blas_t a, blas_t* x, int incx) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}scal(&n, &a, x, &incx) + {{endfor}} + + cdef inline void axpy(int n, blas_t a, blas_t* x, int incx, +- blas_t* y, int incy) nogil: ++ blas_t* y, int incy) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}axpy(&n, &a, x, &incx, y, &incy) + {{endfor}} + +-cdef inline blas_t nrm2(int n, blas_t* x, int incx) nogil: ++cdef inline blas_t nrm2(int n, blas_t* x, int incx) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, ['s', 'd', 'sc', 'dz'])}} + {{COND}} blas_t is {{CNAME}}: + return blas_pointers.{{C}}nrm2(&n, x, &incx) + {{endfor}} + +-cdef inline void lartg(blas_t* a, blas_t* b, blas_t* c, blas_t* s) nogil: ++cdef inline void lartg(blas_t* a, blas_t* b, blas_t* c, blas_t* s) noexcept nogil: + cdef blas_t g + if blas_t is float: + lapack_pointers.slartg(a, b, c, s, &g) +@@ -144,7 +144,7 @@ cdef inline void lartg(blas_t* a, blas_t* b, blas_t* c, blas_t* s) nogil: + b[0] = 0 + + cdef inline void rot(int n, blas_t* x, int incx, blas_t* y, int incy, +- blas_t c, blas_t s) nogil: ++ blas_t c, blas_t s) noexcept nogil: + if blas_t is float: + blas_pointers.srot(&n, x, &incx, y, &incy, &c, &s) + elif blas_t is double: +@@ -155,21 +155,21 @@ cdef inline void rot(int n, blas_t* x, int incx, blas_t* y, int incy, + lapack_pointers.zrot(&n, x, &incx, y, &incy, &c, &s) + + cdef inline void larfg(int n, blas_t* alpha, blas_t* x, int incx, +- blas_t* tau) nogil: ++ blas_t* tau) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + lapack_pointers.{{C}}larfg(&n, alpha, x, &incx, tau) + {{endfor}} + + cdef inline void larf(char* side, int m, int n, blas_t* v, int incv, blas_t tau, +- blas_t* c, int ldc, blas_t* work) nogil: ++ blas_t* c, int ldc, blas_t* work) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + lapack_pointers.{{C}}larf(side, &m, &n, v, &incv, &tau, c, &ldc, work) + {{endfor}} + + cdef inline void ger(int m, int n, blas_t alpha, blas_t* x, int incx, blas_t* y, +- int incy, blas_t* a, int lda) nogil: ++ int incy, blas_t* a, int lda) noexcept nogil: + if blas_t is float: + blas_pointers.sger(&m, &n, &alpha, x, &incx, y, &incy, a, &lda) + elif blas_t is double: +@@ -180,7 +180,7 @@ cdef inline void ger(int m, int n, blas_t alpha, blas_t* x, int incx, blas_t* y, + blas_pointers.zgeru(&m, &n, &alpha, x, &incx, y, &incy, a, &lda) + + cdef inline void gemv(char* trans, int m, int n, blas_t alpha, blas_t* a, +- int lda, blas_t* x, int incx, blas_t beta, blas_t* y, int incy) nogil: ++ int lda, blas_t* x, int incx, blas_t beta, blas_t* y, int incy) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}gemv(trans, &m, &n, &alpha, a, &lda, x, &incx, +@@ -189,7 +189,7 @@ cdef inline void gemv(char* trans, int m, int n, blas_t alpha, blas_t* a, + + cdef inline void gemm(char* transa, char* transb, int m, int n, int k, + blas_t alpha, blas_t* a, int lda, blas_t* b, int ldb, blas_t beta, +- blas_t* c, int ldc) nogil: ++ blas_t* c, int ldc) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}gemm(transa, transb, &m, &n, &k, &alpha, a, &lda, +@@ -197,7 +197,7 @@ cdef inline void gemm(char* transa, char* transb, int m, int n, int k, + {{endfor}} + + cdef inline void trmm(char* side, char* uplo, char* transa, char* diag, int m, +- int n, blas_t alpha, blas_t* a, int lda, blas_t* b, int ldb) nogil: ++ int n, blas_t alpha, blas_t* a, int lda, blas_t* b, int ldb) noexcept nogil: + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: + blas_pointers.{{C}}trmm(side, uplo, transa, diag, &m, &n, &alpha, a, &lda, +@@ -205,7 +205,7 @@ cdef inline void trmm(char* side, char* uplo, char* transa, char* diag, int m, + {{endfor}} + + cdef inline int geqrf(int m, int n, blas_t* a, int lda, blas_t* tau, +- blas_t* work, int lwork) nogil: ++ blas_t* work, int lwork) noexcept nogil: + cdef int info + {{for COND, CNAME, C in zip(CONDS, CNAMES, PREFIX)}} + {{COND}} blas_t is {{CNAME}}: +@@ -214,7 +214,7 @@ cdef inline int geqrf(int m, int n, blas_t* a, int lda, blas_t* tau, + return info + + cdef inline int ormqr(char* side, char* trans, int m, int n, int k, blas_t* a, +- int lda, blas_t* tau, blas_t* c, int ldc, blas_t* work, int lwork) nogil: ++ int lda, blas_t* tau, blas_t* c, int ldc, blas_t* work, int lwork) noexcept nogil: + cdef int info = 0 + if blas_t is float: + lapack_pointers.sormqr(side, trans, &m, &n, &k, a, &lda, tau, c, &ldc, +@@ -234,20 +234,20 @@ cdef inline int ormqr(char* side, char* trans, int m, int n, int k, blas_t* a, + # Utility routines + #------------------------------------------------------------------------------ + +-cdef void blas_t_conj(int n, blas_t* x, int* xs) nogil: ++cdef void blas_t_conj(int n, blas_t* x, int* xs) noexcept nogil: + cdef int j + if blas_t is float_complex or blas_t is double_complex: + for j in range(n): + index1(x, xs, j)[0] = index1(x, xs, j)[0].conjugate() + +-cdef void blas_t_2d_conj(int m, int n, blas_t* x, int* xs) nogil: ++cdef void blas_t_2d_conj(int m, int n, blas_t* x, int* xs) noexcept nogil: + cdef int i, j + if blas_t is float_complex or blas_t is double_complex: + for i in range(m): + for j in range(n): + index2(x, xs, i, j)[0] = index2(x, xs, i, j)[0].conjugate() + +-cdef blas_t blas_t_sqrt(blas_t x) nogil: ++cdef blas_t blas_t_sqrt(blas_t x) noexcept nogil: + if blas_t is float: + return sqrt(x) + elif blas_t is double: +@@ -257,19 +257,19 @@ cdef blas_t blas_t_sqrt(blas_t x) nogil: + else: + return sqrt((&x)[0]) + +-cdef bint blas_t_less_than(blas_t x, blas_t y) nogil: ++cdef bint blas_t_less_than(blas_t x, blas_t y) noexcept nogil: + if blas_t is float or blas_t is double: + return x < y + else: + return x.real < y.real + +-cdef bint blas_t_less_equal(blas_t x, blas_t y) nogil: ++cdef bint blas_t_less_equal(blas_t x, blas_t y) noexcept nogil: + if blas_t is float or blas_t is double: + return x <= y + else: + return x.real <= y.real + +-cdef int to_lwork(blas_t a, blas_t b) nogil: ++cdef int to_lwork(blas_t a, blas_t b) noexcept nogil: + cdef int ai, bi + if blas_t is float or blas_t is double: + ai = a +@@ -286,7 +286,7 @@ cdef int to_lwork(blas_t a, blas_t b) nogil: + # QR update routines start here. + #------------------------------------------------------------------------------ + +-cdef bint reorthx(int m, int n, blas_t* q, int* qs, bint qisF, int j, blas_t* u, blas_t* s) nogil: ++cdef bint reorthx(int m, int n, blas_t* q, int* qs, bint qisF, int j, blas_t* u, blas_t* s) noexcept nogil: + # U should be all zeros on entry., and m > 1 + cdef blas_t unorm, snorm, wnorm, wpnorm, sigma_max, sigma_min, rc + cdef char* T = 'T' +@@ -347,7 +347,7 @@ cdef bint reorthx(int m, int n, blas_t* q, int* qs, bint qisF, int j, blas_t* u, + + cdef int thin_qr_row_delete(int m, int n, blas_t* q, int* qs, bint qisF, + blas_t* r, int* rs, int k, int p_eco, +- int p_full) nogil: ++ int p_full) noexcept nogil: + cdef int i, j, argmin_row_norm + cdef size_t usize = (m + 3*n + 1) * sizeof(blas_t) + cdef blas_t* s +@@ -407,7 +407,7 @@ cdef int thin_qr_row_delete(int m, int n, blas_t* q, int* qs, bint qisF, + return 1 + + cdef void qr_block_row_delete(int m, int n, blas_t* q, int* qs, +- blas_t* r, int* rs, int k, int p) nogil: ++ blas_t* r, int* rs, int k, int p) noexcept nogil: + cdef int i, j + cdef blas_t c,s + cdef blas_t* W +@@ -443,7 +443,7 @@ cdef void qr_block_row_delete(int m, int n, blas_t* q, int* qs, + c, s.conjugate()) + + cdef void qr_col_delete(int m, int o, int n, blas_t* q, int* qs, blas_t* r, +- int* rs, int k) nogil: ++ int* rs, int k) noexcept nogil: + """ + Here we support both full and economic decomposition, q is (m,o), and r + is (o, n). +@@ -457,7 +457,7 @@ cdef void qr_col_delete(int m, int o, int n, blas_t* q, int* qs, blas_t* r, + hessenberg_qr(m, n-1, q, qs, r, rs, k) + + cdef int qr_block_col_delete(int m, int o, int n, blas_t* q, int* qs, +- blas_t* r, int* rs, int k, int p) nogil: ++ blas_t* r, int* rs, int k, int p) noexcept nogil: + """ + Here we support both full and economic decomposition, q is (m,o), and r + is (o, n). +@@ -481,7 +481,7 @@ cdef int qr_block_col_delete(int m, int o, int n, blas_t* q, int* qs, + return 0 + + cdef void thin_qr_row_insert(int m, int n, blas_t* q, int* qs, blas_t* r, +- int* rs, blas_t* u, int* us, int k) nogil: ++ int* rs, blas_t* u, int* us, int k) noexcept nogil: + cdef int j + cdef blas_t c, s + +@@ -497,7 +497,7 @@ cdef void thin_qr_row_insert(int m, int n, blas_t* q, int* qs, blas_t* r, + swap(n, row(q, qs, j), qs[1], row(q, qs, j-1), qs[1]) + + cdef void qr_row_insert(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, +- int k) nogil: ++ int k) noexcept nogil: + cdef int j + cdef blas_t c, s + cdef int limit = min(m-1, n) +@@ -514,7 +514,7 @@ cdef void qr_row_insert(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, + + cdef int thin_qr_block_row_insert(int m, int n, blas_t* q, int* qs, blas_t* r, + int* rs, blas_t* u, int* us, int k, +- int p) nogil: ++ int p) noexcept nogil: + # as below this should someday call lapack's xtpqrt. + cdef int j + cdef blas_t rjj, tau +@@ -568,7 +568,7 @@ cdef int thin_qr_block_row_insert(int m, int n, blas_t* q, int* qs, blas_t* r, + libc.stdlib.free(work) + + cdef int qr_block_row_insert(int m, int n, blas_t* q, int* qs, +- blas_t* r, int* rs, int k, int p) nogil: ++ blas_t* r, int* rs, int k, int p) noexcept nogil: + # this should someday call lapack's xtpqrt (requires lapack >= 3.4 + # released nov 11). RHEL6's atlas doesn't seem to have it. + # On input this looks something like this: +@@ -620,7 +620,7 @@ cdef int qr_block_row_insert(int m, int n, blas_t* q, int* qs, + + cdef int thin_qr_col_insert(int m, int n, blas_t* q, int* qs, blas_t* r, + int* rs, blas_t* u, int* us, int k, int p_eco, +- int p_full, blas_t* rcond) nogil: ++ int p_full, blas_t* rcond) noexcept nogil: + # here q and r will always be fortran ordered since we have to allocate them + cdef int i, j, info + cdef blas_t c, sn +@@ -683,7 +683,7 @@ cdef int thin_qr_col_insert(int m, int n, blas_t* q, int* qs, blas_t* r, + return 0 + + cdef void qr_col_insert(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, +- int k) nogil: ++ int k) noexcept nogil: + cdef int j + cdef blas_t c, s, temp, tau + cdef blas_t* work +@@ -700,7 +700,7 @@ cdef void qr_col_insert(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, + rot(m, col(q, qs, j), qs[0], col(q, qs, j+1), qs[0], c, s.conjugate()) + + cdef int qr_block_col_insert(int m, int n, blas_t* q, int* qs, +- blas_t* r, int* rs, int k, int p) nogil: ++ blas_t* r, int* rs, int k, int p) noexcept nogil: + cdef int i, j + cdef blas_t c, s + cdef blas_t* tau = NULL +@@ -802,7 +802,7 @@ cdef int qr_block_col_insert(int m, int n, blas_t* q, int* qs, + + cdef void thin_qr_rank_1_update(int m, int n, blas_t* q, int* qs, bint qisF, + blas_t* r, int* rs, blas_t* u, int* us, blas_t* v, int* vs, blas_t* s, +- int* ss) nogil: ++ int* ss) noexcept nogil: + """Assume that q is (M,N) and either C or F contiguous, r is (N,N), u is M, + and V is N. s is a 2*n work array. + """ +@@ -844,7 +844,7 @@ cdef void thin_qr_rank_1_update(int m, int n, blas_t* q, int* qs, bint qisF, + + cdef void thin_qr_rank_p_update(int m, int n, int p, blas_t* q, int* qs, + bint qisF, blas_t* r, int* rs, blas_t* u, int* us, blas_t* v, int* vs, +- blas_t* s, int* ss) nogil: ++ blas_t* s, int* ss) noexcept nogil: + """Assume that q is (M,N) and either C or F contiguous, r is (N,N), u is + (M,p) and V is (N,p). s is a 2*n work array. + """ +@@ -855,7 +855,7 @@ cdef void thin_qr_rank_p_update(int m, int n, int p, blas_t* q, int* qs, + col(v, vs, j), vs, s, ss) + + cdef void qr_rank_1_update(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, +- blas_t* u, int* us, blas_t* v, int* vs) nogil: ++ blas_t* u, int* us, blas_t* v, int* vs) noexcept nogil: + """ here we will assume that the u = Q.T.dot(u) and not the bare u. + if A is MxN then q is MxM, r is MxN, u is M and v is N. + e.g. currently assuming full matrices. +@@ -889,7 +889,7 @@ cdef void qr_rank_1_update(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, + # no return, return q, r from python driver. + + cdef int qr_rank_p_update(int m, int n, int p, blas_t* q, int* qs, blas_t* r, +- int* rs, blas_t* u, int* us, blas_t* v, int* vs) nogil: ++ int* rs, blas_t* u, int* us, blas_t* v, int* vs) noexcept nogil: + cdef int i, j + cdef blas_t c, s + cdef blas_t* tau = NULL +@@ -981,7 +981,7 @@ cdef int qr_rank_p_update(int m, int n, int p, blas_t* q, int* qs, blas_t* r, + return 0 + + cdef void hessenberg_qr(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, +- int k) nogil: ++ int k) noexcept nogil: + """Reduce an upper hessenberg matrix r, to upper triangular, starting in + row j. Apply these transformation to q as well. Both full and economic + decompositions are supported here. +@@ -1002,7 +1002,7 @@ cdef void hessenberg_qr(int m, int n, blas_t* q, int* qs, blas_t* r, int* rs, + rot(m, col(q, qs, j), qs[0], col(q, qs, j+1), qs[0], c, s.conjugate()) + + cdef void p_subdiag_qr(int m, int o, int n, blas_t* q, int* qs, blas_t* r, int* rs, +- int k, int p, blas_t* work) nogil: ++ int k, int p, blas_t* work) noexcept nogil: + """ Reduce a matrix r to upper triangular form by eliminating the lower p + subdiagionals using reflectors. Both full and economic decompositions + are supported here. In either case, q is (m,o) and r is (o,n) +@@ -1041,7 +1041,7 @@ cdef void p_subdiag_qr(int m, int o, int n, blas_t* q, int* qs, blas_t* r, int* + index2(r, rs, j, j)[0] = rjj + + cdef int reorth(int m, int n, blas_t* q, int* qs, bint qisF, blas_t* u, +- int* us, blas_t* s, blas_t* RCOND) nogil: ++ int* us, blas_t* s, blas_t* RCOND) noexcept nogil: + """Given a (m,n) matrix q with orthonormal columns and a (m,) vector u, + find vectors s, w and scalar p such that u = Qs + pw where w is of unit + length and orthogonal to the columns of q. +@@ -1181,7 +1181,7 @@ def _form_qTu(object a, object b): + return qTu + + cdef form_qTu(cnp.ndarray q, cnp.ndarray u, void* qTuvoid, int* qTus, +- int k): ++ int k) noexcept: + """ assuming here that q and u have compatible shapes, and are the same + type + Q is contiguous. This function is preferable over simply + calling np.dot for two reasons: 1) this output is always in F order, 2) +@@ -1312,7 +1312,7 @@ cdef form_qTu(cnp.ndarray q, cnp.ndarray u, void* qTuvoid, int* qTus, + else: + raise ValueError('q must be either F or C contiguous') + +-cdef validate_array(cnp.ndarray a, bint chkfinite): ++cdef validate_array(cnp.ndarray a, bint chkfinite) noexcept: + # here we check that a has positive strides and that its size is small + # enough to fit in into an int, as BLAS/LAPACK require + cdef bint copy = False +@@ -1335,7 +1335,7 @@ cdef validate_array(cnp.ndarray a, bint chkfinite): + return a + + cdef tuple validate_qr(object q0, object r0, bint overwrite_q, int q_order, +- bint overwrite_r, int r_order, bint chkfinite): ++ bint overwrite_r, int r_order, bint chkfinite) noexcept: + cdef cnp.ndarray Q + cdef cnp.ndarray R + cdef int typecode +@@ -1388,7 +1388,7 @@ cdef tuple validate_qr(object q0, object r0, bint overwrite_q, int q_order, + + return Q, R, typecode, Q.shape[0], R.shape[1], economic + +-cdef void* extract(cnp.ndarray arr, int* arrs): ++cdef void* extract(cnp.ndarray arr, int* arrs) noexcept: + with cython.cdivision(True): # Assumes itemsize != 0. + if arr.ndim == 2: + arrs[0] = arr.strides[0] / cnp.PyArray_ITEMSIZE(arr) +@@ -1757,7 +1757,7 @@ def qr_insert(Q, R, u, k, which='row', rcond=None, overwrite_qru=False, check_fi + else: + raise ValueError("'which' must be either 'row' or 'col'") + +-cdef qr_insert_row(Q, R, u, int k, bint overwrite_qru, bint check_finite): ++cdef qr_insert_row(Q, R, u, int k, bint overwrite_qru, bint check_finite) noexcept: + cdef cnp.ndarray q1, r1, u1, qnew, rnew + cdef int j + cdef int u_flags = cnp.NPY_BEHAVED_NS | cnp.NPY_ELEMENTSTRIDES +@@ -1877,7 +1877,7 @@ cdef qr_insert_row(Q, R, u, int k, bint overwrite_qru, bint check_finite): + raise MemoryError('Unable to allocate memory for array') + return qnew, rnew + +-cdef qr_insert_col(Q, R, u, int k, rcond, bint overwrite_qru, bint check_finite): ++cdef qr_insert_col(Q, R, u, int k, rcond, bint overwrite_qru, bint check_finite) noexcept: + cdef cnp.ndarray q1, r1, u1, qnew, rnew + cdef int j + cdef int q_flags = ARRAY_ANYORDER +diff --git a/scipy/linalg/_generate_pyx.py b/scipy/linalg/_generate_pyx.py +index 4042bc09..f521d473 100644 +--- a/scipy/linalg/_generate_pyx.py ++++ b/scipy/linalg/_generate_pyx.py +@@ -46,7 +46,7 @@ def arg_names_and_types(args): + pyx_func_template = """ + cdef extern from "{header_name}": + void _fortran_{name} "F_FUNC({name}wrp, {upname}WRP)"({ret_type} *out, {fort_args}) nogil +-cdef {ret_type} {name}({args}) nogil: ++cdef {ret_type} {name}({args}) noexcept nogil: + cdef {ret_type} out + _fortran_{name}(&out, {argnames}) + return out +@@ -94,7 +94,7 @@ def pyx_decl_func(name, ret_type, args, header_name): + + pyx_sub_template = """cdef extern from "{header_name}": + void _fortran_{name} "F_FUNC({name},{upname})"({fort_args}) nogil +-cdef void {name}({args}) nogil: ++cdef void {name}({args}) noexcept nogil: + _fortran_{name}({argnames}) + """ + +@@ -222,30 +222,30 @@ blas_py_wrappers = """ + + # Python-accessible wrappers for testing: + +-cdef inline bint _is_contiguous(double[:,:] a, int axis) nogil: ++cdef inline bint _is_contiguous(double[:,:] a, int axis) noexcept nogil: + return (a.strides[axis] == sizeof(a[0,0]) or a.shape[axis] == 1) + +-cpdef float complex _test_cdotc(float complex[:] cx, float complex[:] cy) nogil: ++cpdef float complex _test_cdotc(float complex[:] cx, float complex[:] cy) noexcept nogil: + cdef: + int n = cx.shape[0] + int incx = cx.strides[0] // sizeof(cx[0]) + int incy = cy.strides[0] // sizeof(cy[0]) + return cdotc(&n, &cx[0], &incx, &cy[0], &incy) + +-cpdef float complex _test_cdotu(float complex[:] cx, float complex[:] cy) nogil: ++cpdef float complex _test_cdotu(float complex[:] cx, float complex[:] cy) noexcept nogil: + cdef: + int n = cx.shape[0] + int incx = cx.strides[0] // sizeof(cx[0]) + int incy = cy.strides[0] // sizeof(cy[0]) + return cdotu(&n, &cx[0], &incx, &cy[0], &incy) + +-cpdef double _test_dasum(double[:] dx) nogil: ++cpdef double _test_dasum(double[:] dx) noexcept nogil: + cdef: + int n = dx.shape[0] + int incx = dx.strides[0] // sizeof(dx[0]) + return dasum(&n, &dx[0], &incx) + +-cpdef double _test_ddot(double[:] dx, double[:] dy) nogil: ++cpdef double _test_ddot(double[:] dx, double[:] dy) noexcept nogil: + cdef: + int n = dx.shape[0] + int incx = dx.strides[0] // sizeof(dx[0]) +@@ -331,87 +331,87 @@ cpdef int _test_dgemm(double alpha, double[:,:] a, double[:,:] b, double beta, + raise ValueError("Input 'c' is neither C nor Fortran contiguous.") + return 0 + +-cpdef double _test_dnrm2(double[:] x) nogil: ++cpdef double _test_dnrm2(double[:] x) noexcept nogil: + cdef: + int n = x.shape[0] + int incx = x.strides[0] // sizeof(x[0]) + return dnrm2(&n, &x[0], &incx) + +-cpdef double _test_dzasum(double complex[:] zx) nogil: ++cpdef double _test_dzasum(double complex[:] zx) noexcept nogil: + cdef: + int n = zx.shape[0] + int incx = zx.strides[0] // sizeof(zx[0]) + return dzasum(&n, &zx[0], &incx) + +-cpdef double _test_dznrm2(double complex[:] x) nogil: ++cpdef double _test_dznrm2(double complex[:] x) noexcept nogil: + cdef: + int n = x.shape[0] + int incx = x.strides[0] // sizeof(x[0]) + return dznrm2(&n, &x[0], &incx) + +-cpdef int _test_icamax(float complex[:] cx) nogil: ++cpdef int _test_icamax(float complex[:] cx) noexcept nogil: + cdef: + int n = cx.shape[0] + int incx = cx.strides[0] // sizeof(cx[0]) + return icamax(&n, &cx[0], &incx) + +-cpdef int _test_idamax(double[:] dx) nogil: ++cpdef int _test_idamax(double[:] dx) noexcept nogil: + cdef: + int n = dx.shape[0] + int incx = dx.strides[0] // sizeof(dx[0]) + return idamax(&n, &dx[0], &incx) + +-cpdef int _test_isamax(float[:] sx) nogil: ++cpdef int _test_isamax(float[:] sx) noexcept nogil: + cdef: + int n = sx.shape[0] + int incx = sx.strides[0] // sizeof(sx[0]) + return isamax(&n, &sx[0], &incx) + +-cpdef int _test_izamax(double complex[:] zx) nogil: ++cpdef int _test_izamax(double complex[:] zx) noexcept nogil: + cdef: + int n = zx.shape[0] + int incx = zx.strides[0] // sizeof(zx[0]) + return izamax(&n, &zx[0], &incx) + +-cpdef float _test_sasum(float[:] sx) nogil: ++cpdef float _test_sasum(float[:] sx) noexcept nogil: + cdef: + int n = sx.shape[0] + int incx = sx.shape[0] // sizeof(sx[0]) + return sasum(&n, &sx[0], &incx) + +-cpdef float _test_scasum(float complex[:] cx) nogil: ++cpdef float _test_scasum(float complex[:] cx) noexcept nogil: + cdef: + int n = cx.shape[0] + int incx = cx.strides[0] // sizeof(cx[0]) + return scasum(&n, &cx[0], &incx) + +-cpdef float _test_scnrm2(float complex[:] x) nogil: ++cpdef float _test_scnrm2(float complex[:] x) noexcept nogil: + cdef: + int n = x.shape[0] + int incx = x.strides[0] // sizeof(x[0]) + return scnrm2(&n, &x[0], &incx) + +-cpdef float _test_sdot(float[:] sx, float[:] sy) nogil: ++cpdef float _test_sdot(float[:] sx, float[:] sy) noexcept nogil: + cdef: + int n = sx.shape[0] + int incx = sx.strides[0] // sizeof(sx[0]) + int incy = sy.strides[0] // sizeof(sy[0]) + return sdot(&n, &sx[0], &incx, &sy[0], &incy) + +-cpdef float _test_snrm2(float[:] x) nogil: ++cpdef float _test_snrm2(float[:] x) noexcept nogil: + cdef: + int n = x.shape[0] + int incx = x.shape[0] // sizeof(x[0]) + return snrm2(&n, &x[0], &incx) + +-cpdef double complex _test_zdotc(double complex[:] zx, double complex[:] zy) nogil: ++cpdef double complex _test_zdotc(double complex[:] zx, double complex[:] zy) noexcept nogil: + cdef: + int n = zx.shape[0] + int incx = zx.strides[0] // sizeof(zx[0]) + int incy = zy.strides[0] // sizeof(zy[0]) + return zdotc(&n, &zx[0], &incx, &zy[0], &incy) + +-cpdef double complex _test_zdotu(double complex[:] zx, double complex[:] zy) nogil: ++cpdef double complex _test_zdotu(double complex[:] zx, double complex[:] zy) noexcept nogil: + cdef: + int n = zx.shape[0] + int incx = zx.strides[0] // sizeof(zx[0]) +@@ -457,10 +457,10 @@ def generate_lapack_pyx(func_sigs, sub_sigs, all_sigs, header_name): + return preamble + funcs + subs + lapack_py_wrappers + + +-pxd_template = """ctypedef {ret_type} {name}_t({args}) nogil ++pxd_template = """ctypedef {ret_type} {name}_t({args}) noexcept nogil + cdef {name}_t *{name}_f + """ +-pxd_template = """cdef {ret_type} {name}({args}) nogil ++pxd_template = """cdef {ret_type} {name}({args}) noexcept nogil + """ + + +diff --git a/scipy/linalg/_matfuncs_expm.pyx.in b/scipy/linalg/_matfuncs_expm.pyx.in +index 41b42c87..61383681 100644 +--- a/scipy/linalg/_matfuncs_expm.pyx.in ++++ b/scipy/linalg/_matfuncs_expm.pyx.in +@@ -36,7 +36,7 @@ prefixes = ['s', 'd', 'c', 'z'] + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef double norm1(lapack_t[:, ::1] A): ++cdef double norm1(lapack_t[:, ::1] A) noexcept: + """ + Fast 1-norm computation for C-contiguous square arrays. + Regardless of the dtype we work in double precision to prevent overflows +@@ -79,7 +79,7 @@ cdef double norm1(lapack_t[:, ::1] A): + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef double kth_power_norm_d(double* A, double* v1, double* v2, Py_ssize_t n, int spins): ++cdef double kth_power_norm_d(double* A, double* v1, double* v2, Py_ssize_t n, int spins) noexcept: + cdef int k, int_one = 1, intn = n + cdef double one =1., zero = 0. + for k in range(spins): +@@ -97,7 +97,7 @@ cdef double kth_power_norm_d(double* A, double* v1, double* v2, Py_ssize_t n, in + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef pick_pade_structure_{{ pfx }}({{ tname }}[:, :, ::1] Am): ++cdef pick_pade_structure_{{ pfx }}({{ tname }}[:, :, ::1] Am) noexcept: + cdef Py_ssize_t n = Am.shape[1], i, j, k + cdef int lm = 0, s = 0, intn = n, n2= intn*intn, int_one = 1 + cdef {{ tname }}[:, :, ::1] Amv = Am +@@ -221,7 +221,7 @@ cdef pick_pade_structure_{{ pfx }}({{ tname }}[:, :, ::1] Am): + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef void pade_357_UV_calc_{{ pfx }}({{ tname }}[:, :, ::]Am, int n, int m) nogil: ++cdef void pade_357_UV_calc_{{ pfx }}({{ tname }}[:, :, ::]Am, int n, int m) noexcept nogil: + cdef {{ tname }} b[7] + cdef int *ipiv = malloc(n*sizeof(int)) + cdef int i, info, n2 = n*n, int_one = 1 +@@ -317,7 +317,7 @@ cdef void pade_357_UV_calc_{{ pfx }}({{ tname }}[:, :, ::]Am, int n, int m) nogi + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef void pade_9_UV_calc_{{ pfx }}({{ tname }}[:, :, ::]Am, int n) nogil: ++cdef void pade_9_UV_calc_{{ pfx }}({{ tname }}[:, :, ::]Am, int n) noexcept nogil: + cdef {{ tname }} b[9] + cdef {{ tname }} *work = <{{ tname }}*>malloc(n*n*sizeof({{ tname }})) + cdef int *ipiv = malloc(n*sizeof(int)) +@@ -382,7 +382,7 @@ cdef void pade_9_UV_calc_{{ pfx }}({{ tname }}[:, :, ::]Am, int n) nogil: + @cython.wraparound(False) + @cython.boundscheck(False) + @cython.initializedcheck(False) +-cdef void pade_13_UV_calc_{{ pfx }}({{ tname }}[:, :, ::1]Am, int n) nogil: ++cdef void pade_13_UV_calc_{{ pfx }}({{ tname }}[:, :, ::1]Am, int n) noexcept nogil: + cdef {{ tname }} *work2 = <{{ tname }}*>malloc(n*n*sizeof({{ tname }})) + cdef {{ tname }} *work3 = <{{ tname }}*>malloc(n*n*sizeof({{ tname }})) + cdef {{ tname }} *work4 = <{{ tname }}*>malloc(n*n*sizeof({{ tname }})) +diff --git a/scipy/ndimage/src/_cytest.pxd b/scipy/ndimage/src/_cytest.pxd +index c022e22b..d0788783 100644 +--- a/scipy/ndimage/src/_cytest.pxd ++++ b/scipy/ndimage/src/_cytest.pxd +@@ -1,8 +1,8 @@ + from numpy cimport npy_intp as intp + + cdef int _filter1d(double *input_line, intp input_length, double *output_line, +- intp output_length, void *callback_data) ++ intp output_length, void *callback_data) noexcept + cdef int _filter2d(double *buffer, intp filter_size, double *res, +- void *callback_data) ++ void *callback_data) noexcept + cdef int _transform(intp *output_coordinates, double *input_coordinates, +- int output_rank, int input_rank, void *callback_data) ++ int output_rank, int input_rank, void *callback_data) noexcept +diff --git a/scipy/ndimage/src/_cytest.pyx b/scipy/ndimage/src/_cytest.pyx +index 3948d97a..d63c9806 100644 +--- a/scipy/ndimage/src/_cytest.pyx ++++ b/scipy/ndimage/src/_cytest.pyx +@@ -8,18 +8,18 @@ from numpy cimport npy_intp as intp + + np.import_array() + +-cdef void _destructor(obj): ++cdef void _destructor(obj) noexcept: + cdef void *callback_data = PyCapsule_GetContext(obj) + PyMem_Free(callback_data) + + +-cdef void _destructor_data(obj): ++cdef void _destructor_data(obj) noexcept: + cdef void *callback_data = PyCapsule_GetPointer(obj, NULL) + PyMem_Free(callback_data) + + + cdef int _filter1d(double *input_line, intp input_length, double *output_line, +- intp output_length, void *callback_data): ++ intp output_length, void *callback_data) noexcept: + cdef intp i, j + cdef intp filter_size = (callback_data)[0] + +@@ -65,7 +65,7 @@ def filter1d_capsule(intp filter_size): + + + cdef int _filter2d(double *buffer, intp filter_size, double *res, +- void *callback_data): ++ void *callback_data) noexcept: + cdef intp i + cdef double *weights = callback_data + +@@ -111,7 +111,7 @@ def filter2d_capsule(seq): + + + cdef int _transform(intp *output_coordinates, double *input_coordinates, +- int output_rank, int input_rank, void *callback_data): ++ int output_rank, int input_rank, void *callback_data) noexcept: + cdef intp i + cdef double shift = (callback_data)[0] + +diff --git a/scipy/ndimage/src/_ni_label.pyx b/scipy/ndimage/src/_ni_label.pyx +index d371f22b..284a52f4 100644 +--- a/scipy/ndimage/src/_ni_label.pyx ++++ b/scipy/ndimage/src/_ni_label.pyx +@@ -52,7 +52,7 @@ ctypedef fused data_t: + # the fused data is nonzero, BACKGROUND elsewhere + ###################################################################### + cdef void fused_nonzero_line(data_t *p, np.intp_t stride, +- np.uintp_t *line, np.intp_t L) nogil: ++ np.uintp_t *line, np.intp_t L) noexcept nogil: + cdef np.intp_t i + for i in range(L): + line[i] = FOREGROUND if \ +@@ -64,7 +64,7 @@ cdef void fused_nonzero_line(data_t *p, np.intp_t stride, + # Load a line from a fused data array to a np.uintp_t array + ###################################################################### + cdef void fused_read_line(data_t *p, np.intp_t stride, +- np.uintp_t *line, np.intp_t L) nogil: ++ np.uintp_t *line, np.intp_t L) noexcept nogil: + cdef np.intp_t i + for i in range(L): + line[i] = ( (( p) + i * stride))[0] +@@ -75,7 +75,7 @@ cdef void fused_read_line(data_t *p, np.intp_t stride, + # returning True if overflowed + ###################################################################### + cdef bint fused_write_line(data_t *p, np.intp_t stride, +- np.uintp_t *line, np.intp_t L) nogil: ++ np.uintp_t *line, np.intp_t L) noexcept nogil: + cdef np.intp_t i + for i in range(L): + # Check before overwrite, as this prevents us accidentally writing a 0 +@@ -104,11 +104,11 @@ def get_write_line(np.ndarray[data_t] a): + # Typedefs for referring to specialized instances of fused functions + ###################################################################### + ctypedef void (*nonzero_line_func_t)(void *p, np.intp_t stride, +- np.uintp_t *line, np.intp_t L) nogil ++ np.uintp_t *line, np.intp_t L) noexcept nogil + ctypedef void (*read_line_func_t)(void *p, np.intp_t stride, +- np.uintp_t *line, np.intp_t L) nogil ++ np.uintp_t *line, np.intp_t L) noexcept nogil + ctypedef bint (*write_line_func_t)(void *p, np.intp_t stride, +- np.uintp_t *line, np.intp_t L) nogil ++ np.uintp_t *line, np.intp_t L) noexcept nogil + + + ###################################################################### +@@ -116,7 +116,7 @@ ctypedef bint (*write_line_func_t)(void *p, np.intp_t stride, + ###################################################################### + cdef inline np.uintp_t mark_for_merge(np.uintp_t a, + np.uintp_t b, +- np.uintp_t *mergetable) nogil: ++ np.uintp_t *mergetable) noexcept nogil: + + cdef: + np.uintp_t orig_a, orig_b, minlabel +@@ -149,7 +149,7 @@ cdef inline np.uintp_t mark_for_merge(np.uintp_t a, + ###################################################################### + cdef inline np.uintp_t take_label_or_merge(np.uintp_t cur_label, + np.uintp_t neighbor_label, +- np.uintp_t *mergetable) nogil: ++ np.uintp_t *mergetable) noexcept nogil: + if neighbor_label == BACKGROUND: + return cur_label + if cur_label == FOREGROUND: +@@ -172,7 +172,7 @@ cdef np.uintp_t label_line_with_neighbor(np.uintp_t *line, + bint label_unlabeled, + bint use_previous, + np.uintp_t next_region, +- np.uintp_t *mergetable) nogil: ++ np.uintp_t *mergetable) noexcept nogil: + cdef: + np.intp_t i + +@@ -199,7 +199,7 @@ cdef np.uintp_t label_line_with_neighbor(np.uintp_t *line, + ###################################################################### + cpdef _label(np.ndarray input, + np.ndarray structure, +- np.ndarray output): ++ np.ndarray output) noexcept: + # check dimensions + # To understand the need for the casts to object, see + # http://trac.cython.org/cython_trac/ticket/302 +diff --git a/scipy/optimize/_bglu_dense.pyx b/scipy/optimize/_bglu_dense.pyx +index 376df50a..d6e8a35b 100644 +--- a/scipy/optimize/_bglu_dense.pyx ++++ b/scipy/optimize/_bglu_dense.pyx +@@ -17,7 +17,7 @@ __all__ = ['LU', 'BGLU'] + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef void swap_rows(self, double[:, ::1] H, int i): ++cdef void swap_rows(self, double[:, ::1] H, int i) noexcept: + """ + Swaps row i of H with next row; represents matrix product by PI_i + matrix described after matrix 5.10 +@@ -32,7 +32,7 @@ cdef void swap_rows(self, double[:, ::1] H, int i): + @cython.boundscheck(False) + @cython.wraparound(False) + @cython.cdivision(True) # not really important +-cdef double row_subtract(self, double[:, ::1] H, int i): ++cdef double row_subtract(self, double[:, ::1] H, int i) noexcept: + """ + Zeros first nonzero element of row i+1 of H by subtracting appropriate + multiple of row i; represents matrix product by matrix 5.10. Returns +@@ -52,7 +52,7 @@ cdef double row_subtract(self, double[:, ::1] H, int i): + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef void hess_lu(self, double[:, ::1] H, int i, double[:,::1] ops): ++cdef void hess_lu(self, double[:, ::1] H, int i, double[:,::1] ops) noexcept: + """ + Converts Hessenberg matrix H with first nonzero off-diagonal in + column i to upper triangular, recording elementary row operations. +@@ -78,7 +78,7 @@ cdef void hess_lu(self, double[:, ::1] H, int i, double[:,::1] ops): + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef void perform_ops(self, double[::1] y, double[:,::1] ops, bint rev = False): ++cdef void perform_ops(self, double[::1] y, double[:,::1] ops, bint rev = False) noexcept: + """ + Replays operations needed to convert Hessenberg matrix into upper + triangular form on a vector y. Equivalent to matrix multlication by +diff --git a/scipy/optimize/_highs/cython/src/_highs_wrapper.pyx b/scipy/optimize/_highs/cython/src/_highs_wrapper.pyx +index 476f3097..519730f3 100644 +--- a/scipy/optimize/_highs/cython/src/_highs_wrapper.pyx ++++ b/scipy/optimize/_highs/cython/src/_highs_wrapper.pyx +@@ -68,7 +68,7 @@ for _r in _ref_opts.records: + _ref_opt_lookup[_r.name] = _r + + +-cdef str _opt_warning(string name, val, valid_set=None): ++cdef str _opt_warning(string name, val, valid_set=None) noexcept: + cdef OptionRecord * r = _ref_opt_lookup[name] + + # BOOL +@@ -113,7 +113,7 @@ cdef str _opt_warning(string name, val, valid_set=None): + 'See documentation for valid options. ' + 'Using default.' % (name.decode(), str(val))) + +-cdef apply_options(dict options, Highs & highs): ++cdef apply_options(dict options, Highs & highs) noexcept: + '''Take options from dictionary and apply to HiGHS object.''' + + # Initialize for error checking +diff --git a/scipy/optimize/cython_optimize/_zeros.pxd b/scipy/optimize/cython_optimize/_zeros.pxd +index 1ae32c9f..c6241d02 100644 +--- a/scipy/optimize/cython_optimize/_zeros.pxd ++++ b/scipy/optimize/cython_optimize/_zeros.pxd +@@ -18,16 +18,16 @@ ctypedef struct zeros_full_output: + + cdef double bisect(callback_type f, double xa, double xb, void* args, + double xtol, double rtol, int iter, +- zeros_full_output *full_output) nogil ++ zeros_full_output *full_output) noexcept nogil + + cdef double ridder(callback_type f, double xa, double xb, void* args, + double xtol, double rtol, int iter, +- zeros_full_output *full_output) nogil ++ zeros_full_output *full_output) noexcept nogil + + cdef double brenth(callback_type f, double xa, double xb, void* args, + double xtol, double rtol, int iter, +- zeros_full_output *full_output) nogil ++ zeros_full_output *full_output) noexcept nogil + + cdef double brentq(callback_type f, double xa, double xb, void* args, + double xtol, double rtol, int iter, +- zeros_full_output *full_output) nogil ++ zeros_full_output *full_output) noexcept nogil +diff --git a/scipy/optimize/cython_optimize/_zeros.pyx.in b/scipy/optimize/cython_optimize/_zeros.pyx.in +index 509d9a89..454769ed 100644 +--- a/scipy/optimize/cython_optimize/_zeros.pyx.in ++++ b/scipy/optimize/cython_optimize/_zeros.pyx.in +@@ -6,7 +6,7 @@ from . cimport c_zeros + + + # callback function wrapper that extracts function, args from params struct +-cdef double scipy_zeros_functions_func(double x, void *params): ++cdef double scipy_zeros_functions_func(double x, void *params) noexcept: + cdef zeros_parameters *myparams = params + cdef void* args = myparams.args + cdef callback_type f = myparams.function +@@ -19,7 +19,7 @@ cdef double scipy_zeros_functions_func(double x, void *params): + # cythonized way to call scalar {{ROOT_FINDER}} + cdef double {{ROOT_FINDER}}( + callback_type f, double xa, double xb, void *args, double xtol, +- double rtol, int iter, zeros_full_output *full_output) nogil: ++ double rtol, int iter, zeros_full_output *full_output) noexcept nogil: + cdef c_zeros.scipy_zeros_info solver_stats + cdef zeros_parameters myparams + cdef double root +@@ -49,7 +49,7 @@ ctypedef struct extra_params: + + + # callback function +-cdef double f_example(double x, void *args): ++cdef double f_example(double x, void *args) noexcept: + cdef extra_params *myargs = args + cdef double[4] a + # unpack structure +@@ -62,7 +62,7 @@ cdef double f_example(double x, void *args): + {{for ROOT_FINDER in root_finders}} + # {{ROOT_FINDER}} example + cdef double {{ROOT_FINDER}}_example( +- tuple args, float xa, float xb, float xtol, float rtol, int mitr): ++ tuple args, float xa, float xb, float xtol, float rtol, int mitr) noexcept: + cdef extra_params myargs + myargs.a = args + return {{ROOT_FINDER}}( +@@ -119,7 +119,7 @@ def loop_example(method, a0, args, xa, xb, xtol, rtol, mitr): + + # brentq example with full ouptut + cdef zeros_full_output brentq_full_output_example( +- tuple args, float xa, float xb, float xtol, float rtol, int mitr): ++ tuple args, float xa, float xb, float xtol, float rtol, int mitr) noexcept: + cdef zeros_full_output full_output + cdef extra_params myargs + myargs.a = args +diff --git a/scipy/optimize/cython_optimize/c_zeros.pxd b/scipy/optimize/cython_optimize/c_zeros.pxd +index 723e479e..0d83c80e 100644 +--- a/scipy/optimize/cython_optimize/c_zeros.pxd ++++ b/scipy/optimize/cython_optimize/c_zeros.pxd +@@ -1,5 +1,5 @@ + cdef extern from "../Zeros/zeros.h": +- ctypedef double (*callback_type)(double, void*) ++ ctypedef double (*callback_type)(double, void*) noexcept + ctypedef struct scipy_zeros_info: + int funcalls + int iterations +diff --git a/scipy/signal/_sosfilt.pyx b/scipy/signal/_sosfilt.pyx +index 140e66cb..e3ca7fd5 100644 +--- a/scipy/signal/_sosfilt.pyx ++++ b/scipy/signal/_sosfilt.pyx +@@ -28,7 +28,7 @@ ctypedef fused DTYPE_t: + @cython.wraparound(False) + cdef void _sosfilt_float(DTYPE_floating_t [:, ::1] sos, + DTYPE_floating_t [:, ::1] x, +- DTYPE_floating_t [:, :, ::1] zi) nogil: ++ DTYPE_floating_t [:, :, ::1] zi) noexcept nogil: + # Modifies x and zi in place + cdef Py_ssize_t n_signals = x.shape[0] + cdef Py_ssize_t n_samples = x.shape[1] +diff --git a/scipy/signal/_upfirdn_apply.pyx b/scipy/signal/_upfirdn_apply.pyx +index 976611c9..4ba5e703 100644 +--- a/scipy/signal/_upfirdn_apply.pyx ++++ b/scipy/signal/_upfirdn_apply.pyx +@@ -108,7 +108,7 @@ cpdef MODE mode_enum(mode): + @cython.boundscheck(False) # designed to stay within bounds + @cython.wraparound(False) # we don't use negative indexing + cdef DTYPE_t _extend_left(DTYPE_t *x, np.intp_t idx, np.intp_t len_x, +- MODE mode, DTYPE_t cval) nogil: ++ MODE mode, DTYPE_t cval) noexcept nogil: + cdef DTYPE_t le = 0. + cdef DTYPE_t lin_slope = 0. + +@@ -174,7 +174,7 @@ cdef DTYPE_t _extend_left(DTYPE_t *x, np.intp_t idx, np.intp_t len_x, + @cython.boundscheck(False) # designed to stay within bounds + @cython.wraparound(False) # we don't use negative indexing + cdef DTYPE_t _extend_right(DTYPE_t *x, np.intp_t idx, np.intp_t len_x, +- MODE mode, DTYPE_t cval) nogil: ++ MODE mode, DTYPE_t cval) noexcept nogil: + # note: idx will be >= len_x + cdef DTYPE_t re = 0. + cdef DTYPE_t lin_slope = 0. +@@ -322,7 +322,7 @@ cdef int _apply_axis_inner(DTYPE_t* data, ArrayInfo data_info, + DTYPE_t* output, ArrayInfo output_info, + np.intp_t up, np.intp_t down, + np.intp_t axis, MODE mode, DTYPE_t cval, +- np.intp_t len_out) nogil: ++ np.intp_t len_out) noexcept nogil: + cdef np.intp_t i + cdef np.intp_t num_loops = 1 + cdef bint make_temp_data, make_temp_output +@@ -421,7 +421,7 @@ cdef int _apply_axis_inner(DTYPE_t* data, ArrayInfo data_info, + cdef void _apply_impl(DTYPE_t *x, np.intp_t len_x, DTYPE_t *h_trans_flip, + np.intp_t len_h, DTYPE_t *out, + np.intp_t up, np.intp_t down, MODE mode, +- DTYPE_t cval, np.intp_t len_out) nogil: ++ DTYPE_t cval, np.intp_t len_out) noexcept nogil: + cdef np.intp_t h_per_phase = len_h // up + cdef np.intp_t padded_len = len_x + h_per_phase - 1 + cdef np.intp_t x_idx = 0 +diff --git a/scipy/sparse/csgraph/_flow.pyx b/scipy/sparse/csgraph/_flow.pyx +index 1315e54c..a76eab37 100644 +--- a/scipy/sparse/csgraph/_flow.pyx ++++ b/scipy/sparse/csgraph/_flow.pyx +@@ -386,7 +386,7 @@ cdef ITYPE_t[:] _edmonds_karp( + ITYPE_t[:] capacities, + ITYPE_t[:] rev_edge_ptr, + ITYPE_t source, +- ITYPE_t sink): ++ ITYPE_t sink) noexcept: + """Solves the maximum flow problem using the Edmonds--Karp algorithm. + + This assumes that for every edge in the graph, the edge in the opposite +@@ -492,7 +492,7 @@ cdef bint _build_level_graph( + const ITYPE_t[:] heads, # IN + ITYPE_t[:] levels, # IN/OUT + ITYPE_t[:] q, # IN/OUT +- ) nogil: ++ ) noexcept nogil: + """Builds layered graph from input graph using breadth first search. + + Parameters +@@ -553,7 +553,7 @@ cdef bint _augment_paths( + ITYPE_t[:] progress, # IN + ITYPE_t[:] flows, # OUT + ITYPE_t[:, :] stack +- ) nogil: ++ ) noexcept nogil: + """Finds augmenting paths in layered graph using depth first search. + + Parameters +@@ -627,7 +627,7 @@ cdef ITYPE_t[:] _dinic( + ITYPE_t[:] capacities, + ITYPE_t[:] rev_edge_ptr, + ITYPE_t source, +- ITYPE_t sink): ++ ITYPE_t sink) noexcept: + """Solves the maximum flow problem using the Dinic's algorithm. + + This assumes that for every edge in the graph, the edge in the opposite +diff --git a/scipy/sparse/csgraph/_matching.pyx b/scipy/sparse/csgraph/_matching.pyx +index a92e8a91..4d5c94a0 100644 +--- a/scipy/sparse/csgraph/_matching.pyx ++++ b/scipy/sparse/csgraph/_matching.pyx +@@ -502,7 +502,7 @@ cdef ITYPE_t[:] _lapjvsp(ITYPE_t[:] first, + ITYPE_t[:] kk, + DTYPE_t[:] cc, + ITYPE_t nr, +- ITYPE_t nc): ++ ITYPE_t nc) noexcept: + """Solves the minimum weight bipartite matching problem using LAPJVsp. + + The implementation at hand is a straightforward port of the original Pascal +diff --git a/scipy/sparse/csgraph/_min_spanning_tree.pyx b/scipy/sparse/csgraph/_min_spanning_tree.pyx +index 9f6f64a3..ea93ac68 100644 +--- a/scipy/sparse/csgraph/_min_spanning_tree.pyx ++++ b/scipy/sparse/csgraph/_min_spanning_tree.pyx +@@ -118,7 +118,7 @@ cdef void _min_spanning_tree(DTYPE_t[::1] data, + ITYPE_t[::1] i_sort, + ITYPE_t[::1] row_indices, + ITYPE_t[::1] predecessors, +- ITYPE_t[::1] rank) nogil: ++ ITYPE_t[::1] rank) noexcept nogil: + # Work-horse routine for computing minimum spanning tree using + # Kruskal's algorithm. By separating this code here, we get more + # efficient indexing. +diff --git a/scipy/sparse/csgraph/_shortest_path.pyx b/scipy/sparse/csgraph/_shortest_path.pyx +index 459672ca..4e158340 100644 +--- a/scipy/sparse/csgraph/_shortest_path.pyx ++++ b/scipy/sparse/csgraph/_shortest_path.pyx +@@ -332,7 +332,7 @@ def floyd_warshall(csgraph, directed=True, + cdef void _floyd_warshall( + np.ndarray[DTYPE_t, ndim=2, mode='c'] dist_matrix, + np.ndarray[ITYPE_t, ndim=2, mode='c'] predecessor_matrix, +- int directed=0): ++ int directed=0) noexcept: + # dist_matrix : in/out + # on input, the graph + # on output, the matrix of shortest paths +@@ -1059,7 +1059,7 @@ cdef int _bellman_ford_directed( + const int[:] csr_indices, + const int[:] csr_indptr, + double[:, :] dist_matrix, +- int[:, :] pred): ++ int[:, :] pred) noexcept: + cdef: + unsigned int Nind = dist_matrix.shape[0] + unsigned int N = dist_matrix.shape[1] +@@ -1100,7 +1100,7 @@ cdef int _bellman_ford_undirected( + const int[:] csr_indices, + const int[:] csr_indptr, + double[:, :] dist_matrix, +- int[:, :] pred): ++ int[:, :] pred) noexcept: + cdef: + unsigned int Nind = dist_matrix.shape[0] + unsigned int N = dist_matrix.shape[1] +@@ -1322,7 +1322,7 @@ cdef void _johnson_add_weights( + double[:] csr_weights, + int[:] csr_indices, + int[:] csr_indptr, +- double[:] dist_array): ++ double[:] dist_array) noexcept: + # let w(u, v) = w(u, v) + h(u) - h(v) + cdef unsigned int j, k, N = dist_array.shape[0] + +@@ -1336,7 +1336,7 @@ cdef int _johnson_directed( + const double[:] csr_weights, + const int[:] csr_indices, + const int[:] csr_indptr, +- double[:] dist_array): ++ double[:] dist_array) noexcept: + # Note: The contents of dist_array must be initialized to zero on entry + cdef: + unsigned int N = dist_array.shape[0] +@@ -1369,7 +1369,7 @@ cdef int _johnson_undirected( + const double[:] csr_weights, + const int[:] csr_indices, + const int[:] csr_indptr, +- double[:] dist_array): ++ double[:] dist_array) noexcept: + # Note: The contents of dist_array must be initialized to zero on entry + cdef: + unsigned int N = dist_array.shape[0] +@@ -1426,7 +1426,7 @@ cdef struct FibonacciNode: + + cdef void initialize_node(FibonacciNode* node, + unsigned int index, +- DTYPE_t val=0): ++ DTYPE_t val=0) noexcept: + # Assumptions: - node is a valid pointer + # - node is not currently part of a heap + node.index = index +@@ -1441,7 +1441,7 @@ cdef void initialize_node(FibonacciNode* node, + node.children = NULL + + +-cdef FibonacciNode* leftmost_sibling(FibonacciNode* node): ++cdef FibonacciNode* leftmost_sibling(FibonacciNode* node) noexcept: + # Assumptions: - node is a valid pointer + cdef FibonacciNode* temp = node + while(temp.left_sibling): +@@ -1449,7 +1449,7 @@ cdef FibonacciNode* leftmost_sibling(FibonacciNode* node): + return temp + + +-cdef void add_child(FibonacciNode* node, FibonacciNode* new_child): ++cdef void add_child(FibonacciNode* node, FibonacciNode* new_child) noexcept: + # Assumptions: - node is a valid pointer + # - new_child is a valid pointer + # - new_child is not the sibling or child of another node +@@ -1465,7 +1465,7 @@ cdef void add_child(FibonacciNode* node, FibonacciNode* new_child): + node.rank = 1 + + +-cdef void add_sibling(FibonacciNode* node, FibonacciNode* new_sibling): ++cdef void add_sibling(FibonacciNode* node, FibonacciNode* new_sibling) noexcept: + # Assumptions: - node is a valid pointer + # - new_sibling is a valid pointer + # - new_sibling is not the child or sibling of another node +@@ -1482,7 +1482,7 @@ cdef void add_sibling(FibonacciNode* node, FibonacciNode* new_sibling): + new_sibling.parent.rank += 1 + + +-cdef void remove(FibonacciNode* node): ++cdef void remove(FibonacciNode* node) noexcept: + # Assumptions: - node is a valid pointer + if node.parent: + node.parent.rank -= 1 +@@ -1515,7 +1515,7 @@ cdef struct FibonacciHeap: + + + cdef void insert_node(FibonacciHeap* heap, +- FibonacciNode* node): ++ FibonacciNode* node) noexcept: + # Assumptions: - heap is a valid pointer + # - node is a valid pointer + # - node is not the child or sibling of another node +@@ -1535,7 +1535,7 @@ cdef void insert_node(FibonacciHeap* heap, + + cdef void decrease_val(FibonacciHeap* heap, + FibonacciNode* node, +- DTYPE_t newval): ++ DTYPE_t newval) noexcept: + # Assumptions: - heap is a valid pointer + # - newval <= node.val + # - node is a valid pointer +@@ -1554,7 +1554,7 @@ cdef void decrease_val(FibonacciHeap* heap, + heap.min_node = node + + +-cdef void link(FibonacciHeap* heap, FibonacciNode* node): ++cdef void link(FibonacciHeap* heap, FibonacciNode* node) noexcept: + # Assumptions: - heap is a valid pointer + # - node is a valid pointer + # - node is already within heap +@@ -1577,7 +1577,7 @@ cdef void link(FibonacciHeap* heap, FibonacciNode* node): + link(heap, linknode) + + +-cdef FibonacciNode* remove_min(FibonacciHeap* heap): ++cdef FibonacciNode* remove_min(FibonacciHeap* heap) noexcept: + # Assumptions: - heap is a valid pointer + # - heap.min_node is a valid pointer + cdef: +@@ -1630,7 +1630,7 @@ cdef FibonacciNode* remove_min(FibonacciHeap* heap): + ###################################################################### + # Debugging: Functions for printing the Fibonacci heap + # +-#cdef void print_node(FibonacciNode* node, int level=0): ++#cdef void print_node(FibonacciNode* node, int level=0) noexcept: + # print('%s(%i,%i) %i' % (level*' ', node.index, node.val, node.rank)) + # if node.children: + # print_node(node.children, level+1) +@@ -1638,7 +1638,7 @@ cdef FibonacciNode* remove_min(FibonacciHeap* heap): + # print_node(node.right_sibling, level) + # + # +-#cdef void print_heap(FibonacciHeap* heap): ++#cdef void print_heap(FibonacciHeap* heap) noexcept: + # print("---------------------------------") + # if heap.min_node: + # print("min node: (%i, %i)" % (heap.min_node.index, heap.min_node.val)) +diff --git a/scipy/sparse/csgraph/_tools.pyx b/scipy/sparse/csgraph/_tools.pyx +index b1b98d72..dde34fe7 100644 +--- a/scipy/sparse/csgraph/_tools.pyx ++++ b/scipy/sparse/csgraph/_tools.pyx +@@ -389,7 +389,7 @@ cdef void _populate_graph(np.ndarray[DTYPE_t, ndim=1, mode='c'] data, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indices, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indptr, + np.ndarray[DTYPE_t, ndim=2, mode='c'] graph, +- DTYPE_t null_value): ++ DTYPE_t null_value) noexcept: + # data, indices, indptr are the csr attributes of the sparse input. + # on input, graph should be filled with infinities, and should be + # of size [N, N], which is also the size of the sparse matrix +@@ -592,7 +592,7 @@ cdef void _construct_dist_matrix(np.ndarray[DTYPE_t, ndim=2] graph, + np.ndarray[ITYPE_t, ndim=2] pred, + np.ndarray[DTYPE_t, ndim=2] dist, + int directed, +- DTYPE_t null_value): ++ DTYPE_t null_value) noexcept: + # All matrices should be size N x N + # note that graph will be modified if directed == False + # dist should be all zero on entry +diff --git a/scipy/sparse/csgraph/_traversal.pyx b/scipy/sparse/csgraph/_traversal.pyx +index 8b25f590..ec5bd294 100644 +--- a/scipy/sparse/csgraph/_traversal.pyx ++++ b/scipy/sparse/csgraph/_traversal.pyx +@@ -357,7 +357,7 @@ cdef unsigned int _breadth_first_directed( + np.ndarray[ITYPE_t, ndim=1, mode='c'] indices, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indptr, + np.ndarray[ITYPE_t, ndim=1, mode='c'] node_list, +- np.ndarray[ITYPE_t, ndim=1, mode='c'] predecessors): ++ np.ndarray[ITYPE_t, ndim=1, mode='c'] predecessors) noexcept: + # Inputs: + # head_node: (input) index of the node from which traversal starts + # indices: (input) CSR indices of graph +@@ -398,7 +398,7 @@ cdef unsigned int _breadth_first_undirected( + np.ndarray[ITYPE_t, ndim=1, mode='c'] indices2, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indptr2, + np.ndarray[ITYPE_t, ndim=1, mode='c'] node_list, +- np.ndarray[ITYPE_t, ndim=1, mode='c'] predecessors): ++ np.ndarray[ITYPE_t, ndim=1, mode='c'] predecessors) noexcept: + # Inputs: + # head_node: (input) index of the node from which traversal starts + # indices1: (input) CSR indices of graph +@@ -545,7 +545,7 @@ cdef unsigned int _depth_first_directed( + np.ndarray[ITYPE_t, ndim=1, mode='c'] node_list, + np.ndarray[ITYPE_t, ndim=1, mode='c'] predecessors, + np.ndarray[ITYPE_t, ndim=1, mode='c'] root_list, +- np.ndarray[ITYPE_t, ndim=1, mode='c'] flag): ++ np.ndarray[ITYPE_t, ndim=1, mode='c'] flag) noexcept: + cdef unsigned int i, i_nl_end, cnode, pnode + cdef unsigned int N = node_list.shape[0] + cdef int no_children, i_root +@@ -591,7 +591,7 @@ cdef unsigned int _depth_first_undirected( + np.ndarray[ITYPE_t, ndim=1, mode='c'] node_list, + np.ndarray[ITYPE_t, ndim=1, mode='c'] predecessors, + np.ndarray[ITYPE_t, ndim=1, mode='c'] root_list, +- np.ndarray[ITYPE_t, ndim=1, mode='c'] flag): ++ np.ndarray[ITYPE_t, ndim=1, mode='c'] flag) noexcept: + cdef unsigned int i, i_nl_end, cnode, pnode + cdef unsigned int N = node_list.shape[0] + cdef int no_children, i_root +@@ -647,7 +647,7 @@ cdef unsigned int _depth_first_undirected( + cdef int _connected_components_directed( + np.ndarray[ITYPE_t, ndim=1, mode='c'] indices, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indptr, +- np.ndarray[ITYPE_t, ndim=1, mode='c'] labels): ++ np.ndarray[ITYPE_t, ndim=1, mode='c'] labels) noexcept: + """ + Uses an iterative version of Tarjan's algorithm to find the + strongly connected components of a directed graph represented as a +@@ -771,7 +771,7 @@ cdef int _connected_components_undirected( + np.ndarray[ITYPE_t, ndim=1, mode='c'] indptr1, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indices2, + np.ndarray[ITYPE_t, ndim=1, mode='c'] indptr2, +- np.ndarray[ITYPE_t, ndim=1, mode='c'] labels): ++ np.ndarray[ITYPE_t, ndim=1, mode='c'] labels) noexcept: + + cdef int v, w, j, label, SS_head + cdef int N = labels.shape[0] +diff --git a/scipy/spatial/_ckdtree.pyx b/scipy/spatial/_ckdtree.pyx +index aaa641ee..d00d5fcf 100644 +--- a/scipy/spatial/_ckdtree.pyx ++++ b/scipy/spatial/_ckdtree.pyx +@@ -343,7 +343,7 @@ cdef class cKDTreeNode: + readonly object lesser + readonly object greater + +- cdef void _setup(cKDTreeNode self, cKDTree parent, ckdtreenode *node, np.intp_t level): ++ cdef void _setup(cKDTreeNode self, cKDTree parent, ckdtreenode *node, np.intp_t level) noexcept: + cdef cKDTreeNode n1, n2 + self.level = level + self.split_dim = node.split_dim +diff --git a/scipy/spatial/_qhull.pxd b/scipy/spatial/_qhull.pxd +index a0635ac4..c397091d 100644 +--- a/scipy/spatial/_qhull.pxd ++++ b/scipy/spatial/_qhull.pxd +@@ -40,33 +40,33 @@ cdef int _get_delaunay_info(DelaunayInfo_t *, obj, + # + + cdef int _barycentric_inside(int ndim, double *transform, +- double *x, double *c, double eps) nogil ++ double *x, double *c, double eps) noexcept nogil + + cdef void _barycentric_coordinate_single(int ndim, double *transform, +- double *x, double *c, int i) nogil ++ double *x, double *c, int i) noexcept nogil + + cdef void _barycentric_coordinates(int ndim, double *transform, +- double *x, double *c) nogil ++ double *x, double *c) noexcept nogil + + # + # N+1-D geometry + # + +-cdef void _lift_point(DelaunayInfo_t *d, double *x, double *z) nogil ++cdef void _lift_point(DelaunayInfo_t *d, double *x, double *z) noexcept nogil + +-cdef double _distplane(DelaunayInfo_t *d, int isimplex, double *point) nogil ++cdef double _distplane(DelaunayInfo_t *d, int isimplex, double *point) noexcept nogil + + # + # Finding simplices + # + +-cdef int _is_point_fully_outside(DelaunayInfo_t *d, double *x, double eps) nogil ++cdef int _is_point_fully_outside(DelaunayInfo_t *d, double *x, double eps) noexcept nogil + + cdef int _find_simplex_bruteforce(DelaunayInfo_t *d, double *c, double *x, +- double eps, double eps_broad) nogil ++ double eps, double eps_broad) noexcept nogil + + cdef int _find_simplex_directed(DelaunayInfo_t *d, double *c, double *x, +- int *start, double eps, double eps_broad) nogil ++ int *start, double eps, double eps_broad) noexcept nogil + + cdef int _find_simplex(DelaunayInfo_t *d, double *c, double *x, int *start, +- double eps, double eps_broad) nogil ++ double eps, double eps_broad) noexcept nogil +diff --git a/scipy/spatial/_qhull.pyx b/scipy/spatial/_qhull.pyx +index 5b47e8b0..f15a51f9 100644 +--- a/scipy/spatial/_qhull.pyx ++++ b/scipy/spatial/_qhull.pyx +@@ -988,7 +988,7 @@ cdef class _Qhull: + + + cdef void _visit_voronoi(qhT *_qh, FILE *ptr, vertexT *vertex, vertexT *vertexA, +- setT *centers, boolT unbounded): ++ setT *centers, boolT unbounded) noexcept: + cdef _Qhull qh = <_Qhull>ptr + cdef int point_1, point_2, ix + cdef list cur_vertices +@@ -1024,7 +1024,7 @@ cdef void _visit_voronoi(qhT *_qh, FILE *ptr, vertexT *vertex, vertexT *vertexA, + return + + +-cdef void qh_order_vertexneighbors_nd(qhT *qh, int nd, vertexT *vertex): ++cdef void qh_order_vertexneighbors_nd(qhT *qh, int nd, vertexT *vertex) noexcept: + if nd == 3: + qh_order_vertexneighbors(qh, vertex) + elif nd >= 4: +@@ -1147,7 +1147,7 @@ def _get_barycentric_transforms(np.ndarray[np.double_t, ndim=2] points, + return Tinvs + + @cython.boundscheck(False) +-cdef double _matrix_norm1(int n, double *a) nogil: ++cdef double _matrix_norm1(int n, double *a) noexcept nogil: + """Compute the 1-norm of a square matrix given in in Fortran order""" + cdef double maxsum = 0, colsum + cdef int i, j +@@ -1162,7 +1162,7 @@ cdef double _matrix_norm1(int n, double *a) nogil: + return maxsum + + cdef int _barycentric_inside(int ndim, double *transform, +- double *x, double *c, double eps) nogil: ++ double *x, double *c, double eps) noexcept nogil: + """ + Check whether point is inside a simplex, using barycentric + coordinates. `c` will be filled with barycentric coordinates, if +@@ -1184,7 +1184,7 @@ cdef int _barycentric_inside(int ndim, double *transform, + return 1 + + cdef void _barycentric_coordinate_single(int ndim, double *transform, +- double *x, double *c, int i) nogil: ++ double *x, double *c, int i) noexcept nogil: + """ + Compute a single barycentric coordinate. + +@@ -1204,7 +1204,7 @@ cdef void _barycentric_coordinate_single(int ndim, double *transform, + c[i] += transform[ndim*i + j] * (x[j] - transform[ndim*ndim + j]) + + cdef void _barycentric_coordinates(int ndim, double *transform, +- double *x, double *c) nogil: ++ double *x, double *c) noexcept nogil: + """ + Compute barycentric coordinates. + +@@ -1222,7 +1222,7 @@ cdef void _barycentric_coordinates(int ndim, double *transform, + # N-D geometry + #------------------------------------------------------------------------------ + +-cdef void _lift_point(DelaunayInfo_t *d, double *x, double *z) nogil: ++cdef void _lift_point(DelaunayInfo_t *d, double *x, double *z) noexcept nogil: + cdef int i + z[d.ndim] = 0 + for i in range(d.ndim): +@@ -1231,7 +1231,7 @@ cdef void _lift_point(DelaunayInfo_t *d, double *x, double *z) nogil: + z[d.ndim] *= d.paraboloid_scale + z[d.ndim] += d.paraboloid_shift + +-cdef double _distplane(DelaunayInfo_t *d, int isimplex, double *point) nogil: ++cdef double _distplane(DelaunayInfo_t *d, int isimplex, double *point) noexcept nogil: + """ + qh_distplane + """ +@@ -1248,7 +1248,7 @@ cdef double _distplane(DelaunayInfo_t *d, int isimplex, double *point) nogil: + #------------------------------------------------------------------------------ + + cdef int _is_point_fully_outside(DelaunayInfo_t *d, double *x, +- double eps) nogil: ++ double eps) noexcept nogil: + """ + Is the point outside the bounding box of the triangulation? + +@@ -1262,7 +1262,7 @@ cdef int _is_point_fully_outside(DelaunayInfo_t *d, double *x, + + cdef int _find_simplex_bruteforce(DelaunayInfo_t *d, double *c, + double *x, double eps, +- double eps_broad) nogil: ++ double eps_broad) noexcept nogil: + """ + Find simplex containing point `x` by going through all simplices. + +@@ -1320,7 +1320,7 @@ cdef int _find_simplex_bruteforce(DelaunayInfo_t *d, double *c, + + cdef int _find_simplex_directed(DelaunayInfo_t *d, double *c, + double *x, int *start, double eps, +- double eps_broad) nogil: ++ double eps_broad) noexcept nogil: + """ + Find simplex containing point `x` via a directed walk in the tessellation. + +@@ -1421,7 +1421,7 @@ cdef int _find_simplex_directed(DelaunayInfo_t *d, double *c, + + cdef int _find_simplex(DelaunayInfo_t *d, double *c, + double *x, int *start, double eps, +- double eps_broad) nogil: ++ double eps_broad) noexcept nogil: + """ + Find simplex containing point `x` by walking the triangulation. + +diff --git a/scipy/spatial/_voronoi.pyx b/scipy/spatial/_voronoi.pyx +index f86086a4..ddfdee92 100644 +--- a/scipy/spatial/_voronoi.pyx ++++ b/scipy/spatial/_voronoi.pyx +@@ -23,7 +23,7 @@ DEF ARRAY_FILLER = -2 + + @cython.boundscheck(False) + cdef void remaining_filter(np.npy_intp[:] remaining, +- np.npy_intp current_simplex): ++ np.npy_intp current_simplex) noexcept: + cdef np.npy_intp i + for i in range(remaining.shape[0]): + if remaining[i] == current_simplex: +diff --git a/scipy/spatial/setlist.pxd b/scipy/spatial/setlist.pxd +index 646d8bc7..554710bf 100644 +--- a/scipy/spatial/setlist.pxd ++++ b/scipy/spatial/setlist.pxd +@@ -57,7 +57,7 @@ cdef inline int init(setlist_t *setlist, size_t n, size_t size_guess) except -1: + + return 0 + +-cdef inline void free(setlist_t *setlist): ++cdef inline void free(setlist_t *setlist) noexcept: + """ + Free the set list + """ +@@ -73,7 +73,7 @@ cdef inline void free(setlist_t *setlist): + setlist.alloc_sizes = NULL + setlist.n = 0 + +-cdef inline int add(setlist_t *setlist, int n, int value) nogil: ++cdef inline int add(setlist_t *setlist, int n, int value) noexcept nogil: + """ + Add a value to set `n` + """ +diff --git a/scipy/spatial/transform/_rotation.pyx b/scipy/spatial/transform/_rotation.pyx +index d97a9b0c..6e680777 100644 +--- a/scipy/spatial/transform/_rotation.pyx ++++ b/scipy/spatial/transform/_rotation.pyx +@@ -13,13 +13,13 @@ from numpy.math cimport PI as pi, NAN, isnan # avoid MSVC error + np.import_array() + + # utilities for empty array initialization +-cdef inline double[:] _empty1(int n): ++cdef inline double[:] _empty1(int n) noexcept: + return array(shape=(n,), itemsize=sizeof(double), format=b"d") +-cdef inline double[:, :] _empty2(int n1, int n2): ++cdef inline double[:, :] _empty2(int n1, int n2) noexcept : + return array(shape=(n1, n2), itemsize=sizeof(double), format=b"d") +-cdef inline double[:, :, :] _empty3(int n1, int n2, int n3): ++cdef inline double[:, :, :] _empty3(int n1, int n2, int n3) noexcept: + return array(shape=(n1, n2, n3), itemsize=sizeof(double), format=b"d") +-cdef inline double[:, :] _zeros2(int n1, int n2): ++cdef inline double[:, :] _zeros2(int n1, int n2) noexcept: + cdef double[:, :] arr = array(shape=(n1, n2), + itemsize=sizeof(double), format=b"d") + arr[:, :] = 0 +@@ -28,7 +28,7 @@ cdef inline double[:, :] _zeros2(int n1, int n2): + # flat implementations of numpy functions + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline double[:] _cross3(const double[:] a, const double[:] b): ++cdef inline double[:] _cross3(const double[:] a, const double[:] b) noexcept: + cdef double[:] result = _empty1(3) + result[0] = a[1]*b[2] - a[2]*b[1] + result[1] = a[2]*b[0] - a[0]*b[2] +@@ -37,17 +37,17 @@ cdef inline double[:] _cross3(const double[:] a, const double[:] b): + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline double _dot3(const double[:] a, const double[:] b) nogil: ++cdef inline double _dot3(const double[:] a, const double[:] b) noexcept nogil: + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline double _norm3(const double[:] elems) nogil: ++cdef inline double _norm3(const double[:] elems) noexcept nogil: + return sqrt(_dot3(elems, elems)) + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline double _normalize4(double[:] elems) nogil: ++cdef inline double _normalize4(double[:] elems) noexcept nogil: + cdef double norm = sqrt(_dot3(elems, elems) + elems[3]*elems[3]) + + if norm == 0: +@@ -62,7 +62,7 @@ cdef inline double _normalize4(double[:] elems) nogil: + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline int _argmax4(double[:] a) nogil: ++cdef inline int _argmax4(double[:] a) noexcept nogil: + cdef int imax = 0 + cdef double vmax = a[0] + +@@ -81,7 +81,7 @@ cdef double[3] _ez = [0, 0, 1] + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef inline const double[:] _elementary_basis_vector(uchar axis): ++cdef inline const double[:] _elementary_basis_vector(uchar axis) noexcept: + if axis == b'x': return _ex + elif axis == b'y': return _ey + elif axis == b'z': return _ez +@@ -90,7 +90,7 @@ cdef inline const double[:] _elementary_basis_vector(uchar axis): + @cython.wraparound(False) + cdef double[:, :] _compute_euler_from_matrix( + np.ndarray[double, ndim=3] matrix, const uchar[:] seq, bint extrinsic=False +-): ++) noexcept: + # The algorithm assumes intrinsic frame transformations. The algorithm + # in the paper is formulated for rotation matrices which are transposition + # rotation matrices used within Rotation. +@@ -227,7 +227,7 @@ cdef double[:, :] _compute_euler_from_matrix( + @cython.wraparound(False) + cdef inline void _compose_quat_single( # calculate p * q into r + const double[:] p, const double[:] q, double[:] r +-): ++) noexcept: + cdef double[:] cross = _cross3(p[:3], q[:3]) + + r[0] = p[3]*q[0] + q[3]*p[0] + cross[0] +@@ -239,7 +239,7 @@ cdef inline void _compose_quat_single( # calculate p * q into r + @cython.wraparound(False) + cdef inline double[:, :] _compose_quat( + const double[:, :] p, const double[:, :] q +-): ++) noexcept: + cdef Py_ssize_t n = max(p.shape[0], q.shape[0]) + cdef double[:, :] product = _empty2(n, 4) + +@@ -260,7 +260,7 @@ cdef inline double[:, :] _compose_quat( + @cython.wraparound(False) + cdef inline double[:, :] _make_elementary_quat( + uchar axis, const double[:] angles +-): ++) noexcept: + cdef Py_ssize_t n = angles.shape[0] + cdef double[:, :] quat = _zeros2(n, 4) + +@@ -278,7 +278,7 @@ cdef inline double[:, :] _make_elementary_quat( + @cython.wraparound(False) + cdef double[:, :] _elementary_quat_compose( + const uchar[:] seq, const double[:, :] angles, bint intrinsic=False +-): ++) noexcept: + cdef double[:, :] result = _make_elementary_quat(seq[0], angles[:, 0]) + cdef Py_ssize_t seq_len = seq.shape[0] + +diff --git a/scipy/special/_agm.pxd b/scipy/special/_agm.pxd +index 8b31ffb3..0a67888b 100644 +--- a/scipy/special/_agm.pxd ++++ b/scipy/special/_agm.pxd +@@ -5,7 +5,7 @@ from libc.math cimport log, exp, fabs, sqrt, isnan, isinf, NAN, M_PI + from ._cephes cimport ellpk + + +-cdef inline double _agm_iter(double a, double b) nogil: ++cdef inline double _agm_iter(double a, double b) noexcept nogil: + # Arithmetic-geometric mean, iterative implementation + # a and b must be positive (not zero, not nan). + +@@ -23,7 +23,7 @@ cdef inline double _agm_iter(double a, double b) nogil: + + + @cython.cdivision(True) +-cdef inline double agm(double a, double b) nogil: ++cdef inline double agm(double a, double b) noexcept nogil: + # Arithmetic-geometric mean + + # sqrthalfmax is sqrt(np.finfo(1.0).max/2) +diff --git a/scipy/special/_boxcox.pxd b/scipy/special/_boxcox.pxd +index 275e7757..440684b7 100644 +--- a/scipy/special/_boxcox.pxd ++++ b/scipy/special/_boxcox.pxd +@@ -2,7 +2,7 @@ + from libc.math cimport log, log1p, expm1, exp, fabs + + +-cdef inline double boxcox(double x, double lmbda) nogil: ++cdef inline double boxcox(double x, double lmbda) noexcept nogil: + # if lmbda << 1 and log(x) < 1.0, the lmbda*log(x) product can lose + # precision, furthermore, expm1(x) == x for x < eps. + # For doubles, the range of log is -744.44 to +709.78, with eps being +@@ -15,7 +15,7 @@ cdef inline double boxcox(double x, double lmbda) nogil: + return expm1(lmbda * log(x)) / lmbda + + +-cdef inline double boxcox1p(double x, double lmbda) nogil: ++cdef inline double boxcox1p(double x, double lmbda) noexcept nogil: + # The argument given above in boxcox applies here with the modification + # that the smallest value produced by log1p is the minimum representable + # value, rather than eps. The second condition here prevents unflow +@@ -27,14 +27,14 @@ cdef inline double boxcox1p(double x, double lmbda) nogil: + return expm1(lmbda * lgx) / lmbda + + +-cdef inline double inv_boxcox(double x, double lmbda) nogil: ++cdef inline double inv_boxcox(double x, double lmbda) noexcept nogil: + if lmbda == 0: + return exp(x) + else: + return exp(log1p(lmbda * x) / lmbda) + + +-cdef inline double inv_boxcox1p(double x, double lmbda) nogil: ++cdef inline double inv_boxcox1p(double x, double lmbda) noexcept nogil: + if lmbda == 0: + return expm1(x) + elif fabs(lmbda * x) < 1e-154: +diff --git a/scipy/special/_comb.pyx b/scipy/special/_comb.pyx +index 5f9af908..7eb79f49 100644 +--- a/scipy/special/_comb.pyx ++++ b/scipy/special/_comb.pyx +@@ -30,7 +30,7 @@ def _comb_int(N, k): + return numerator // denominator + + +-cdef unsigned long _comb_int_long(unsigned long N, unsigned long k): ++cdef unsigned long _comb_int_long(unsigned long N, unsigned long k) noexcept: + """ + Compute binom(N, k) for integers. + Returns 0 if error/overflow encountered. +diff --git a/scipy/special/_complexstuff.pxd b/scipy/special/_complexstuff.pxd +index 96e8196d..ce11be1d 100644 +--- a/scipy/special/_complexstuff.pxd ++++ b/scipy/special/_complexstuff.pxd +@@ -32,51 +32,51 @@ ctypedef union _complex_pun: + double_complex c99 + + cdef inline np.npy_cdouble npy_cdouble_from_double_complex( +- double_complex x) nogil: ++ double_complex x) noexcept nogil: + cdef _complex_pun z + z.c99 = x + return z.npy + + cdef inline double_complex double_complex_from_npy_cdouble( +- np.npy_cdouble x) nogil: ++ np.npy_cdouble x) noexcept nogil: + cdef _complex_pun z + z.npy = x + return z.c99 + +-cdef inline bint zisnan(number_t x) nogil: ++cdef inline bint zisnan(number_t x) noexcept nogil: + if number_t is double_complex: + return isnan(x.real) or isnan(x.imag) + else: + return isnan(x) + +-cdef inline bint zisfinite(number_t x) nogil: ++cdef inline bint zisfinite(number_t x) noexcept nogil: + if number_t is double_complex: + return isfinite(x.real) and isfinite(x.imag) + else: + return isfinite(x) + +-cdef inline bint zisinf(number_t x) nogil: ++cdef inline bint zisinf(number_t x) noexcept nogil: + if number_t is double_complex: + return not zisnan(x) and not zisfinite(x) + else: + return isinf(x) + +-cdef inline double zreal(number_t x) nogil: ++cdef inline double zreal(number_t x) noexcept nogil: + if number_t is double_complex: + return x.real + else: + return x + +-cdef inline double zabs(number_t x) nogil: ++cdef inline double zabs(number_t x) noexcept nogil: + if number_t is double_complex: + return npy_cabs(npy_cdouble_from_double_complex(x)) + else: + return fabs(x) + +-cdef inline double zarg(double complex x) nogil: ++cdef inline double zarg(double complex x) noexcept nogil: + return npy_carg(npy_cdouble_from_double_complex(x)) + +-cdef inline number_t zlog(number_t x) nogil: ++cdef inline number_t zlog(number_t x) noexcept nogil: + cdef np.npy_cdouble r + if number_t is double_complex: + r = npy_clog(npy_cdouble_from_double_complex(x)) +@@ -84,7 +84,7 @@ cdef inline number_t zlog(number_t x) nogil: + else: + return log(x) + +-cdef inline number_t zexp(number_t x) nogil: ++cdef inline number_t zexp(number_t x) noexcept nogil: + cdef np.npy_cdouble r + if number_t is double_complex: + r = npy_cexp(npy_cdouble_from_double_complex(x)) +@@ -92,7 +92,7 @@ cdef inline number_t zexp(number_t x) nogil: + else: + return exp(x) + +-cdef inline number_t zsin(number_t x) nogil: ++cdef inline number_t zsin(number_t x) noexcept nogil: + cdef np.npy_cdouble r + if number_t is double_complex: + r = npy_csin(npy_cdouble_from_double_complex(x)) +@@ -100,7 +100,7 @@ cdef inline number_t zsin(number_t x) nogil: + else: + return sin(x) + +-cdef inline number_t zcos(number_t x) nogil: ++cdef inline number_t zcos(number_t x) noexcept nogil: + cdef np.npy_cdouble r + if number_t is double_complex: + r = npy_ccos(npy_cdouble_from_double_complex(x)) +@@ -108,7 +108,7 @@ cdef inline number_t zcos(number_t x) nogil: + else: + return cos(x) + +-cdef inline number_t zsqrt(number_t x) nogil: ++cdef inline number_t zsqrt(number_t x) noexcept nogil: + cdef np.npy_cdouble r + if number_t is double_complex: + r = npy_csqrt(npy_cdouble_from_double_complex(x)) +@@ -116,7 +116,7 @@ cdef inline number_t zsqrt(number_t x) nogil: + else: + return sqrt(x) + +-cdef inline number_t zpow(number_t x, double y) nogil: ++cdef inline number_t zpow(number_t x, double y) noexcept nogil: + cdef np.npy_cdouble r, z + # FIXME + if number_t is double_complex: +@@ -127,14 +127,14 @@ cdef inline number_t zpow(number_t x, double y) nogil: + else: + return pow(x, y) + +-cdef inline double_complex zpack(double zr, double zi) nogil: ++cdef inline double_complex zpack(double zr, double zi) noexcept nogil: + cdef np.npy_cdouble z + z.real = zr + z.imag = zi + return double_complex_from_npy_cdouble(z) + + @cython.cdivision(True) +-cdef inline double complex zlog1(double complex z) nogil: ++cdef inline double complex zlog1(double complex z) noexcept nogil: + """ + Compute log, paying special attention to accuracy around 1. We + implement this ourselves because some systems (most notably the +diff --git a/scipy/special/_convex_analysis.pxd b/scipy/special/_convex_analysis.pxd +index 70bf0aa6..2fe95b95 100644 +--- a/scipy/special/_convex_analysis.pxd ++++ b/scipy/special/_convex_analysis.pxd +@@ -1,6 +1,6 @@ + from libc.math cimport log, fabs, expm1, log1p, isnan, NAN, INFINITY + +-cdef inline double entr(double x) nogil: ++cdef inline double entr(double x) noexcept nogil: + if isnan(x): + return x + elif x > 0: +@@ -10,7 +10,7 @@ cdef inline double entr(double x) nogil: + else: + return -INFINITY + +-cdef inline double kl_div(double x, double y) nogil: ++cdef inline double kl_div(double x, double y) noexcept nogil: + if isnan(x) or isnan(y): + return NAN + elif x > 0 and y > 0: +@@ -20,7 +20,7 @@ cdef inline double kl_div(double x, double y) nogil: + else: + return INFINITY + +-cdef inline double rel_entr(double x, double y) nogil: ++cdef inline double rel_entr(double x, double y) noexcept nogil: + if isnan(x) or isnan(y): + return NAN + elif x > 0 and y > 0: +@@ -30,7 +30,7 @@ cdef inline double rel_entr(double x, double y) nogil: + else: + return INFINITY + +-cdef inline double huber(double delta, double r) nogil: ++cdef inline double huber(double delta, double r) noexcept nogil: + if delta < 0: + return INFINITY + elif fabs(r) <= delta: +@@ -38,7 +38,7 @@ cdef inline double huber(double delta, double r) nogil: + else: + return delta * (fabs(r) - 0.5 * delta); + +-cdef inline double pseudo_huber(double delta, double r) nogil: ++cdef inline double pseudo_huber(double delta, double r) noexcept nogil: + cdef double u, v + if delta < 0: + return INFINITY +diff --git a/scipy/special/_cunity.pxd b/scipy/special/_cunity.pxd +index 06653f99..9cb010f9 100644 +--- a/scipy/special/_cunity.pxd ++++ b/scipy/special/_cunity.pxd +@@ -36,7 +36,7 @@ from ._cephes cimport log1p, expm1, cosm1 + # This expression suffers from cancellation when x < 0 and + # y = +/-sqrt(2*fabs(x)). To get around this cancellation problem, we use + # double-double precision when necessary. +-cdef inline double complex clog1p(double complex z) nogil: ++cdef inline double complex clog1p(double complex z) noexcept nogil: + cdef double zr, zi, x, y, az, azi + cdef np.npy_cdouble ret + +@@ -65,7 +65,7 @@ cdef inline double complex clog1p(double complex z) nogil: + ret = npy_clog(npy_cdouble_from_double_complex(z)) + return double_complex_from_npy_cdouble(ret) + +-cdef inline double complex clog1p_ddouble(double zr, double zi) nogil: ++cdef inline double complex clog1p_ddouble(double zr, double zi) noexcept nogil: + cdef double x, y + cdef double2 r, i, two, rsqr, isqr, rtwo, absm1 + +@@ -90,7 +90,7 @@ cdef inline double complex clog1p_ddouble(double zr, double zi) nogil: + # z.real = -log(cos(z.imag)). There isn't a way around this problem that + # doesn't involve computing exp(z.real) and/or cos(z.imag) to higher + # precision. +-cdef inline double complex cexpm1(double complex z) nogil: ++cdef inline double complex cexpm1(double complex z) noexcept nogil: + cdef double zr, zi, ezr, x, y + cdef np.npy_cdouble ret + +diff --git a/scipy/special/_cython_special.pxi b/scipy/special/_cython_special.pxi +index b5e9270b..97ef1489 100644 +--- a/scipy/special/_cython_special.pxi ++++ b/scipy/special/_cython_special.pxi +@@ -10,7 +10,7 @@ from numpy cimport ( + cdef extern from "numpy/ufuncobject.h": + int PyUFunc_getfperr() nogil + +-cdef public int wrap_PyUFunc_getfperr() nogil: ++cdef public int wrap_PyUFunc_getfperr() noexcept nogil: + """ + Call PyUFunc_getfperr in a context where PyUFunc_API array is initialized; + this avoids messing with the UNIQUE_SYMBOL #defines +diff --git a/scipy/special/_cython_special_custom.pxi b/scipy/special/_cython_special_custom.pxi +index 8769a892..7a479084 100644 +--- a/scipy/special/_cython_special_custom.pxi ++++ b/scipy/special/_cython_special_custom.pxi +@@ -1,7 +1,7 @@ + from . cimport _spherical_bessel + + +-cpdef number_t spherical_jn(long n, number_t z, bint derivative=0) nogil: ++cpdef number_t spherical_jn(long n, number_t z, bint derivative=0) noexcept nogil: + """See the documentation for scipy.special.spherical_jn""" + if derivative: + if number_t is double: +@@ -15,7 +15,7 @@ cpdef number_t spherical_jn(long n, number_t z, bint derivative=0) nogil: + return _spherical_bessel.spherical_jn_complex(n, z) + + +-cpdef number_t spherical_yn(long n, number_t z, bint derivative=0) nogil: ++cpdef number_t spherical_yn(long n, number_t z, bint derivative=0) noexcept nogil: + """See the documentation for scipy.special.spherical_yn""" + if derivative: + if number_t is double: +@@ -29,7 +29,7 @@ cpdef number_t spherical_yn(long n, number_t z, bint derivative=0) nogil: + return _spherical_bessel.spherical_yn_complex(n, z) + + +-cpdef number_t spherical_in(long n, number_t z, bint derivative=0) nogil: ++cpdef number_t spherical_in(long n, number_t z, bint derivative=0) noexcept nogil: + """See the documentation for scipy.special.spherical_in""" + if derivative: + if number_t is double: +@@ -43,7 +43,7 @@ cpdef number_t spherical_in(long n, number_t z, bint derivative=0) nogil: + return _spherical_bessel.spherical_in_complex(n, z) + + +-cpdef number_t spherical_kn(long n, number_t z, bint derivative=0) nogil: ++cpdef number_t spherical_kn(long n, number_t z, bint derivative=0) noexcept nogil: + """See the documentation for scipy.special.spherical_kn""" + if derivative: + if number_t is double: +diff --git a/scipy/special/_digamma.pxd b/scipy/special/_digamma.pxd +index fc1baffa..f3aefa29 100644 +--- a/scipy/special/_digamma.pxd ++++ b/scipy/special/_digamma.pxd +@@ -36,7 +36,7 @@ DEF negroot = -0.504083008264455409 + DEF negrootval = 7.2897639029768949e-17 + + +-cdef inline double digamma(double z) nogil: ++cdef inline double digamma(double z) noexcept nogil: + """Wrap Cephes' psi to take advantage of the series expansion around + the smallest negative zero. + +@@ -48,7 +48,7 @@ cdef inline double digamma(double z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex cdigamma(double complex z) nogil: ++cdef inline double complex cdigamma(double complex z) noexcept nogil: + """ + Compute the digamma function for complex arguments. The strategy + is: +@@ -113,7 +113,7 @@ cdef inline double complex cdigamma(double complex z) nogil: + @cython.cdivision(True) + cdef inline double complex forward_recurrence(double complex z, + double complex psiz, +- int n) nogil: ++ int n) noexcept nogil: + """ + Compute digamma(z + n) using digamma(z) using the recurrence + relation +@@ -135,7 +135,7 @@ cdef inline double complex forward_recurrence(double complex z, + @cython.cdivision(True) + cdef inline double complex backward_recurrence(double complex z, + double complex psiz, +- int n) nogil: ++ int n) noexcept nogil: + """ + Compute digamma(z - n) using digamma(z) and a recurrence + relation. +@@ -151,7 +151,7 @@ cdef inline double complex backward_recurrence(double complex z, + + + @cython.cdivision(True) +-cdef inline double complex asymptotic_series(double complex z) nogil: ++cdef inline double complex asymptotic_series(double complex z) noexcept nogil: + """ + Evaluate digamma using an asymptotic series. See + +@@ -185,7 +185,7 @@ cdef inline double complex asymptotic_series(double complex z) nogil: + return res + + +-cdef inline number_t zeta_series(number_t z, double root, double rootval) nogil: ++cdef inline number_t zeta_series(number_t z, double root, double rootval) noexcept nogil: + """ + The coefficients of the Taylor series for digamma at any point can + be expressed in terms of the Hurwitz zeta function. If we +diff --git a/scipy/special/_ellip_harm.pxd b/scipy/special/_ellip_harm.pxd +index 4f83d05c..f980efd2 100644 +--- a/scipy/special/_ellip_harm.pxd ++++ b/scipy/special/_ellip_harm.pxd +@@ -50,7 +50,7 @@ cdef extern from "lapack_defs.h": + @cython.cdivision(True) + cdef inline double* lame_coefficients(double h2, double k2, int n, int p, + void **bufferp, double signm, +- double signn) nogil: ++ double signn) noexcept nogil: + + # Ensure that the caller can safely call free(*bufferp) even if an + # invalid argument is found in the following validation code. +@@ -183,7 +183,7 @@ cdef inline double* lame_coefficients(double h2, double k2, int n, int p, + @cython.cdivision(True) + cdef inline double ellip_harm_eval(double h2, double k2, int n, int p, + double s, double *eigv, double signm, +- double signn) nogil: ++ double signn) noexcept nogil: + cdef int size, tp, r, j + cdef double s2, pp, lambda_romain, psi + s2 = s*s +@@ -210,7 +210,7 @@ cdef inline double ellip_harm_eval(double h2, double k2, int n, int p, + + + cdef inline double ellip_harmonic(double h2, double k2, int n, int p, double s, +- double signm, double signn) nogil: ++ double signm, double signn) noexcept nogil: + cdef double result + cdef double *eigv + cdef void *bufferp +diff --git a/scipy/special/_ellip_harm_2.pyx b/scipy/special/_ellip_harm_2.pyx +index 5b7010b1..38582858 100644 +--- a/scipy/special/_ellip_harm_2.pyx ++++ b/scipy/special/_ellip_harm_2.pyx +@@ -13,7 +13,7 @@ ctypedef struct _ellip_data_t: + double h2, k2 + int n, p + +-cdef double _F_integrand(double t, void *user_data) nogil: ++cdef double _F_integrand(double t, void *user_data) noexcept nogil: + cdef _ellip_data_t *data = <_ellip_data_t *>user_data + cdef double h2, k2, t2, i, result + cdef int n, p +@@ -28,7 +28,7 @@ cdef double _F_integrand(double t, void *user_data) nogil: + result = 1/(i*i*sqrt(1 - t2*k2)*sqrt(1 - t2*h2)) + return result + +-cdef double _F_integrand1(double t, void *user_data) nogil: ++cdef double _F_integrand1(double t, void *user_data) noexcept nogil: + cdef _ellip_data_t *data = <_ellip_data_t *>user_data + cdef double h2, k2, i, h, result + cdef int n, p +@@ -45,7 +45,7 @@ cdef double _F_integrand1(double t, void *user_data) nogil: + result = i*i/sqrt((t + h)*(t + k)) + return result + +-cdef double _F_integrand2(double t, void *user_data) nogil: ++cdef double _F_integrand2(double t, void *user_data) noexcept nogil: + cdef _ellip_data_t *data = <_ellip_data_t *>user_data + cdef double h2, k2, t2, i, h, result + cdef int n, p +@@ -63,7 +63,7 @@ cdef double _F_integrand2(double t, void *user_data) nogil: + result = t2*i*i/sqrt((t + h)*(t + k)) + return result + +-cdef double _F_integrand3(double t, void *user_data) nogil: ++cdef double _F_integrand3(double t, void *user_data) noexcept nogil: + cdef _ellip_data_t *data = <_ellip_data_t *>user_data + cdef double h2, k2, t2, i, h, result + cdef int n, p +@@ -80,7 +80,7 @@ cdef double _F_integrand3(double t, void *user_data) nogil: + result = i*i/sqrt((t + h)*(k2 - t2)) + return result + +-cdef double _F_integrand4(double t, void *user_data) nogil: ++cdef double _F_integrand4(double t, void *user_data) noexcept nogil: + cdef _ellip_data_t *data = <_ellip_data_t *>user_data + cdef double h2, k2, t2, i, h, result + cdef int n, p +@@ -192,7 +192,7 @@ np.import_ufunc() + cdef extern from "numpy/ufuncobject.h": + int PyUFunc_getfperr() nogil + +-cdef public int wrap_PyUFunc_getfperr() nogil: ++cdef public int wrap_PyUFunc_getfperr() noexcept nogil: + """ + Call PyUFunc_getfperr in a context where PyUFunc_API array is initialized; + this avoids messing with the UNIQUE_SYMBOL #defines +diff --git a/scipy/special/_ellipk.pxd b/scipy/special/_ellipk.pxd +index 55c2f094..fc170327 100644 +--- a/scipy/special/_ellipk.pxd ++++ b/scipy/special/_ellipk.pxd +@@ -1,5 +1,5 @@ + from ._cephes cimport ellpk + + +-cdef inline double ellipk(double m) nogil: ++cdef inline double ellipk(double m) noexcept nogil: + return ellpk(1.0 - m) +diff --git a/scipy/special/_evalpoly.pxd b/scipy/special/_evalpoly.pxd +index c1d76aaf..e6a5b552 100644 +--- a/scipy/special/_evalpoly.pxd ++++ b/scipy/special/_evalpoly.pxd +@@ -18,7 +18,7 @@ from ._complexstuff cimport zabs + + + cdef inline double complex cevalpoly(double *coeffs, int degree, +- double complex z) nogil: ++ double complex z) noexcept nogil: + """Evaluate a polynomial with real coefficients at a complex point. + + Uses equation (3) in section 4.6.4 of [1]. Note that it is more +diff --git a/scipy/special/_exprel.pxd b/scipy/special/_exprel.pxd +index c8660189..66f5acdd 100644 +--- a/scipy/special/_exprel.pxd ++++ b/scipy/special/_exprel.pxd +@@ -1,6 +1,6 @@ + from libc.math cimport expm1, fabs, log, INFINITY + +-cdef inline double exprel(double x) nogil: ++cdef inline double exprel(double x) noexcept nogil: + if fabs(x) < 1e-16: + return 1.0 + elif x > 717: # near log(DBL_MAX) +diff --git a/scipy/special/_factorial.pxd b/scipy/special/_factorial.pxd +index f28b732c..5b65cf30 100644 +--- a/scipy/special/_factorial.pxd ++++ b/scipy/special/_factorial.pxd +@@ -1,7 +1,7 @@ + from ._cephes cimport Gamma + + +-cdef inline double _factorial(double n) nogil: ++cdef inline double _factorial(double n) noexcept nogil: + if n < 0: + return 0 + else: +diff --git a/scipy/special/_generate_pyx.py b/scipy/special/_generate_pyx.py +index 8e3e49db..ad5532ff 100644 +--- a/scipy/special/_generate_pyx.py ++++ b/scipy/special/_generate_pyx.py +@@ -100,10 +100,10 @@ ctypedef fused number_t: + double complex + double + +-cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) nogil +-cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) nogil +-cpdef number_t spherical_in(long n, number_t z, bint derivative=*) nogil +-cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) nogil ++cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil ++cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil ++cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil ++cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil + """ + + CYTHON_SPECIAL_PYX = """\ +@@ -371,7 +371,7 @@ def generate_loop(func_inputs, func_outputs, func_retval, + name = "loop_%s_%s_%s_As_%s_%s" % ( + func_retval, func_inputs, func_outputs, ufunc_inputs, ufunc_outputs + ) +- body = "cdef void %s(char **args, np.npy_intp *dims, np.npy_intp *steps, void *data) nogil:\n" % name ++ body = "cdef void %s(char **args, np.npy_intp *dims, np.npy_intp *steps, void *data) noexcept nogil:\n" % name + body += " cdef np.npy_intp i, n = dims[0]\n" + body += " cdef void *func = (data)[0]\n" + body += " cdef char *func_name = (data)[1]\n" +@@ -409,7 +409,7 @@ def generate_loop(func_inputs, func_outputs, func_retval, + else: + rv = "" + +- funcall = " %s(<%s(*)(%s) nogil>func)(%s)\n" % ( ++ funcall = " %s(<%s(*)(%s) noexcept nogil>func)(%s)\n" % ( + rv, CY_TYPES[func_retval], ", ".join(ftypes), ", ".join(fvars)) + + # Cast-check inputs and call function +@@ -629,7 +629,7 @@ class Func: + if header.endswith("h") and nptypes_for_h: + cy_proto = c_proto + "nogil" + else: +- cy_proto = "%s (*)(%s) nogil" % (CY_TYPES[ret], ", ".join(cy_args)) ++ cy_proto = "%s (*)(%s) noexcept nogil" % (CY_TYPES[ret], ", ".join(cy_args)) + prototypes.append((func_name, c_proto, cy_proto, header)) + return prototypes + +@@ -1013,7 +1013,7 @@ class FusedFunc(Func): + # Functions from _ufuncs_cxx are exported as a void* + # pointers; cast them to the correct types + func_name = "scipy.special._ufuncs_cxx._export_{}".format(func_name) +- func_name = "(<{}(*)({}) nogil>{})"\ ++ func_name = "(<{}(*)({}) noexcept nogil>{})"\ + .format(rettype, ", ".join(intypes + outtypes), func_name) + else: + func_name = self.cython_func_name(func_name, specialized=True) +@@ -1126,9 +1126,9 @@ class FusedFunc(Func): + callvars.append("{} *{}".format(outtype, outvar)) + if len(self.outvars) == 1: + outtype, _ = self.outtypes[0] +- dec = "cpdef {} {}({}) nogil".format(outtype, self.name, ", ".join(callvars)) ++ dec = "cpdef {} {}({}) noexcept nogil".format(outtype, self.name, ", ".join(callvars)) + else: +- dec = "cdef void {}({}) nogil".format(self.name, ", ".join(callvars)) ++ dec = "cdef void {}({}) noexcept nogil".format(self.name, ", ".join(callvars)) + head.append(dec + ":") + head.append(tab + '"""{}"""'.format(self.doc)) + if len(self.outvars) == 1: +@@ -1174,7 +1174,7 @@ class FusedFunc(Func): + callvars.append("{} {}".format(intype, invar)) + for outvar, (outtype, _) in zip(self.outvars, self.outtypes): + callvars.append("{} *{}".format(outtype, outvar)) +- dec = "cdef void {}({}) nogil".format(self.name, ", ".join(callvars)) ++ dec = "cdef void {}({}) noexcept nogil".format(self.name, ", ".join(callvars)) + head.append(dec + ":") + head.append(tab + '"""{}"""'.format(self.doc)) + head.extend(self._get_tmp_decs(all_tmpvars)) +@@ -1259,7 +1259,7 @@ def generate_ufuncs(fn_prefix, cxx_fn_prefix, ufuncs): + cxx_defs = [] + cxx_pxd_defs = [ + "from . cimport sf_error", +- "cdef void _set_action(sf_error.sf_error_t, sf_error.sf_action_t) nogil" ++ "cdef void _set_action(sf_error.sf_error_t, sf_error.sf_action_t) noexcept nogil" + ] + cxx_defs_h = [] + +diff --git a/scipy/special/_hyp0f1.pxd b/scipy/special/_hyp0f1.pxd +index baacca8c..e12088fd 100644 +--- a/scipy/special/_hyp0f1.pxd ++++ b/scipy/special/_hyp0f1.pxd +@@ -20,7 +20,7 @@ cdef extern from "amos_wrappers.h": + # + # Real-valued kernel + # +-cdef inline double _hyp0f1_real(double v, double z) nogil: ++cdef inline double _hyp0f1_real(double v, double z) noexcept nogil: + cdef double arg, v1, arg_exp, bess_val + + # handle poles, zeros +@@ -48,7 +48,7 @@ cdef inline double _hyp0f1_real(double v, double z) nogil: + return pow(arg, 1.0 - v) * Gamma(v) * jv(v - 1, 2*arg) + + +-cdef inline double _hyp0f1_asy(double v, double z) nogil: ++cdef inline double _hyp0f1_asy(double v, double z) noexcept nogil: + r"""Asymptotic expansion for I_{v-1}(2*sqrt(z)) * Gamma(v) + for real $z > 0$ and $v\to +\infty$. + +@@ -95,7 +95,7 @@ cdef inline double _hyp0f1_asy(double v, double z) nogil: + # + # Complex valued kernel + # +-cdef inline double complex _hyp0f1_cmplx(double v, double complex z) nogil: ++cdef inline double complex _hyp0f1_cmplx(double v, double complex z) noexcept nogil: + cdef: + np.npy_cdouble zz = npy_cdouble_from_double_complex(z) + np.npy_cdouble r +diff --git a/scipy/special/_hyp2f1.pxd b/scipy/special/_hyp2f1.pxd +index 14181b80..febdb049 100644 +--- a/scipy/special/_hyp2f1.pxd ++++ b/scipy/special/_hyp2f1.pxd +@@ -81,7 +81,7 @@ DEF LOG_PI_2 = 0.5723649429247001 # log(M_PI) / 2 + @cython.cdivision(True) + cdef inline double complex hyp2f1_complex( + double a, double b, double c, double complex z +-) nogil: ++) noexcept nogil: + cdef: + double modulus_z + double max_degree +@@ -231,7 +231,7 @@ cdef inline double complex hyp2f1_series( + uint64_t max_degree, + bint early_stop, + double rtol, +-) nogil: ++) noexcept nogil: + """Return Truncated Maclaurin series for hyp2f1. + + Series is convergent for |z| < 1 but is only practical for numerical +@@ -286,7 +286,7 @@ cdef inline double complex hyp2f1_lopez_temme_series( + double complex z, + int max_degree, + double rtol, +-) nogil: ++) noexcept nogil: + """Lopez-Temme Series for Gaussian hypergeometric function [4]. + + Converges for all z with real(z) < 1, including in the regions surrounding +@@ -321,7 +321,7 @@ cdef inline double complex hyp2f1_lopez_temme_series( + + + @cython.cdivision(True) +-cdef inline double four_gammas(double u, double v, double w, double x) nogil: ++cdef inline double four_gammas(double u, double v, double w, double x) noexcept nogil: + cdef double result + # Without loss of generality, assume |u| >= |v|, |w| >= |x|. + if fabs(v) > fabs(u): +@@ -350,7 +350,7 @@ cdef inline double four_gammas(double u, double v, double w, double x) nogil: + @cython.cdivision(True) + cdef inline double four_gammas_lanczos( + double u, double v, double w, double x +-) nogil: ++) noexcept nogil: + """Compute ratio of gamma functions using lanczos approximation. + + Computes gamma(u)*gamma(v)/(gamma(w)*gamma(x)) +diff --git a/scipy/special/_hypergeometric.pxd b/scipy/special/_hypergeometric.pxd +index e2df5bef..df88d8b8 100644 +--- a/scipy/special/_hypergeometric.pxd ++++ b/scipy/special/_hypergeometric.pxd +@@ -13,7 +13,7 @@ DEF ACCEPTABLE_RTOL = 1e-7 + + + @cython.cdivision(True) +-cdef inline double hyperu(double a, double b, double x) nogil: ++cdef inline double hyperu(double a, double b, double x) noexcept nogil: + if isnan(a) or isnan(b) or isnan(x): + return NAN + +diff --git a/scipy/special/_lambertw.pxd b/scipy/special/_lambertw.pxd +index 3d601f7b..566b5e0d 100644 +--- a/scipy/special/_lambertw.pxd ++++ b/scipy/special/_lambertw.pxd +@@ -31,7 +31,7 @@ DEF OMEGA = 0.56714329040978387299997 # W(1, 0) + + + @cython.cdivision(True) +-cdef inline double complex lambertw_scalar(double complex z, long k, double tol) nogil: ++cdef inline double complex lambertw_scalar(double complex z, long k, double tol) noexcept nogil: + cdef int i + cdef double absz, p + cdef double complex w +@@ -101,7 +101,7 @@ cdef inline double complex lambertw_scalar(double complex z, long k, double tol) + + + @cython.cdivision(True) +-cdef inline double complex lambertw_branchpt(double complex z) nogil: ++cdef inline double complex lambertw_branchpt(double complex z) noexcept nogil: + """Series for W(z, 0) around the branch point; see 4.22 in [1].""" + cdef double *coeffs = [-1.0/3.0, 1.0, -1.0] + cdef double complex p = zsqrt(2*(M_E*z + 1)) +@@ -110,7 +110,7 @@ cdef inline double complex lambertw_branchpt(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex lambertw_pade0(double complex z) nogil: ++cdef inline double complex lambertw_pade0(double complex z) noexcept nogil: + """(3, 2) Pade approximation for W(z, 0) around 0.""" + cdef: + double *num = [ +@@ -131,7 +131,7 @@ cdef inline double complex lambertw_pade0(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex lambertw_asy(double complex z, long k) nogil: ++cdef inline double complex lambertw_asy(double complex z, long k) noexcept nogil: + """Compute the W function using the first two terms of the + asymptotic series. See 4.20 in [1]. + +diff --git a/scipy/special/_legacy.pxd b/scipy/special/_legacy.pxd +index a97f56dc..6992b1a1 100644 +--- a/scipy/special/_legacy.pxd ++++ b/scipy/special/_legacy.pxd +@@ -23,21 +23,21 @@ cdef extern from "Python.h": + # Purposefully ignore the raised PyError --- assume the ufunc will collect it + int PyErr_WarnEx_noerr "PyErr_WarnEx" (object, char *, int) + +-cdef inline void _legacy_cast_check(char *func_name, double x, double y) nogil: ++cdef inline void _legacy_cast_check(char *func_name, double x, double y) noexcept nogil: + if x != x or y != y: + with gil: + PyErr_WarnEx_noerr(RuntimeWarning, + "floating point number truncated to an integer", + 1) + +-cdef inline void _legacy_deprecation(char *func_name, double x, double y) nogil: ++cdef inline void _legacy_deprecation(char *func_name, double x, double y) noexcept nogil: + with gil: + PyErr_WarnEx_noerr(DeprecationWarning, + "non-integer arg n is deprecated, removed in SciPy 1.7.x", + 1) + + cdef inline double complex sph_harmonic_unsafe(double m, double n, +- double theta, double phi) nogil: ++ double theta, double phi) noexcept nogil: + if isnan(m) or isnan(n): + return NAN + _legacy_cast_check("sph_harm", m, n) +@@ -45,100 +45,100 @@ cdef inline double complex sph_harmonic_unsafe(double m, double n, + + cdef inline double ellip_harmonic_unsafe(double h2, double k2, double n, + double p, double l, double signm, +- double signn) nogil: ++ double signn) noexcept nogil: + if isnan(n) or isnan(p): + return NAN + _legacy_cast_check("_ellip_harm", n, p) + return ellip_harmonic(h2, k2, n, p, l, signm, signn) + +-cdef inline double bdtr_unsafe(double k, double n, double p) nogil: ++cdef inline double bdtr_unsafe(double k, double n, double p) noexcept nogil: + _legacy_deprecation("bdtr", k, n) + if isnan(n) or isinf(n): + return NAN + else: + return bdtr(k, n, p) + +-cdef inline double bdtrc_unsafe(double k, double n, double p) nogil: ++cdef inline double bdtrc_unsafe(double k, double n, double p) noexcept nogil: + _legacy_deprecation("bdtrc", k, n) + if isnan(n) or isinf(n): + return NAN + else: + return bdtrc(k, n, p) + +-cdef inline double bdtri_unsafe(double k, double n, double p) nogil: ++cdef inline double bdtri_unsafe(double k, double n, double p) noexcept nogil: + _legacy_deprecation("bdtri", k, n) + if isnan(n) or isinf(n): + return NAN + else: + return bdtri(k, n, p) + +-cdef inline double expn_unsafe(double n, double x) nogil: ++cdef inline double expn_unsafe(double n, double x) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("expn", n, 0) + return expn(n, x) + +-cdef inline double nbdtrc_unsafe(double k, double n, double p) nogil: ++cdef inline double nbdtrc_unsafe(double k, double n, double p) noexcept nogil: + if isnan(k) or isnan(n): + return NAN + _legacy_cast_check("nbdtrc", k, n) + return nbdtrc(k, n, p) + +-cdef inline double nbdtr_unsafe(double k, double n, double p) nogil: ++cdef inline double nbdtr_unsafe(double k, double n, double p) noexcept nogil: + if isnan(k) or isnan(n): + return NAN + _legacy_cast_check("nbdtr", k, n) + return nbdtr(k, n, p) + +-cdef inline double nbdtri_unsafe(double k, double n, double p) nogil: ++cdef inline double nbdtri_unsafe(double k, double n, double p) noexcept nogil: + if isnan(k) or isnan(n): + return NAN + _legacy_cast_check("nbdtri", k, n) + return nbdtri(k, n, p) + +-cdef inline double pdtri_unsafe(double k, double y) nogil: ++cdef inline double pdtri_unsafe(double k, double y) noexcept nogil: + if isnan(k): + return k + _legacy_cast_check("pdtri", k, 0) + return pdtri(k, y) + +-cdef inline double kn_unsafe(double n, double x) nogil: ++cdef inline double kn_unsafe(double n, double x) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("kn", n, 0) + return cbesk_wrap_real_int(n, x) + +-cdef inline double yn_unsafe(double n, double x) nogil: ++cdef inline double yn_unsafe(double n, double x) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("yn", n, 0) + return yn(n, x) + +-cdef inline double smirnov_unsafe(double n, double e) nogil: ++cdef inline double smirnov_unsafe(double n, double e) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("smirnov", n, 0) + return smirnov(n, e) + +-cdef inline double smirnovc_unsafe(double n, double e) nogil: ++cdef inline double smirnovc_unsafe(double n, double e) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("smirnovc", n, 0) + return smirnovc(n, e) + +-cdef inline double smirnovp_unsafe(double n, double e) nogil: ++cdef inline double smirnovp_unsafe(double n, double e) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("smirnovp", n, 0) + return smirnovp(n, e) + +-cdef inline double smirnovi_unsafe(double n, double p) nogil: ++cdef inline double smirnovi_unsafe(double n, double p) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("smirnovi", n, 0) + return smirnovi(n, p) + +-cdef inline double smirnovci_unsafe(double n, double p) nogil: ++cdef inline double smirnovci_unsafe(double n, double p) noexcept nogil: + if isnan(n): + return n + _legacy_cast_check("smirnovci", n, 0) +diff --git a/scipy/special/_loggamma.pxd b/scipy/special/_loggamma.pxd +index c2f91074..bd730147 100644 +--- a/scipy/special/_loggamma.pxd ++++ b/scipy/special/_loggamma.pxd +@@ -35,7 +35,7 @@ DEF SMALLY = 7 + DEF TAYLOR_RADIUS = 0.2 + + +-cdef inline double loggamma_real(double x) nogil: ++cdef inline double loggamma_real(double x) noexcept nogil: + if x < 0.0: + return NAN + +@@ -43,7 +43,7 @@ cdef inline double loggamma_real(double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex loggamma(double complex z) nogil: ++cdef inline double complex loggamma(double complex z) noexcept nogil: + """Compute the principal branch of log-Gamma.""" + cdef double tmp + +@@ -71,7 +71,7 @@ cdef inline double complex loggamma(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex loggamma_recurrence(double complex z) nogil: ++cdef inline double complex loggamma_recurrence(double complex z) noexcept nogil: + """Backward recurrence relation. + + See Proposition 2.2 in [1] and the Julia implementation [2]. +@@ -94,7 +94,7 @@ cdef inline double complex loggamma_recurrence(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex loggamma_stirling(double complex z) nogil: ++cdef inline double complex loggamma_stirling(double complex z) noexcept nogil: + """Stirling series for log-Gamma. + + The coefficients are B[2*n]/(2*n*(2*n - 1)) where B[2*n] is the +@@ -115,7 +115,7 @@ cdef inline double complex loggamma_stirling(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex loggamma_taylor(double complex z) nogil: ++cdef inline double complex loggamma_taylor(double complex z) noexcept nogil: + """Taylor series for log-Gamma around z = 1. + + It is +@@ -145,7 +145,7 @@ cdef inline double complex loggamma_taylor(double complex z) nogil: + return z*cevalpoly(coeffs, 22, z) + + +-cdef inline double complex cgamma(double complex z) nogil: ++cdef inline double complex cgamma(double complex z) noexcept nogil: + """Compute Gamma(z) using loggamma.""" + if z.real <= 0 and z == floor(z.real): + # Poles +@@ -154,7 +154,7 @@ cdef inline double complex cgamma(double complex z) nogil: + return zexp(loggamma(z)) + + +-cdef inline double complex crgamma(double complex z) nogil: ++cdef inline double complex crgamma(double complex z) noexcept nogil: + """Compute 1/Gamma(z) using loggamma.""" + if z.real <= 0 and z == floor(z.real): + # Zeros at 0, -1, -2, ... +diff --git a/scipy/special/_ndtri_exp.pxd b/scipy/special/_ndtri_exp.pxd +index 14a7a889..72c33eb2 100644 +--- a/scipy/special/_ndtri_exp.pxd ++++ b/scipy/special/_ndtri_exp.pxd +@@ -109,7 +109,7 @@ cdef extern from "cephes/polevl.h": + from ._cephes cimport ndtri + + @cython.cdivision(True) +-cdef inline double _ndtri_exp_small_y(double y) nogil: ++cdef inline double _ndtri_exp_small_y(double y) noexcept nogil: + """Return inverse of log CDF of normal distribution for very small y + + For p sufficiently small, the inverse of the CDF of the normal +@@ -160,7 +160,7 @@ cdef inline double _ndtri_exp_small_y(double y) nogil: + return x1 - x0 + + +-cdef inline double ndtri_exp(double y) nogil: ++cdef inline double ndtri_exp(double y) noexcept nogil: + """Return inverse of logarithm of Normal CDF evaluated at y.""" + if y < -DBL_MAX: + return -INFINITY +diff --git a/scipy/special/_sici.pxd b/scipy/special/_sici.pxd +index 5250283c..d1aa0478 100644 +--- a/scipy/special/_sici.pxd ++++ b/scipy/special/_sici.pxd +@@ -24,7 +24,7 @@ DEF TOL = 2.220446092504131e-16 + DEF EULER = 0.577215664901532860606512090082402431 # Euler constant + + +-cdef inline double complex zexpi(double complex z) nogil: ++cdef inline double complex zexpi(double complex z) noexcept nogil: + cdef np.npy_cdouble r + r = cexpi_wrap(npy_cdouble_from_double_complex(z)) + return double_complex_from_npy_cdouble(r) +@@ -32,7 +32,7 @@ cdef inline double complex zexpi(double complex z) nogil: + + @cython.cdivision(True) + cdef inline void power_series(int sgn, double complex z, +- double complex *s, double complex *c) nogil: ++ double complex *s, double complex *c) noexcept nogil: + """DLMF 6.6.5 and 6.6.6. If sgn = -1 computes si/ci, and if sgn = 1 + computes shi/chi. + +@@ -56,7 +56,7 @@ cdef inline void power_series(int sgn, double complex z, + + + cdef inline int csici(double complex z, +- double complex *si, double complex *ci) nogil: ++ double complex *si, double complex *ci) noexcept nogil: + """Compute sin/cos integrals at complex arguments. The algorithm + largely follows that of [1]. + +@@ -105,7 +105,7 @@ cdef inline int csici(double complex z, + + + cdef inline int cshichi(double complex z, +- double complex *shi, double complex *chi) nogil: ++ double complex *shi, double complex *chi) noexcept nogil: + """Compute sinh/cosh integrals at complex arguments. The algorithm + largely follows that of [1]. + +diff --git a/scipy/special/_spence.pxd b/scipy/special/_spence.pxd +index 73ed675e..2525629a 100644 +--- a/scipy/special/_spence.pxd ++++ b/scipy/special/_spence.pxd +@@ -20,7 +20,7 @@ DEF PISQ_6 = 1.6449340668482264365 + + + @cython.cdivision(True) +-cdef inline double complex cspence(double complex z) nogil: ++cdef inline double complex cspence(double complex z) noexcept nogil: + """ + Compute Spence's function for complex arguments. The strategy is: + - If z is close to 0, use a series centered at 0. +@@ -42,7 +42,7 @@ cdef inline double complex cspence(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex cspence_series0(double complex z) nogil: ++cdef inline double complex cspence_series0(double complex z) noexcept nogil: + """ + A series centered at z = 0; see + +@@ -71,7 +71,7 @@ cdef inline double complex cspence_series0(double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex cspence_series1(double complex z) nogil: ++cdef inline double complex cspence_series1(double complex z) noexcept nogil: + """ + A series centered at z = 1 which enjoys faster convergence than + the Taylor series. See [3]. The number of terms used comes from +diff --git a/scipy/special/_spherical_bessel.pxd b/scipy/special/_spherical_bessel.pxd +index 06e2610f..bbffbef8 100644 +--- a/scipy/special/_spherical_bessel.pxd ++++ b/scipy/special/_spherical_bessel.pxd +@@ -43,7 +43,7 @@ from ._cephes cimport iv + + # Fused type wrappers + +-cdef inline number_t cbesj(double v, number_t z) nogil: ++cdef inline number_t cbesj(double v, number_t z) noexcept nogil: + cdef npy_cdouble r + if number_t is double: + return cbesj_wrap_real(v, z) +@@ -51,7 +51,7 @@ cdef inline number_t cbesj(double v, number_t z) nogil: + r = cbesj_wrap(v, npy_cdouble_from_double_complex(z)) + return double_complex_from_npy_cdouble(r) + +-cdef inline number_t cbesy(double v, number_t z) nogil: ++cdef inline number_t cbesy(double v, number_t z) noexcept nogil: + cdef npy_cdouble r + if number_t is double: + return cbesy_wrap_real(v, z) +@@ -59,7 +59,7 @@ cdef inline number_t cbesy(double v, number_t z) nogil: + r = cbesy_wrap(v, npy_cdouble_from_double_complex(z)) + return double_complex_from_npy_cdouble(r) + +-cdef inline number_t cbesk(double v, number_t z) nogil: ++cdef inline number_t cbesk(double v, number_t z) noexcept nogil: + cdef npy_cdouble r + if number_t is double: + return cbesk_wrap_real(v, z) +@@ -71,7 +71,7 @@ cdef inline number_t cbesk(double v, number_t z) nogil: + # Spherical Bessel functions + + @cython.cdivision(True) +-cdef inline double spherical_jn_real(long n, double x) nogil: ++cdef inline double spherical_jn_real(long n, double x) noexcept nogil: + cdef double s0, s1, sn + cdef int idx + +@@ -110,7 +110,7 @@ cdef inline double spherical_jn_real(long n, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_jn_complex(long n, double complex z) nogil: ++cdef inline double complex spherical_jn_complex(long n, double complex z) noexcept nogil: + cdef double complex out + if zisnan(z): + return z +@@ -139,7 +139,7 @@ cdef inline double complex spherical_jn_complex(long n, double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double spherical_yn_real(long n, double x) nogil: ++cdef inline double spherical_yn_real(long n, double x) noexcept nogil: + cdef double s0, s1, sn + cdef int idx + +@@ -174,7 +174,7 @@ cdef inline double spherical_yn_real(long n, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_yn_complex(long n, double complex z) nogil: ++cdef inline double complex spherical_yn_complex(long n, double complex z) noexcept nogil: + + if zisnan(z): + return z +@@ -195,7 +195,7 @@ cdef inline double complex spherical_yn_complex(long n, double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double spherical_in_real(long n, double z) nogil: ++cdef inline double spherical_in_real(long n, double z) noexcept nogil: + + if isnan(z): + return z +@@ -219,7 +219,7 @@ cdef inline double spherical_in_real(long n, double z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_in_complex(long n, double complex z) nogil: ++cdef inline double complex spherical_in_complex(long n, double complex z) noexcept nogil: + cdef npy_cdouble s + + if zisnan(z): +@@ -248,7 +248,7 @@ cdef inline double complex spherical_in_complex(long n, double complex z) nogil: + + + @cython.cdivision(True) +-cdef inline double spherical_kn_real(long n, double z) nogil: ++cdef inline double spherical_kn_real(long n, double z) noexcept nogil: + + if isnan(z): + return z +@@ -268,7 +268,7 @@ cdef inline double spherical_kn_real(long n, double z) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_kn_complex(long n, double complex z) nogil: ++cdef inline double complex spherical_kn_complex(long n, double complex z) noexcept nogil: + + if zisnan(z): + return z +@@ -293,7 +293,7 @@ cdef inline double complex spherical_kn_complex(long n, double complex z) nogil: + # Derivatives + + @cython.cdivision(True) +-cdef inline double spherical_jn_d_real(long n, double x) nogil: ++cdef inline double spherical_jn_d_real(long n, double x) noexcept nogil: + if n == 0: + return -spherical_jn_real(1, x) + else: +@@ -310,7 +310,7 @@ cdef inline double spherical_jn_d_real(long n, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_jn_d_complex(long n, double complex x) nogil: ++cdef inline double complex spherical_jn_d_complex(long n, double complex x) noexcept nogil: + if n == 0: + return -spherical_jn_complex(1, x) + else: +@@ -319,7 +319,7 @@ cdef inline double complex spherical_jn_d_complex(long n, double complex x) nogi + + + @cython.cdivision(True) +-cdef inline double spherical_yn_d_real(long n, double x) nogil: ++cdef inline double spherical_yn_d_real(long n, double x) noexcept nogil: + if n == 0: + return -spherical_yn_real(1, x) + else: +@@ -328,7 +328,7 @@ cdef inline double spherical_yn_d_real(long n, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_yn_d_complex(long n, double complex x) nogil: ++cdef inline double complex spherical_yn_d_complex(long n, double complex x) noexcept nogil: + if n == 0: + return -spherical_yn_complex(1, x) + else: +@@ -337,7 +337,7 @@ cdef inline double complex spherical_yn_d_complex(long n, double complex x) nogi + + + @cython.cdivision(True) +-cdef inline double spherical_in_d_real(long n, double x) nogil: ++cdef inline double spherical_in_d_real(long n, double x) noexcept nogil: + if n == 0: + return spherical_in_real(1, x) + else: +@@ -348,7 +348,7 @@ cdef inline double spherical_in_d_real(long n, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_in_d_complex(long n, double complex x) nogil: ++cdef inline double complex spherical_in_d_complex(long n, double complex x) noexcept nogil: + if n == 0: + return spherical_in_complex(1, x) + else: +@@ -359,7 +359,7 @@ cdef inline double complex spherical_in_d_complex(long n, double complex x) nogi + + + @cython.cdivision(True) +-cdef inline double spherical_kn_d_real(long n, double x) nogil: ++cdef inline double spherical_kn_d_real(long n, double x) noexcept nogil: + if n == 0: + return -spherical_kn_real(1, x) + else: +@@ -368,7 +368,7 @@ cdef inline double spherical_kn_d_real(long n, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double complex spherical_kn_d_complex(long n, double complex x) nogil: ++cdef inline double complex spherical_kn_d_complex(long n, double complex x) noexcept nogil: + if n == 0: + return -spherical_kn_complex(1, x) + else: +diff --git a/scipy/special/_trig.pxd b/scipy/special/_trig.pxd +index f7cdc9cb..d4d031af 100644 +--- a/scipy/special/_trig.pxd ++++ b/scipy/special/_trig.pxd +@@ -11,7 +11,7 @@ from ._cephes cimport sinpi as dsinpi, cospi as dcospi + from ._complexstuff cimport number_t, double_complex, zpack + + +-cdef inline double complex csinpi(double complex z) nogil: ++cdef inline double complex csinpi(double complex z) noexcept nogil: + """Compute sin(pi*z) for complex arguments.""" + cdef: + double x = z.real +@@ -50,7 +50,7 @@ cdef inline double complex csinpi(double complex z) nogil: + return zpack(coshfac*exphpiy, sinhfac*exphpiy) + + +-cdef inline double complex ccospi(double complex z) nogil: ++cdef inline double complex ccospi(double complex z) noexcept nogil: + """Compute cos(pi*z) for complex arguments.""" + cdef: + double x = z.real +@@ -81,14 +81,14 @@ cdef inline double complex ccospi(double complex z) nogil: + return zpack(coshfac*exphpiy, sinhfac*exphpiy) + + +-cdef inline number_t sinpi(number_t z) nogil: ++cdef inline number_t sinpi(number_t z) noexcept nogil: + if number_t is double: + return dsinpi(z) + else: + return csinpi(z) + + +-cdef inline number_t cospi(number_t z) nogil: ++cdef inline number_t cospi(number_t z) noexcept nogil: + if number_t is double: + return dcospi(z) + else: +diff --git a/scipy/special/_ufuncs_extra_code_common.pxi b/scipy/special/_ufuncs_extra_code_common.pxi +index e6e9573e..95930004 100644 +--- a/scipy/special/_ufuncs_extra_code_common.pxi ++++ b/scipy/special/_ufuncs_extra_code_common.pxi +@@ -12,7 +12,7 @@ ctypedef double complex double_complex + cdef extern from "numpy/ufuncobject.h": + int PyUFunc_getfperr() nogil + +-cdef public int wrap_PyUFunc_getfperr() nogil: ++cdef public int wrap_PyUFunc_getfperr() noexcept nogil: + """ + Call PyUFunc_getfperr in a context where PyUFunc_API array is initialized; + this avoids messing with the UNIQUE_SYMBOL #defines +@@ -27,5 +27,5 @@ np.import_array() + np.import_ufunc() + + cdef void _set_action(sf_error.sf_error_t code, +- sf_error.sf_action_t action) nogil: ++ sf_error.sf_action_t action) noexcept nogil: + sf_error.set_action(code, action) +diff --git a/scipy/special/_wright_bessel.pxd b/scipy/special/_wright_bessel.pxd +index 2f986a3a..815f6f31 100644 +--- a/scipy/special/_wright_bessel.pxd ++++ b/scipy/special/_wright_bessel.pxd +@@ -39,7 +39,7 @@ DEF exp_inf = 709.78271289338403 + + + @cython.cdivision(True) +-cdef inline double _exp_rgamma(double x, double y) nogil: ++cdef inline double _exp_rgamma(double x, double y) noexcept nogil: + """Compute exp(x) / gamma(y) = exp(x) * rgamma(y). + + This helper function avoids overflow by using the lanczos approximation +@@ -53,7 +53,7 @@ cdef inline double _exp_rgamma(double x, double y) nogil: + + @cython.cdivision(True) + cdef inline double _wb_series(double a, double b, double x, +- unsigned int nstart, unsigned int nstop) nogil: ++ unsigned int nstart, unsigned int nstop) noexcept nogil: + """1. Taylor series expansion in x=0, for x <= 1 + + Phi(a, b, x) = sum_k x^k / k! / Gamma(a*k+b) +@@ -82,7 +82,7 @@ cdef inline double _wb_series(double a, double b, double x, + + @cython.cdivision(True) + cdef inline double _wb_large_a(double a, double b, double x, +- unsigned int n) nogil: ++ unsigned int n) noexcept nogil: + """2. Taylor series expansion in x=0, for large a. + + Phi(a, b, x) = sum_k x^k / k! / Gamma(a*k+b) +@@ -109,7 +109,7 @@ cdef inline double _wb_large_a(double a, double b, double x, + + + @cython.cdivision(True) +-cdef inline double _wb_small_a(double a, double b, double x, int order) nogil: ++cdef inline double _wb_small_a(double a, double b, double x, int order) noexcept nogil: + """3. Taylor series in a=0 up to order 5, for tiny a and not too large x + + Phi(a, b, x) = exp(x)/Gamma(b) +@@ -219,7 +219,7 @@ cdef inline double _wb_small_a(double a, double b, double x, int order) nogil: + + + @cython.cdivision(True) +-cdef inline double _wb_asymptotic(double a, double b, double x) nogil: ++cdef inline double _wb_asymptotic(double a, double b, double x) noexcept nogil: + """4. Asymptotic expansion for large x up to order 8 + + Phi(a, b, x) ~ Z^(1/2-b) * exp((1+a)/a * Z) * sum_k (-1)^k * C_k / Z^k +@@ -579,7 +579,7 @@ cdef inline double _wb_asymptotic(double a, double b, double x) nogil: + + @cython.cdivision(True) + cdef inline double _Kmod(double eps, double a, double b, double x, +- double r) nogil: ++ double r) noexcept nogil: + """Compute integrand Kmod(eps, a, b, x, r) for Gauss-Laguerre quadrature. + + K(a, b, x, r+eps) = exp(-r-eps) * Kmod(eps, a, b, x, r) +@@ -592,7 +592,7 @@ cdef inline double _Kmod(double eps, double a, double b, double x, + + @cython.cdivision(True) + cdef inline double _P(double eps, double a, double b, double x, +- double phi) nogil: ++ double phi) noexcept nogil: + """Compute integrand P for Gauss-Legendre quadrature. + + P(eps, a, b, x, phi) = +@@ -607,7 +607,7 @@ cdef inline double _P(double eps, double a, double b, double x, + + + @cython.cdivision(True) +-cdef inline double wright_bessel_integral(double a, double b, double x) nogil: ++cdef inline double wright_bessel_integral(double a, double b, double x) noexcept nogil: + """5. Integral representation + + K(a, b, x, r) = exp(-r + x * r^(-a) * cos(pi*a)) * r^(-b) +@@ -770,7 +770,7 @@ cdef inline double wright_bessel_integral(double a, double b, double x) nogil: + + + @cython.cdivision(True) +-cdef inline double wright_bessel_scalar(double a, double b, double x) nogil: ++cdef inline double wright_bessel_scalar(double a, double b, double x) noexcept nogil: + """Compute Wright's generalized Bessel function for scalar arguments. + + According to [1], it is an entire function defined as +diff --git a/scipy/special/_xlogy.pxd b/scipy/special/_xlogy.pxd +index a5866d3e..b9ddf300 100644 +--- a/scipy/special/_xlogy.pxd ++++ b/scipy/special/_xlogy.pxd +@@ -3,13 +3,13 @@ from libc.math cimport log1p + from ._complexstuff cimport zlog, zisnan, number_t + from ._cunity cimport clog1p + +-cdef inline number_t xlogy(number_t x, number_t y) nogil: ++cdef inline number_t xlogy(number_t x, number_t y) noexcept nogil: + if x == 0 and not zisnan(y): + return 0 + else: + return x * zlog(y) + +-cdef inline number_t xlog1py(number_t x, number_t y) nogil: ++cdef inline number_t xlog1py(number_t x, number_t y) noexcept nogil: + if x == 0 and not zisnan(y): + return 0 + else: +diff --git a/scipy/special/orthogonal_eval.pxd b/scipy/special/orthogonal_eval.pxd +index 764f1dd1..9d55bc71 100644 +--- a/scipy/special/orthogonal_eval.pxd ++++ b/scipy/special/orthogonal_eval.pxd +@@ -43,7 +43,7 @@ cdef extern from "specfun_wrappers.h": + + # Fused type wrappers + +-cdef inline number_t hyp2f1(double a, double b, double c, number_t z) nogil: ++cdef inline number_t hyp2f1(double a, double b, double c, number_t z) noexcept nogil: + cdef npy_cdouble r + if number_t is double: + return hyp2f1_wrap(a, b, c, z) +@@ -51,7 +51,7 @@ cdef inline number_t hyp2f1(double a, double b, double c, number_t z) nogil: + r = chyp2f1_wrap(a, b, c, npy_cdouble_from_double_complex(z)) + return double_complex_from_npy_cdouble(r) + +-cdef inline number_t hyp1f1(double a, double b, number_t z) nogil: ++cdef inline number_t hyp1f1(double a, double b, number_t z) noexcept nogil: + cdef npy_cdouble r + if number_t is double: + return hyp1f1_wrap(a, b, z) +@@ -65,7 +65,7 @@ cdef inline number_t hyp1f1(double a, double b, number_t z) nogil: + #----------------------------------------------------------------------------- + + @cython.cdivision(True) +-cdef inline double binom(double n, double k) nogil: ++cdef inline double binom(double n, double k) noexcept nogil: + cdef double kx, nx, num, den, dk, sgn + cdef int i + +@@ -129,7 +129,7 @@ cdef inline double binom(double n, double k) nogil: + # Jacobi + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_jacobi(double n, double alpha, double beta, number_t x) nogil: ++cdef inline number_t eval_jacobi(double n, double alpha, double beta, number_t x) noexcept nogil: + cdef double a, b, c, d + cdef number_t g + +@@ -141,7 +141,7 @@ cdef inline number_t eval_jacobi(double n, double alpha, double beta, number_t x + return d * hyp2f1(a, b, c, g) + + @cython.cdivision(True) +-cdef inline double eval_jacobi_l(long n, double alpha, double beta, double x) nogil: ++cdef inline double eval_jacobi_l(long n, double alpha, double beta, double x) noexcept nogil: + cdef long kk + cdef double p, d + cdef double k, t +@@ -167,11 +167,11 @@ cdef inline double eval_jacobi_l(long n, double alpha, double beta, double x) no + #----------------------------------------------------------------------------- + + @cython.cdivision(True) +-cdef inline number_t eval_sh_jacobi(double n, double p, double q, number_t x) nogil: ++cdef inline number_t eval_sh_jacobi(double n, double p, double q, number_t x) noexcept nogil: + return eval_jacobi(n, p-q, q-1, 2*x-1) / binom(2*n + p - 1, n) + + @cython.cdivision(True) +-cdef inline double eval_sh_jacobi_l(long n, double p, double q, double x) nogil: ++cdef inline double eval_sh_jacobi_l(long n, double p, double q, double x) noexcept nogil: + return eval_jacobi_l(n, p-q, q-1, 2*x-1) / binom(2*n + p - 1, n) + + #----------------------------------------------------------------------------- +@@ -179,7 +179,7 @@ cdef inline double eval_sh_jacobi_l(long n, double p, double q, double x) nogil: + #----------------------------------------------------------------------------- + + @cython.cdivision(True) +-cdef inline number_t eval_gegenbauer(double n, double alpha, number_t x) nogil: ++cdef inline number_t eval_gegenbauer(double n, double alpha, number_t x) noexcept nogil: + cdef double a, b, c, d + cdef number_t g + +@@ -191,7 +191,7 @@ cdef inline number_t eval_gegenbauer(double n, double alpha, number_t x) nogil: + return d * hyp2f1(a, b, c, g) + + @cython.cdivision(True) +-cdef inline double eval_gegenbauer_l(long n, double alpha, double x) nogil: ++cdef inline double eval_gegenbauer_l(long n, double alpha, double x) noexcept nogil: + cdef long kk + cdef long a, b + cdef double p, d +@@ -247,7 +247,7 @@ cdef inline double eval_gegenbauer_l(long n, double alpha, double x) nogil: + # Chebyshev 1st kind (T) + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_chebyt(double n, number_t x) nogil: ++cdef inline number_t eval_chebyt(double n, number_t x) noexcept nogil: + cdef double a, b, c, d + cdef number_t g + +@@ -258,7 +258,7 @@ cdef inline number_t eval_chebyt(double n, number_t x) nogil: + g = 0.5*(1-x) + return hyp2f1(a, b, c, g) + +-cdef inline double eval_chebyt_l(long k, double x) nogil: ++cdef inline double eval_chebyt_l(long k, double x) noexcept nogil: + # Use Chebyshev T recurrence directly, see [MH] + cdef long m + cdef double b2, b1, b0 +@@ -281,7 +281,7 @@ cdef inline double eval_chebyt_l(long k, double x) nogil: + # Chebyshev 2st kind (U) + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_chebyu(double n, number_t x) nogil: ++cdef inline number_t eval_chebyu(double n, number_t x) noexcept nogil: + cdef double a, b, c, d + cdef number_t g + +@@ -292,7 +292,7 @@ cdef inline number_t eval_chebyu(double n, number_t x) nogil: + g = 0.5*(1-x) + return d*hyp2f1(a, b, c, g) + +-cdef inline double eval_chebyu_l(long k, double x) nogil: ++cdef inline double eval_chebyu_l(long k, double x) noexcept nogil: + cdef long m + cdef int sign + cdef double b2, b1, b0 +@@ -320,47 +320,47 @@ cdef inline double eval_chebyu_l(long k, double x) nogil: + # Chebyshev S + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_chebys(double n, number_t x) nogil: ++cdef inline number_t eval_chebys(double n, number_t x) noexcept nogil: + return eval_chebyu(n, 0.5*x) + +-cdef inline double eval_chebys_l(long n, double x) nogil: ++cdef inline double eval_chebys_l(long n, double x) noexcept nogil: + return eval_chebyu_l(n, 0.5*x) + + #----------------------------------------------------------------------------- + # Chebyshev C + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_chebyc(double n, number_t x) nogil: ++cdef inline number_t eval_chebyc(double n, number_t x) noexcept nogil: + return 2*eval_chebyt(n, 0.5*x) + +-cdef inline double eval_chebyc_l(long n, double x) nogil: ++cdef inline double eval_chebyc_l(long n, double x) noexcept nogil: + return 2*eval_chebyt_l(n, 0.5*x) + + #----------------------------------------------------------------------------- + # Chebyshev 1st kind shifted + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_sh_chebyt(double n, number_t x) nogil: ++cdef inline number_t eval_sh_chebyt(double n, number_t x) noexcept nogil: + return eval_chebyt(n, 2*x-1) + +-cdef inline double eval_sh_chebyt_l(long n, double x) nogil: ++cdef inline double eval_sh_chebyt_l(long n, double x) noexcept nogil: + return eval_chebyt_l(n, 2*x-1) + + #----------------------------------------------------------------------------- + # Chebyshev 2st kind shifted + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_sh_chebyu(double n, number_t x) nogil: ++cdef inline number_t eval_sh_chebyu(double n, number_t x) noexcept nogil: + return eval_chebyu(n, 2*x-1) + +-cdef inline double eval_sh_chebyu_l(long n, double x) nogil: ++cdef inline double eval_sh_chebyu_l(long n, double x) noexcept nogil: + return eval_chebyu_l(n, 2*x-1) + + #----------------------------------------------------------------------------- + # Legendre + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_legendre(double n, number_t x) nogil: ++cdef inline number_t eval_legendre(double n, number_t x) noexcept nogil: + cdef double a, b, c, d + cdef number_t g + +@@ -372,7 +372,7 @@ cdef inline number_t eval_legendre(double n, number_t x) nogil: + return d*hyp2f1(a, b, c, g) + + @cython.cdivision(True) +-cdef inline double eval_legendre_l(long n, double x) nogil: ++cdef inline double eval_legendre_l(long n, double x) noexcept nogil: + cdef long kk, a + cdef double p, d + cdef double k +@@ -418,17 +418,17 @@ cdef inline double eval_legendre_l(long n, double x) nogil: + # Legendre Shifted + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_sh_legendre(double n, number_t x) nogil: ++cdef inline number_t eval_sh_legendre(double n, number_t x) noexcept nogil: + return eval_legendre(n, 2*x-1) + +-cdef inline double eval_sh_legendre_l(long n, double x) nogil: ++cdef inline double eval_sh_legendre_l(long n, double x) noexcept nogil: + return eval_legendre_l(n, 2*x-1) + + #----------------------------------------------------------------------------- + # Generalized Laguerre + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_genlaguerre(double n, double alpha, number_t x) nogil: ++cdef inline number_t eval_genlaguerre(double n, double alpha, number_t x) noexcept nogil: + cdef double a, b, d + cdef number_t g + +@@ -444,7 +444,7 @@ cdef inline number_t eval_genlaguerre(double n, double alpha, number_t x) nogil: + return d * hyp1f1(a, b, g) + + @cython.cdivision(True) +-cdef inline double eval_genlaguerre_l(long n, double alpha, double x) nogil: ++cdef inline double eval_genlaguerre_l(long n, double alpha, double x) noexcept nogil: + cdef long kk + cdef double p, d + cdef double k +@@ -476,17 +476,17 @@ cdef inline double eval_genlaguerre_l(long n, double alpha, double x) nogil: + # Laguerre + #----------------------------------------------------------------------------- + +-cdef inline number_t eval_laguerre(double n, number_t x) nogil: ++cdef inline number_t eval_laguerre(double n, number_t x) noexcept nogil: + return eval_genlaguerre(n, 0., x) + +-cdef inline double eval_laguerre_l(long n, double x) nogil: ++cdef inline double eval_laguerre_l(long n, double x) noexcept nogil: + return eval_genlaguerre_l(n, 0., x) + + #----------------------------------------------------------------------------- + # Hermite (statistician's) + #----------------------------------------------------------------------------- + +-cdef inline double eval_hermitenorm(long n, double x) nogil: ++cdef inline double eval_hermitenorm(long n, double x) noexcept nogil: + cdef long k + cdef double y1, y2, y3 + +@@ -518,7 +518,7 @@ cdef inline double eval_hermitenorm(long n, double x) nogil: + #----------------------------------------------------------------------------- + + @cython.cdivision(True) +-cdef inline double eval_hermite(long n, double x) nogil: ++cdef inline double eval_hermite(long n, double x) noexcept nogil: + if n < 0: + sf_error.error( + "eval_hermite", +diff --git a/scipy/special/sf_error.pxd b/scipy/special/sf_error.pxd +index 305e5b85..1885a912 100644 +--- a/scipy/special/sf_error.pxd ++++ b/scipy/special/sf_error.pxd +@@ -25,7 +25,7 @@ cdef extern from "sf_error.h": + sf_action_t get_action "sf_error_get_action" (sf_error_t code) nogil + + +-cdef inline int _sf_error_test_function(int code) nogil: ++cdef inline int _sf_error_test_function(int code) noexcept nogil: + """Function that can raise every sf_error category for testing + purposes. + +diff --git a/scipy/special/sph_harm.pxd b/scipy/special/sph_harm.pxd +index 1a9bc7aa..24ecb2c7 100644 +--- a/scipy/special/sph_harm.pxd ++++ b/scipy/special/sph_harm.pxd +@@ -8,7 +8,7 @@ from ._complexstuff cimport * + from libc.math cimport cos, sqrt, fabs, NAN, M_PI + from libc.stdlib cimport abs + +-cdef inline double complex sph_harmonic(int m, int n, double theta, double phi) nogil: ++cdef inline double complex sph_harmonic(int m, int n, double theta, double phi) noexcept nogil: + cdef double x, prefactor + cdef double complex val + cdef int mp +diff --git a/scipy/stats/_biasedurn.pyx.templ b/scipy/stats/_biasedurn.pyx.templ +index 752c3b62..01cd3978 100644 +--- a/scipy/stats/_biasedurn.pyx.templ ++++ b/scipy/stats/_biasedurn.pyx.templ +@@ -78,18 +78,18 @@ cdef class _PyWalleniusNCHypergeometric: + + IF NPY_OLD: + cdef object _glob_rng +- cdef double next_double() nogil: ++ cdef double next_double() noexcept nogil: + with gil: + return _glob_rng.uniform() +- cdef double next_normal(const double m, const double s) nogil: ++ cdef double next_normal(const double m, const double s) noexcept nogil: + with gil: + return _glob_rng.normal(m, s) + ELSE: + cdef bitgen_t* _glob_rng +- cdef double next_double() nogil: ++ cdef double next_double() noexcept nogil: + global _glob_rng + return _glob_rng.next_double(_glob_rng.state) +- cdef double next_normal(const double m, const double s) nogil: ++ cdef double next_normal(const double m, const double s) noexcept nogil: + global _glob_rng + return random_normal(_glob_rng, m, s) + +diff --git a/scipy/stats/_qmc_cy.pyx b/scipy/stats/_qmc_cy.pyx +index 6dc47e5f..f165cb0d 100644 +--- a/scipy/stats/_qmc_cy.pyx ++++ b/scipy/stats/_qmc_cy.pyx +@@ -59,7 +59,7 @@ def _cy_wrapper_l2_star_discrepancy(double[:, ::1] sample, + + + cdef double centered_discrepancy(double[:, ::1] sample_view, +- bint iterative, unsigned int workers) nogil: ++ bint iterative, unsigned int workers) noexcept nogil: + cdef: + Py_ssize_t n = sample_view.shape[0] + Py_ssize_t d = sample_view.shape[1] +@@ -86,7 +86,7 @@ cdef double centered_discrepancy(double[:, ::1] sample_view, + + + cdef double centered_discrepancy_loop(double[:, ::1] sample_view, +- Py_ssize_t istart, Py_ssize_t istop) nogil: ++ Py_ssize_t istart, Py_ssize_t istop) noexcept nogil: + + cdef: + Py_ssize_t i, j, k +@@ -107,7 +107,7 @@ cdef double centered_discrepancy_loop(double[:, ::1] sample_view, + + + cdef double wrap_around_discrepancy(double[:, ::1] sample_view, +- bint iterative, unsigned int workers) nogil: ++ bint iterative, unsigned int workers) noexcept nogil: + cdef: + Py_ssize_t n = sample_view.shape[0] + Py_ssize_t d = sample_view.shape[1] +@@ -123,7 +123,7 @@ cdef double wrap_around_discrepancy(double[:, ::1] sample_view, + + + cdef double wrap_around_loop(double[:, ::1] sample_view, +- Py_ssize_t istart, Py_ssize_t istop) nogil: ++ Py_ssize_t istart, Py_ssize_t istop) noexcept nogil: + + cdef: + Py_ssize_t i, j, k +@@ -141,7 +141,7 @@ cdef double wrap_around_loop(double[:, ::1] sample_view, + + + cdef double mixture_discrepancy(double[:, ::1] sample_view, +- bint iterative, unsigned int workers) nogil: ++ bint iterative, unsigned int workers) noexcept nogil: + cdef: + Py_ssize_t n = sample_view.shape[0] + Py_ssize_t d = sample_view.shape[1] +@@ -170,7 +170,7 @@ cdef double mixture_discrepancy(double[:, ::1] sample_view, + + + cdef double mixture_loop(double[:, ::1] sample_view, Py_ssize_t istart, +- Py_ssize_t istop) nogil: ++ Py_ssize_t istop) noexcept nogil: + + cdef: + Py_ssize_t i, j, k +@@ -193,7 +193,7 @@ cdef double mixture_loop(double[:, ::1] sample_view, Py_ssize_t istart, + + + cdef double l2_star_discrepancy(double[:, ::1] sample_view, +- bint iterative, unsigned int workers) nogil: ++ bint iterative, unsigned int workers) noexcept nogil: + cdef: + Py_ssize_t n = sample_view.shape[0] + Py_ssize_t d = sample_view.shape[1] +@@ -219,7 +219,7 @@ cdef double l2_star_discrepancy(double[:, ::1] sample_view, + + + cdef double l2_star_loop(double[:, ::1] sample_view, Py_ssize_t istart, +- Py_ssize_t istop) nogil: ++ Py_ssize_t istop) noexcept nogil: + + cdef: + Py_ssize_t i, j, k +@@ -248,7 +248,7 @@ def _cy_wrapper_update_discrepancy(double[::1] x_new_view, + + cdef double c_update_discrepancy(double[::1] x_new_view, + double[:, ::1] sample_view, +- double initial_disc): ++ double initial_disc) noexcept: + cdef: + Py_ssize_t n = sample_view.shape[0] + 1 + Py_ssize_t d = sample_view.shape[1] +@@ -295,7 +295,7 @@ ctypedef double (*func_type)(double[:, ::1], Py_ssize_t, + + cdef double threaded_loops(func_type loop_func, + double[:, ::1] sample_view, +- unsigned int workers) nogil: ++ unsigned int workers) noexcept nogil: + cdef: + Py_ssize_t n = sample_view.shape[0] + double disc2 = 0 +@@ -328,7 +328,7 @@ cdef void one_thread_loop(func_type loop_func, + double[:, ::1] sample_view, + Py_ssize_t istart, + Py_ssize_t istop, +- _) nogil: ++ _) noexcept nogil: + + cdef double tmp = loop_func(sample_view, istart, istop) + +diff --git a/scipy/stats/_sobol.pyx b/scipy/stats/_sobol.pyx +index 6e766f36..733e85b7 100644 +--- a/scipy/stats/_sobol.pyx ++++ b/scipy/stats/_sobol.pyx +@@ -150,7 +150,7 @@ def _initialize_direction_numbers(poly, vinit, dtype): + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef int bit_length(uint_32_64 n): ++cdef int bit_length(uint_32_64 n) noexcept: + cdef int bits = 0 + cdef uint_32_64 nloc = n + while nloc != 0: +@@ -161,7 +161,7 @@ cdef int bit_length(uint_32_64 n): + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef int low_0_bit(uint_32_64 x) nogil: ++cdef int low_0_bit(uint_32_64 x) noexcept nogil: + """Get the position of the right-most 0 bit for an integer. + + Examples: +@@ -195,7 +195,7 @@ cdef int low_0_bit(uint_32_64 x) nogil: + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef int ibits(uint_32_64 x, const int pos, const int length) nogil: ++cdef int ibits(uint_32_64 x, const int pos, const int length) noexcept nogil: + """Extract a sequence of bits from the bit representation of an integer. + + Extract the sequence from position `pos` (inclusive) to ``pos + length`` +@@ -236,7 +236,7 @@ cdef int ibits(uint_32_64 x, const int pos, const int length) nogil: + @cython.wraparound(False) + cpdef void _initialize_v( + uint_32_64[:, ::1] v, const int dim, const int bits +-): ++) noexcept: + """Initialize matrix of size ``dim * bits`` with direction numbers.""" + cdef int d, i, j, k, m + cdef uint_32_64 p, newv, pow2 +@@ -313,7 +313,7 @@ cdef void draw( + uint_32_64[:, ::1] sv, + uint_32_64[::1] quasi, + cnp.float64_t[:, ::1] sample +-) nogil: ++) noexcept nogil: + cdef int j, l + cdef uint_32_64 num_gen_loc = num_gen + cdef uint_32_64 i, qtmp +@@ -333,7 +333,7 @@ cpdef void _fast_forward(const uint_32_64 n, + const uint_32_64 num_gen, + const int dim, + uint_32_64[:, ::1] sv, +- uint_32_64[::1] quasi) nogil: ++ uint_32_64[::1] quasi) noexcept nogil: + cdef int j, l + cdef uint_32_64 num_gen_loc = num_gen + cdef uint_32_64 i +@@ -346,7 +346,7 @@ cpdef void _fast_forward(const uint_32_64 n, + + @cython.boundscheck(False) + @cython.wraparound(False) +-cdef uint_32_64 cdot_pow2(uint_32_64[::1] a) nogil: ++cdef uint_32_64 cdot_pow2(uint_32_64[::1] a) noexcept nogil: + cdef int i + cdef int size = a.shape[0] + cdef uint_32_64 z = 0 +@@ -362,7 +362,7 @@ cdef uint_32_64 cdot_pow2(uint_32_64[::1] a) nogil: + cpdef void _cscramble(const int dim, + const int bits, + uint_32_64[:, :, ::1] ltm, +- uint_32_64[:, ::1] sv) nogil: ++ uint_32_64[:, ::1] sv) noexcept nogil: + """Scrambling using (left) linear matrix scramble (LMS).""" + cdef int d, i, j, k, p + cdef uint_32_64 l, lsmdp, t1, t2, vdj +@@ -391,7 +391,7 @@ cpdef void _cscramble(const int dim, + @cython.boundscheck(False) + @cython.wraparound(False) + cpdef void _fill_p_cumulative(cnp.float_t[::1] p, +- cnp.float_t[::1] p_cumulative) nogil: ++ cnp.float_t[::1] p_cumulative) noexcept nogil: + cdef int i + cdef int len_p = p.shape[0] + cdef float tot = 0 +@@ -406,7 +406,7 @@ cpdef void _fill_p_cumulative(cnp.float_t[::1] p, + @cython.wraparound(False) + cpdef void _categorize(cnp.float_t[::1] draws, + cnp.float_t[::1] p_cumulative, +- cnp.int_t[::1] result) nogil: ++ cnp.int_t[::1] result) noexcept nogil: + cdef int i + cdef int n_p = p_cumulative.shape[0] + for i in range(draws.shape[0]): +@@ -418,7 +418,7 @@ cpdef void _categorize(cnp.float_t[::1] draws, + @cython.wraparound(False) + cdef int _find_index(cnp.float_t[::1] p_cumulative, + const int size, +- const float value) nogil: ++ const float value) noexcept nogil: + cdef int l = 0 + cdef int r = size - 1 + cdef int m +diff --git a/scipy/stats/_stats.pxd b/scipy/stats/_stats.pxd +index b50e16c5..d9dce901 100644 +--- a/scipy/stats/_stats.pxd ++++ b/scipy/stats/_stats.pxd +@@ -1,9 +1,9 @@ + # destined to be used in a LowLevelCallable + cdef double _geninvgauss_pdf(double x, void *user_data) nogil except * +-cdef double _studentized_range_cdf(int n, double[2] x, void *user_data) nogil +-cdef double _studentized_range_cdf_asymptotic(double z, void *user_data) nogil +-cdef double _studentized_range_pdf(int n, double[2] x, void *user_data) nogil +-cdef double _studentized_range_pdf_asymptotic(double z, void *user_data) nogil +-cdef double _studentized_range_moment(int n, double[3] x_arg, void *user_data) nogil ++cdef double _studentized_range_cdf(int n, double[2] x, void *user_data) noexcept nogil ++cdef double _studentized_range_cdf_asymptotic(double z, void *user_data) noexcept nogil ++cdef double _studentized_range_pdf(int n, double[2] x, void *user_data) noexcept nogil ++cdef double _studentized_range_pdf_asymptotic(double z, void *user_data) noexcept nogil ++cdef double _studentized_range_moment(int n, double[3] x_arg, void *user_data) noexcept nogil + cdef double _genhyperbolic_pdf(double x, void *user_data) nogil except * + cdef double _genhyperbolic_logpdf(double x, void *user_data) nogil except * +diff --git a/scipy/stats/_stats.pyx b/scipy/stats/_stats.pyx +index b8496b1f..d2a3035a 100644 +--- a/scipy/stats/_stats.pyx ++++ b/scipy/stats/_stats.pyx +@@ -14,7 +14,7 @@ cimport scipy.special.cython_special as cs + + np.import_array() + +-cdef double von_mises_cdf_series(double k, double x, unsigned int p): ++cdef double von_mises_cdf_series(double k, double x, unsigned int p) noexcept: + cdef double s, c, sn, cn, R, V + cdef unsigned int n + s = math.sin(x) +@@ -490,11 +490,11 @@ def _local_correlations(distx, disty, global_corr='mgc'): + return corr_mat + + +-cpdef double geninvgauss_logpdf(double x, double p, double b) nogil: ++cpdef double geninvgauss_logpdf(double x, double p, double b) noexcept nogil: + return _geninvgauss_logpdf_kernel(x, p, b) + + +-cdef double _geninvgauss_logpdf_kernel(double x, double p, double b) nogil: ++cdef double _geninvgauss_logpdf_kernel(double x, double p, double b) noexcept nogil: + cdef double z, c + + if x <= 0: +@@ -521,19 +521,19 @@ cdef double _geninvgauss_pdf(double x, void *user_data) nogil except *: + return math.exp(_geninvgauss_logpdf_kernel(x, p, b)) + + +-cdef double _phi(double z) nogil: ++cdef double _phi(double z) noexcept nogil: + """evaluates the normal PDF. Used in `studentized_range`""" + cdef double inv_sqrt_2pi = 0.3989422804014327 + return inv_sqrt_2pi * math.exp(-0.5 * z * z) + + +-cdef double _logphi(double z) nogil: ++cdef double _logphi(double z) noexcept nogil: + """evaluates the log of the normal PDF. Used in `studentized_range`""" + cdef double log_inv_sqrt_2pi = -0.9189385332046727 + return log_inv_sqrt_2pi - 0.5 * z * z + + +-cdef double _Phi(double z) nogil: ++cdef double _Phi(double z) noexcept nogil: + """evaluates the normal CDF. Used in `studentized_range`""" + # use a custom function because using cs.ndtr results in incorrect PDF at + # q=0 on 32bit systems. Use a hardcoded 1/sqrt(2) constant rather than +@@ -542,14 +542,14 @@ cdef double _Phi(double z) nogil: + return 0.5 * math.erfc(-z * inv_sqrt_2) + + +-cpdef double _studentized_range_cdf_logconst(double k, double df): ++cpdef double _studentized_range_cdf_logconst(double k, double df) noexcept: + """Evaluates log of constant terms in the cdf integrand""" + cdef double log_2 = 0.6931471805599453 + return (math.log(k) + (df / 2) * math.log(df) + - (math.lgamma(df / 2) + (df / 2 - 1) * log_2)) + + +-cpdef double _studentized_range_pdf_logconst(double k, double df): ++cpdef double _studentized_range_pdf_logconst(double k, double df) noexcept: + """Evaluates log of constant terms in the pdf integrand""" + cdef double log_2 = 0.6931471805599453 + return (math.log(k) + math.log(k - 1) + (df / 2) * math.log(df) +@@ -557,7 +557,7 @@ cpdef double _studentized_range_pdf_logconst(double k, double df): + + + cdef double _studentized_range_cdf(int n, double[2] integration_var, +- void *user_data) nogil: ++ void *user_data) noexcept nogil: + # evaluates the integrand of Equation (3) by Batista, et al [2] + # destined to be used in a LowLevelCallable + q = ( user_data)[0] +@@ -578,7 +578,7 @@ cdef double _studentized_range_cdf(int n, double[2] integration_var, + return math.exp(log_terms) * math.pow(_Phi(z + q * s) - _Phi(z), k - 1) + + +-cdef double _studentized_range_cdf_asymptotic(double z, void *user_data) nogil: ++cdef double _studentized_range_cdf_asymptotic(double z, void *user_data) noexcept nogil: + # evaluates the integrand of equation (2) by Lund, Lund, page 205. [4] + # destined to be used in a LowLevelCallable + q = ( user_data)[0] +@@ -588,7 +588,7 @@ cdef double _studentized_range_cdf_asymptotic(double z, void *user_data) nogil: + + + cdef double _studentized_range_pdf(int n, double[2] integration_var, +- void *user_data) nogil: ++ void *user_data) noexcept nogil: + # evaluates the integrand of equation (4) by Batista, et al [2] + # destined to be used in a LowLevelCallable + q = ( user_data)[0] +@@ -610,7 +610,7 @@ cdef double _studentized_range_pdf(int n, double[2] integration_var, + return math.exp(log_terms) * math.pow(_Phi(s * q + z) - _Phi(z), k - 2) + + +-cdef double _studentized_range_pdf_asymptotic(double z, void *user_data) nogil: ++cdef double _studentized_range_pdf_asymptotic(double z, void *user_data) noexcept nogil: + # evaluates the integrand of equation (2) by Lund, Lund, page 205. [4] + # destined to be used in a LowLevelCallable + q = ( user_data)[0] +@@ -620,7 +620,7 @@ cdef double _studentized_range_pdf_asymptotic(double z, void *user_data) nogil: + + + cdef double _studentized_range_moment(int n, double[3] integration_var, +- void *user_data) nogil: ++ void *user_data) noexcept nogil: + # destined to be used in a LowLevelCallable + K = ( user_data)[0] # the Kth moment to calc. + k = ( user_data)[1] +@@ -640,7 +640,7 @@ cdef double _studentized_range_moment(int n, double[3] integration_var, + _studentized_range_pdf(4, integration_var, pdf_data)) + + +-cpdef double genhyperbolic_pdf(double x, double p, double a, double b) nogil: ++cpdef double genhyperbolic_pdf(double x, double p, double a, double b) noexcept nogil: + return math.exp(_genhyperbolic_logpdf_kernel(x, p, a, b)) + + +@@ -657,7 +657,7 @@ cdef double _genhyperbolic_pdf(double x, void *user_data) nogil except *: + + cpdef double genhyperbolic_logpdf( + double x, double p, double a, double b +- ) nogil: ++ ) noexcept nogil: + return _genhyperbolic_logpdf_kernel(x, p, a, b) + + cdef double _genhyperbolic_logpdf(double x, void *user_data) nogil except *: +@@ -673,7 +673,7 @@ cdef double _genhyperbolic_logpdf(double x, void *user_data) nogil except *: + + cdef double _genhyperbolic_logpdf_kernel( + double x, double p, double a, double b +- ) nogil: ++ ) noexcept nogil: + cdef double t1, t2, t3, t4, t5 + + t1 = _log_norming_constant(p, a, b) +@@ -686,7 +686,7 @@ cdef double _genhyperbolic_logpdf_kernel( + + return t1 + t3 + t4 + t5 + +-cdef double _log_norming_constant(double p, double a, double b) nogil: ++cdef double _log_norming_constant(double p, double a, double b) noexcept nogil: + cdef double t1, t2, t3, t4, t5, t6 + + t1 = math.pow(a, 2) - math.pow(b, 2) +@@ -713,7 +713,7 @@ cdef inline int gaussian_kernel_estimate_inner( + real[:, :] points_, real[:, :] values_, real[:, :] xi_, + real[:, :] estimate, real[:, :] cho_cov, + int n, int m, int d, int p, +-) nogil: ++) noexcept nogil: + cdef: + int i, j, k + real residual, arg, norm +-- +2.23.0 + diff --git a/0001-Mark-function-pointer-ctypedefs-as-noexcept.patch b/0001-Mark-function-pointer-ctypedefs-as-noexcept.patch new file mode 100644 index 0000000..2bc004f --- /dev/null +++ b/0001-Mark-function-pointer-ctypedefs-as-noexcept.patch @@ -0,0 +1,67 @@ +From 50d0825256ddb76c5567e6cc8eb50e7d36908e21 Mon Sep 17 00:00:00 2001 +From: Matus Valo +Date: Mon, 17 Apr 2023 23:00:04 +0200 +Subject: [PATCH] Mark function pointer ctypedefs as noexcept + +--- + scipy/cluster/_hierarchy_distance_update.pxi | 2 +- + scipy/optimize/cython_optimize/_zeros.pxd | 2 +- + scipy/stats/_qmc_cy.pyx | 2 +- + scipy/stats/_unuran/unuran_wrapper.pyx.templ | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/scipy/cluster/_hierarchy_distance_update.pxi b/scipy/cluster/_hierarchy_distance_update.pxi +index 17dedb305..bc57a3fa1 100644 +--- a/scipy/cluster/_hierarchy_distance_update.pxi ++++ b/scipy/cluster/_hierarchy_distance_update.pxi +@@ -24,7 +24,7 @@ d_xyi : double + """ + ctypedef double (*linkage_distance_update)(double d_xi, double d_yi, + double d_xy, int size_x, +- int size_y, int size_i) ++ int size_y, int size_i) noexcept + + + cdef double _single(double d_xi, double d_yi, double d_xy, +diff --git a/scipy/optimize/cython_optimize/_zeros.pxd b/scipy/optimize/cython_optimize/_zeros.pxd +index c6241d022..d3c9e98f0 100644 +--- a/scipy/optimize/cython_optimize/_zeros.pxd ++++ b/scipy/optimize/cython_optimize/_zeros.pxd +@@ -4,7 +4,7 @@ + # should be made to this file** --- any API additions/changes should be + # done in `cython_optimize.pxd` (see gh-11793). + +-ctypedef double (*callback_type)(double, void*) ++ctypedef double (*callback_type)(double, void*) noexcept + + ctypedef struct zeros_parameters: + callback_type function +diff --git a/scipy/stats/_qmc_cy.pyx b/scipy/stats/_qmc_cy.pyx +index f165cb0d1..a9e94354f 100644 +--- a/scipy/stats/_qmc_cy.pyx ++++ b/scipy/stats/_qmc_cy.pyx +@@ -290,7 +290,7 @@ cdef double c_update_discrepancy(double[::1] x_new_view, + + + ctypedef double (*func_type)(double[:, ::1], Py_ssize_t, +- Py_ssize_t) nogil ++ Py_ssize_t) noexcept nogil + + + cdef double threaded_loops(func_type loop_func, +diff --git a/scipy/stats/_unuran/unuran_wrapper.pyx.templ b/scipy/stats/_unuran/unuran_wrapper.pyx.templ +index 2279dfc34..9eb63fb1c 100644 +--- a/scipy/stats/_unuran/unuran_wrapper.pyx.templ ++++ b/scipy/stats/_unuran/unuran_wrapper.pyx.templ +@@ -58,7 +58,7 @@ class UNURANError(RuntimeError): + pass + + +-ctypedef double (*URNG_FUNCT)(void *) nogil ++ctypedef double (*URNG_FUNCT)(void *) noexcept nogil + + IF not NPY_OLD: + cdef object get_numpy_rng(object seed = None): +-- +2.23.0 + diff --git a/scipy.spec b/scipy.spec index 94c0990..532037d 100644 --- a/scipy.spec +++ b/scipy.spec @@ -2,12 +2,17 @@ %global debug_package %{nil} Name: scipy Version: 1.10.1 -Release: 2 +Release: 3 Summary: A Python-based ecosystem of open-source software for mathematics, science, and engineering License: Qhull and Apache-2.0 URL: https://www.scipy.org Source0: https://github.com/scipy/scipy/releases/download/v%{version}/scipy-%{version}.tar.gz +Patch6001: 0001-MAINT-Explicitly-mark-cdef-functions-not-raising-exc.patch +Patch6002: 0001-Mark-function-pointer-ctypedefs-as-noexcept.patch +Patch6003: 0001-MAINT-Allow-scipy-to-be-compiled-in-cython3-18242.patch +Patch6004: 0001-BLD-copy-cython_optimize.pxd-to-build-dir-18810.patch + BuildRequires: python3-devel python3-numpy >= 1.8.2 python3-numpy-f2py BuildRequires: gcc-c++ openblas-devel gcc-gfortran chrpath BuildRequires: pybind11-devel python3-pybind11 python3-Cython @@ -101,6 +106,9 @@ echo "%{_libdir}/%{name}" >> $RPM_BUILD_ROOT/etc/ld.so.conf.d/%{name}-%{_arch}.c %config(noreplace) /etc/ld.so.conf.d/* %changelog +* Thu Feb 1 2024 Liu Chao - 1.10.1-3 +- Fix scipy compile error in cython3 + * Mon Sep 11 2023 liyunfei - 1.10.1-2 - add clang compile support -- Gitee