scipy 1.15.3__cp312-cp312-musllinux_1_2_aarch64.whl → 1.16.0rc2__cp312-cp312-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (641) hide show
  1. scipy/__config__.py +10 -10
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-aarch64-linux-musl.so +0 -0
  4. scipy/_lib/_array_api.py +486 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-312-aarch64-linux-musl.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_fpumode.cpython-312-aarch64-linux-musl.so +0 -0
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_ccallback.cpython-312-aarch64-linux-musl.so +0 -0
  13. scipy/_lib/_test_deprecation_call.cpython-312-aarch64-linux-musl.so +0 -0
  14. scipy/_lib/_test_deprecation_def.cpython-312-aarch64-linux-musl.so +0 -0
  15. scipy/_lib/_testutils.py +6 -2
  16. scipy/_lib/_uarray/_uarray.cpython-312-aarch64-linux-musl.so +0 -0
  17. scipy/_lib/_util.py +222 -125
  18. scipy/_lib/array_api_compat/__init__.py +4 -4
  19. scipy/_lib/array_api_compat/_internal.py +19 -6
  20. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  21. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  22. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  23. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  24. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  25. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  26. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  27. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  28. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  29. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  30. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  31. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  32. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  33. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  34. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  35. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  36. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  37. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  38. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  39. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  40. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  41. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  42. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  43. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  44. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  45. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  46. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  47. scipy/_lib/array_api_extra/__init__.py +26 -3
  48. scipy/_lib/array_api_extra/_delegation.py +171 -0
  49. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  50. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  51. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  52. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  53. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  54. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  61. scipy/_lib/array_api_extra/testing.py +359 -0
  62. scipy/_lib/decorator.py +2 -2
  63. scipy/_lib/doccer.py +1 -7
  64. scipy/_lib/messagestream.cpython-312-aarch64-linux-musl.so +0 -0
  65. scipy/_lib/pyprima/__init__.py +212 -0
  66. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  67. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  68. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  69. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  70. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  71. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  72. scipy/_lib/pyprima/cobyla/update.py +289 -0
  73. scipy/_lib/pyprima/common/__init__.py +0 -0
  74. scipy/_lib/pyprima/common/_bounds.py +34 -0
  75. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  76. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  77. scipy/_lib/pyprima/common/_project.py +173 -0
  78. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  79. scipy/_lib/pyprima/common/consts.py +47 -0
  80. scipy/_lib/pyprima/common/evaluate.py +99 -0
  81. scipy/_lib/pyprima/common/history.py +38 -0
  82. scipy/_lib/pyprima/common/infos.py +30 -0
  83. scipy/_lib/pyprima/common/linalg.py +435 -0
  84. scipy/_lib/pyprima/common/message.py +290 -0
  85. scipy/_lib/pyprima/common/powalg.py +131 -0
  86. scipy/_lib/pyprima/common/preproc.py +277 -0
  87. scipy/_lib/pyprima/common/present.py +5 -0
  88. scipy/_lib/pyprima/common/ratio.py +54 -0
  89. scipy/_lib/pyprima/common/redrho.py +47 -0
  90. scipy/_lib/pyprima/common/selectx.py +296 -0
  91. scipy/_lib/tests/test__util.py +105 -121
  92. scipy/_lib/tests/test_array_api.py +166 -35
  93. scipy/_lib/tests/test_bunch.py +7 -0
  94. scipy/_lib/tests/test_ccallback.py +2 -10
  95. scipy/_lib/tests/test_public_api.py +13 -0
  96. scipy/cluster/_hierarchy.cpython-312-aarch64-linux-musl.so +0 -0
  97. scipy/cluster/_optimal_leaf_ordering.cpython-312-aarch64-linux-musl.so +0 -0
  98. scipy/cluster/_vq.cpython-312-aarch64-linux-musl.so +0 -0
  99. scipy/cluster/hierarchy.py +393 -223
  100. scipy/cluster/tests/test_hierarchy.py +273 -335
  101. scipy/cluster/tests/test_vq.py +45 -61
  102. scipy/cluster/vq.py +39 -35
  103. scipy/conftest.py +263 -157
  104. scipy/constants/_constants.py +4 -1
  105. scipy/constants/tests/test_codata.py +2 -2
  106. scipy/constants/tests/test_constants.py +11 -18
  107. scipy/datasets/_download_all.py +15 -1
  108. scipy/datasets/_fetchers.py +7 -1
  109. scipy/datasets/_utils.py +1 -1
  110. scipy/differentiate/_differentiate.py +25 -25
  111. scipy/differentiate/tests/test_differentiate.py +24 -25
  112. scipy/fft/_basic.py +20 -0
  113. scipy/fft/_helper.py +3 -34
  114. scipy/fft/_pocketfft/helper.py +29 -1
  115. scipy/fft/_pocketfft/pypocketfft.cpython-312-aarch64-linux-musl.so +0 -0
  116. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  117. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  118. scipy/fft/_realtransforms.py +13 -0
  119. scipy/fft/tests/test_basic.py +27 -25
  120. scipy/fft/tests/test_fftlog.py +16 -7
  121. scipy/fft/tests/test_helper.py +18 -34
  122. scipy/fft/tests/test_real_transforms.py +8 -10
  123. scipy/fftpack/convolve.cpython-312-aarch64-linux-musl.so +0 -0
  124. scipy/fftpack/tests/test_basic.py +2 -4
  125. scipy/fftpack/tests/test_real_transforms.py +8 -9
  126. scipy/integrate/_bvp.py +9 -3
  127. scipy/integrate/_cubature.py +3 -2
  128. scipy/integrate/_dop.cpython-312-aarch64-linux-musl.so +0 -0
  129. scipy/integrate/_lsoda.cpython-312-aarch64-linux-musl.so +0 -0
  130. scipy/integrate/_ode.py +9 -2
  131. scipy/integrate/_odepack.cpython-312-aarch64-linux-musl.so +0 -0
  132. scipy/integrate/_quad_vec.py +21 -29
  133. scipy/integrate/_quadpack.cpython-312-aarch64-linux-musl.so +0 -0
  134. scipy/integrate/_quadpack_py.py +11 -7
  135. scipy/integrate/_quadrature.py +3 -3
  136. scipy/integrate/_rules/_base.py +2 -2
  137. scipy/integrate/_tanhsinh.py +48 -47
  138. scipy/integrate/_test_multivariate.cpython-312-aarch64-linux-musl.so +0 -0
  139. scipy/integrate/_test_odeint_banded.cpython-312-aarch64-linux-musl.so +0 -0
  140. scipy/integrate/_vode.cpython-312-aarch64-linux-musl.so +0 -0
  141. scipy/integrate/tests/test__quad_vec.py +0 -6
  142. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  143. scipy/integrate/tests/test_cubature.py +21 -35
  144. scipy/integrate/tests/test_quadrature.py +6 -8
  145. scipy/integrate/tests/test_tanhsinh.py +56 -48
  146. scipy/interpolate/__init__.py +70 -58
  147. scipy/interpolate/_bary_rational.py +22 -22
  148. scipy/interpolate/_bsplines.py +119 -66
  149. scipy/interpolate/_cubic.py +65 -50
  150. scipy/interpolate/_dfitpack.cpython-312-aarch64-linux-musl.so +0 -0
  151. scipy/interpolate/_dierckx.cpython-312-aarch64-linux-musl.so +0 -0
  152. scipy/interpolate/_fitpack.cpython-312-aarch64-linux-musl.so +0 -0
  153. scipy/interpolate/_fitpack2.py +9 -6
  154. scipy/interpolate/_fitpack_impl.py +32 -26
  155. scipy/interpolate/_fitpack_repro.py +23 -19
  156. scipy/interpolate/_interpnd.cpython-312-aarch64-linux-musl.so +0 -0
  157. scipy/interpolate/_interpolate.py +30 -12
  158. scipy/interpolate/_ndbspline.py +13 -18
  159. scipy/interpolate/_ndgriddata.py +5 -8
  160. scipy/interpolate/_polyint.py +95 -31
  161. scipy/interpolate/_ppoly.cpython-312-aarch64-linux-musl.so +0 -0
  162. scipy/interpolate/_rbf.py +2 -2
  163. scipy/interpolate/_rbfinterp.py +1 -1
  164. scipy/interpolate/_rbfinterp_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  165. scipy/interpolate/_rgi.py +31 -26
  166. scipy/interpolate/_rgi_cython.cpython-312-aarch64-linux-musl.so +0 -0
  167. scipy/interpolate/dfitpack.py +0 -20
  168. scipy/interpolate/interpnd.py +1 -2
  169. scipy/interpolate/tests/test_bary_rational.py +2 -2
  170. scipy/interpolate/tests/test_bsplines.py +97 -1
  171. scipy/interpolate/tests/test_fitpack2.py +39 -1
  172. scipy/interpolate/tests/test_interpnd.py +32 -20
  173. scipy/interpolate/tests/test_interpolate.py +48 -4
  174. scipy/interpolate/tests/test_rgi.py +2 -1
  175. scipy/io/_fast_matrix_market/__init__.py +2 -0
  176. scipy/io/_fast_matrix_market/_fmm_core.cpython-312-aarch64-linux-musl.so +0 -0
  177. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  178. scipy/io/_harwell_boeing/hb.py +7 -11
  179. scipy/io/_idl.py +5 -7
  180. scipy/io/_netcdf.py +15 -5
  181. scipy/io/_test_fortran.cpython-312-aarch64-linux-musl.so +0 -0
  182. scipy/io/arff/tests/test_arffread.py +3 -3
  183. scipy/io/matlab/__init__.py +5 -3
  184. scipy/io/matlab/_mio.py +4 -1
  185. scipy/io/matlab/_mio5.py +19 -13
  186. scipy/io/matlab/_mio5_utils.cpython-312-aarch64-linux-musl.so +0 -0
  187. scipy/io/matlab/_mio_utils.cpython-312-aarch64-linux-musl.so +0 -0
  188. scipy/io/matlab/_miobase.py +4 -1
  189. scipy/io/matlab/_streams.cpython-312-aarch64-linux-musl.so +0 -0
  190. scipy/io/matlab/tests/test_mio.py +46 -18
  191. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  192. scipy/io/tests/test_mmio.py +7 -1
  193. scipy/io/tests/test_wavfile.py +41 -0
  194. scipy/io/wavfile.py +57 -10
  195. scipy/linalg/_basic.py +113 -86
  196. scipy/linalg/_cythonized_array_utils.cpython-312-aarch64-linux-musl.so +0 -0
  197. scipy/linalg/_decomp.py +22 -9
  198. scipy/linalg/_decomp_cholesky.py +28 -13
  199. scipy/linalg/_decomp_cossin.py +45 -30
  200. scipy/linalg/_decomp_interpolative.cpython-312-aarch64-linux-musl.so +0 -0
  201. scipy/linalg/_decomp_ldl.py +4 -1
  202. scipy/linalg/_decomp_lu.py +18 -6
  203. scipy/linalg/_decomp_lu_cython.cpython-312-aarch64-linux-musl.so +0 -0
  204. scipy/linalg/_decomp_polar.py +2 -0
  205. scipy/linalg/_decomp_qr.py +6 -2
  206. scipy/linalg/_decomp_qz.py +3 -0
  207. scipy/linalg/_decomp_schur.py +3 -1
  208. scipy/linalg/_decomp_svd.py +13 -2
  209. scipy/linalg/_decomp_update.cpython-312-aarch64-linux-musl.so +0 -0
  210. scipy/linalg/_expm_frechet.py +4 -0
  211. scipy/linalg/_fblas.cpython-312-aarch64-linux-musl.so +0 -0
  212. scipy/linalg/_flapack.cpython-312-aarch64-linux-musl.so +0 -0
  213. scipy/linalg/_linalg_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  214. scipy/linalg/_matfuncs.py +187 -4
  215. scipy/linalg/_matfuncs_expm.cpython-312-aarch64-linux-musl.so +0 -0
  216. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-aarch64-linux-musl.so +0 -0
  217. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  218. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-aarch64-linux-musl.so +0 -0
  219. scipy/linalg/_procrustes.py +2 -0
  220. scipy/linalg/_sketches.py +17 -6
  221. scipy/linalg/_solve_toeplitz.cpython-312-aarch64-linux-musl.so +0 -0
  222. scipy/linalg/_solvers.py +7 -2
  223. scipy/linalg/_special_matrices.py +26 -36
  224. scipy/linalg/cython_blas.cpython-312-aarch64-linux-musl.so +0 -0
  225. scipy/linalg/cython_lapack.cpython-312-aarch64-linux-musl.so +0 -0
  226. scipy/linalg/lapack.py +22 -2
  227. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  228. scipy/linalg/tests/test_basic.py +31 -16
  229. scipy/linalg/tests/test_batch.py +588 -0
  230. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  231. scipy/linalg/tests/test_decomp.py +40 -3
  232. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  233. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  234. scipy/linalg/tests/test_lapack.py +115 -7
  235. scipy/linalg/tests/test_matfuncs.py +157 -102
  236. scipy/linalg/tests/test_procrustes.py +0 -7
  237. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  238. scipy/linalg/tests/test_special_matrices.py +1 -5
  239. scipy/ndimage/__init__.py +1 -0
  240. scipy/ndimage/_ctest.cpython-312-aarch64-linux-musl.so +0 -0
  241. scipy/ndimage/_cytest.cpython-312-aarch64-linux-musl.so +0 -0
  242. scipy/ndimage/_delegators.py +8 -2
  243. scipy/ndimage/_filters.py +453 -5
  244. scipy/ndimage/_interpolation.py +36 -6
  245. scipy/ndimage/_measurements.py +4 -2
  246. scipy/ndimage/_morphology.py +5 -0
  247. scipy/ndimage/_nd_image.cpython-312-aarch64-linux-musl.so +0 -0
  248. scipy/ndimage/_ni_docstrings.py +5 -1
  249. scipy/ndimage/_ni_label.cpython-312-aarch64-linux-musl.so +0 -0
  250. scipy/ndimage/_ni_support.py +1 -5
  251. scipy/ndimage/_rank_filter_1d.cpython-312-aarch64-linux-musl.so +0 -0
  252. scipy/ndimage/_support_alternative_backends.py +18 -6
  253. scipy/ndimage/tests/test_filters.py +370 -259
  254. scipy/ndimage/tests/test_fourier.py +7 -9
  255. scipy/ndimage/tests/test_interpolation.py +68 -61
  256. scipy/ndimage/tests/test_measurements.py +18 -35
  257. scipy/ndimage/tests/test_morphology.py +143 -131
  258. scipy/ndimage/tests/test_splines.py +1 -3
  259. scipy/odr/__odrpack.cpython-312-aarch64-linux-musl.so +0 -0
  260. scipy/optimize/_basinhopping.py +13 -7
  261. scipy/optimize/_bglu_dense.cpython-312-aarch64-linux-musl.so +0 -0
  262. scipy/optimize/_bracket.py +17 -24
  263. scipy/optimize/_chandrupatla.py +9 -10
  264. scipy/optimize/_cobyla_py.py +104 -123
  265. scipy/optimize/_constraints.py +14 -10
  266. scipy/optimize/_differentiable_functions.py +371 -230
  267. scipy/optimize/_differentialevolution.py +4 -3
  268. scipy/optimize/_direct.cpython-312-aarch64-linux-musl.so +0 -0
  269. scipy/optimize/_dual_annealing.py +1 -1
  270. scipy/optimize/_elementwise.py +1 -4
  271. scipy/optimize/_group_columns.cpython-312-aarch64-linux-musl.so +0 -0
  272. scipy/optimize/_highspy/_core.cpython-312-aarch64-linux-musl.so +0 -0
  273. scipy/optimize/_highspy/_highs_options.cpython-312-aarch64-linux-musl.so +0 -0
  274. scipy/optimize/_lbfgsb.cpython-312-aarch64-linux-musl.so +0 -0
  275. scipy/optimize/_lbfgsb_py.py +57 -16
  276. scipy/optimize/_linprog_doc.py +2 -2
  277. scipy/optimize/_linprog_highs.py +2 -2
  278. scipy/optimize/_linprog_ip.py +25 -10
  279. scipy/optimize/_linprog_util.py +14 -16
  280. scipy/optimize/_lsap.cpython-312-aarch64-linux-musl.so +0 -0
  281. scipy/optimize/_lsq/common.py +3 -3
  282. scipy/optimize/_lsq/dogbox.py +16 -2
  283. scipy/optimize/_lsq/givens_elimination.cpython-312-aarch64-linux-musl.so +0 -0
  284. scipy/optimize/_lsq/least_squares.py +198 -126
  285. scipy/optimize/_lsq/lsq_linear.py +6 -6
  286. scipy/optimize/_lsq/trf.py +35 -8
  287. scipy/optimize/_milp.py +3 -1
  288. scipy/optimize/_minimize.py +105 -36
  289. scipy/optimize/_minpack.cpython-312-aarch64-linux-musl.so +0 -0
  290. scipy/optimize/_minpack_py.py +21 -14
  291. scipy/optimize/_moduleTNC.cpython-312-aarch64-linux-musl.so +0 -0
  292. scipy/optimize/_nnls.py +20 -21
  293. scipy/optimize/_nonlin.py +34 -3
  294. scipy/optimize/_numdiff.py +288 -110
  295. scipy/optimize/_optimize.py +86 -48
  296. scipy/optimize/_pava_pybind.cpython-312-aarch64-linux-musl.so +0 -0
  297. scipy/optimize/_remove_redundancy.py +5 -5
  298. scipy/optimize/_root_scalar.py +1 -1
  299. scipy/optimize/_shgo.py +6 -0
  300. scipy/optimize/_shgo_lib/_complex.py +1 -1
  301. scipy/optimize/_slsqp_py.py +216 -124
  302. scipy/optimize/_slsqplib.cpython-312-aarch64-linux-musl.so +0 -0
  303. scipy/optimize/_spectral.py +1 -1
  304. scipy/optimize/_tnc.py +8 -1
  305. scipy/optimize/_trlib/_trlib.cpython-312-aarch64-linux-musl.so +0 -0
  306. scipy/optimize/_trustregion.py +20 -6
  307. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  308. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  309. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  310. scipy/optimize/_trustregion_constr/projections.py +12 -8
  311. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  312. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  313. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  314. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  315. scipy/optimize/_trustregion_exact.py +0 -1
  316. scipy/optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
  317. scipy/optimize/_zeros_py.py +97 -17
  318. scipy/optimize/cython_optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
  319. scipy/optimize/slsqp.py +0 -1
  320. scipy/optimize/tests/test__basinhopping.py +1 -1
  321. scipy/optimize/tests/test__differential_evolution.py +4 -4
  322. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  323. scipy/optimize/tests/test__numdiff.py +66 -22
  324. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  325. scipy/optimize/tests/test__shgo.py +9 -1
  326. scipy/optimize/tests/test_bracket.py +36 -46
  327. scipy/optimize/tests/test_chandrupatla.py +133 -135
  328. scipy/optimize/tests/test_cobyla.py +74 -45
  329. scipy/optimize/tests/test_constraints.py +1 -1
  330. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  331. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  332. scipy/optimize/tests/test_least_squares.py +125 -13
  333. scipy/optimize/tests/test_linear_assignment.py +3 -3
  334. scipy/optimize/tests/test_linprog.py +3 -3
  335. scipy/optimize/tests/test_lsq_linear.py +6 -6
  336. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  337. scipy/optimize/tests/test_minpack.py +4 -4
  338. scipy/optimize/tests/test_nnls.py +43 -3
  339. scipy/optimize/tests/test_nonlin.py +36 -0
  340. scipy/optimize/tests/test_optimize.py +95 -17
  341. scipy/optimize/tests/test_slsqp.py +36 -4
  342. scipy/optimize/tests/test_zeros.py +34 -1
  343. scipy/signal/__init__.py +12 -23
  344. scipy/signal/_delegators.py +568 -0
  345. scipy/signal/_filter_design.py +459 -241
  346. scipy/signal/_fir_filter_design.py +262 -90
  347. scipy/signal/_lti_conversion.py +3 -2
  348. scipy/signal/_ltisys.py +118 -91
  349. scipy/signal/_max_len_seq_inner.cpython-312-aarch64-linux-musl.so +0 -0
  350. scipy/signal/_peak_finding_utils.cpython-312-aarch64-linux-musl.so +0 -0
  351. scipy/signal/_polyutils.py +172 -0
  352. scipy/signal/_short_time_fft.py +519 -70
  353. scipy/signal/_signal_api.py +30 -0
  354. scipy/signal/_signaltools.py +719 -399
  355. scipy/signal/_sigtools.cpython-312-aarch64-linux-musl.so +0 -0
  356. scipy/signal/_sosfilt.cpython-312-aarch64-linux-musl.so +0 -0
  357. scipy/signal/_spectral_py.py +230 -50
  358. scipy/signal/_spline.cpython-312-aarch64-linux-musl.so +0 -0
  359. scipy/signal/_spline_filters.py +108 -68
  360. scipy/signal/_support_alternative_backends.py +73 -0
  361. scipy/signal/_upfirdn.py +4 -1
  362. scipy/signal/_upfirdn_apply.cpython-312-aarch64-linux-musl.so +0 -0
  363. scipy/signal/_waveforms.py +2 -11
  364. scipy/signal/_wavelets.py +1 -1
  365. scipy/signal/fir_filter_design.py +1 -0
  366. scipy/signal/spline.py +4 -11
  367. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  368. scipy/signal/tests/test_bsplines.py +114 -79
  369. scipy/signal/tests/test_cont2discrete.py +9 -2
  370. scipy/signal/tests/test_filter_design.py +721 -481
  371. scipy/signal/tests/test_fir_filter_design.py +332 -140
  372. scipy/signal/tests/test_savitzky_golay.py +4 -3
  373. scipy/signal/tests/test_short_time_fft.py +221 -3
  374. scipy/signal/tests/test_signaltools.py +2144 -1348
  375. scipy/signal/tests/test_spectral.py +50 -6
  376. scipy/signal/tests/test_splines.py +161 -96
  377. scipy/signal/tests/test_upfirdn.py +84 -50
  378. scipy/signal/tests/test_waveforms.py +20 -0
  379. scipy/signal/tests/test_windows.py +607 -466
  380. scipy/signal/windows/_windows.py +287 -148
  381. scipy/sparse/__init__.py +23 -4
  382. scipy/sparse/_base.py +270 -108
  383. scipy/sparse/_bsr.py +7 -4
  384. scipy/sparse/_compressed.py +59 -231
  385. scipy/sparse/_construct.py +90 -38
  386. scipy/sparse/_coo.py +115 -181
  387. scipy/sparse/_csc.py +4 -4
  388. scipy/sparse/_csparsetools.cpython-312-aarch64-linux-musl.so +0 -0
  389. scipy/sparse/_csr.py +2 -2
  390. scipy/sparse/_data.py +48 -48
  391. scipy/sparse/_dia.py +105 -18
  392. scipy/sparse/_dok.py +0 -23
  393. scipy/sparse/_index.py +4 -4
  394. scipy/sparse/_matrix.py +23 -0
  395. scipy/sparse/_sparsetools.cpython-312-aarch64-linux-musl.so +0 -0
  396. scipy/sparse/_sputils.py +37 -22
  397. scipy/sparse/base.py +0 -9
  398. scipy/sparse/bsr.py +0 -14
  399. scipy/sparse/compressed.py +0 -23
  400. scipy/sparse/construct.py +0 -6
  401. scipy/sparse/coo.py +0 -14
  402. scipy/sparse/csc.py +0 -3
  403. scipy/sparse/csgraph/_flow.cpython-312-aarch64-linux-musl.so +0 -0
  404. scipy/sparse/csgraph/_matching.cpython-312-aarch64-linux-musl.so +0 -0
  405. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-aarch64-linux-musl.so +0 -0
  406. scipy/sparse/csgraph/_reordering.cpython-312-aarch64-linux-musl.so +0 -0
  407. scipy/sparse/csgraph/_shortest_path.cpython-312-aarch64-linux-musl.so +0 -0
  408. scipy/sparse/csgraph/_tools.cpython-312-aarch64-linux-musl.so +0 -0
  409. scipy/sparse/csgraph/_traversal.cpython-312-aarch64-linux-musl.so +0 -0
  410. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  411. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  412. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  413. scipy/sparse/csr.py +0 -5
  414. scipy/sparse/data.py +1 -6
  415. scipy/sparse/dia.py +0 -7
  416. scipy/sparse/dok.py +0 -10
  417. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-aarch64-linux-musl.so +0 -0
  418. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  419. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  420. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-aarch64-linux-musl.so +0 -0
  421. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  422. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  423. scipy/sparse/linalg/_interface.py +17 -18
  424. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  425. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  426. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  427. scipy/sparse/linalg/_isolve/minres.py +5 -5
  428. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  429. scipy/sparse/linalg/_isolve/utils.py +2 -8
  430. scipy/sparse/linalg/_matfuncs.py +1 -1
  431. scipy/sparse/linalg/_norm.py +1 -1
  432. scipy/sparse/linalg/_propack/_cpropack.cpython-312-aarch64-linux-musl.so +0 -0
  433. scipy/sparse/linalg/_propack/_dpropack.cpython-312-aarch64-linux-musl.so +0 -0
  434. scipy/sparse/linalg/_propack/_spropack.cpython-312-aarch64-linux-musl.so +0 -0
  435. scipy/sparse/linalg/_propack/_zpropack.cpython-312-aarch64-linux-musl.so +0 -0
  436. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  437. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  438. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  439. scipy/sparse/tests/test_base.py +214 -42
  440. scipy/sparse/tests/test_common1d.py +7 -7
  441. scipy/sparse/tests/test_construct.py +1 -1
  442. scipy/sparse/tests/test_coo.py +272 -4
  443. scipy/sparse/tests/test_sparsetools.py +5 -0
  444. scipy/sparse/tests/test_sputils.py +36 -7
  445. scipy/spatial/_ckdtree.cpython-312-aarch64-linux-musl.so +0 -0
  446. scipy/spatial/_distance_pybind.cpython-312-aarch64-linux-musl.so +0 -0
  447. scipy/spatial/_distance_wrap.cpython-312-aarch64-linux-musl.so +0 -0
  448. scipy/spatial/_hausdorff.cpython-312-aarch64-linux-musl.so +0 -0
  449. scipy/spatial/_qhull.cpython-312-aarch64-linux-musl.so +0 -0
  450. scipy/spatial/_voronoi.cpython-312-aarch64-linux-musl.so +0 -0
  451. scipy/spatial/distance.py +49 -42
  452. scipy/spatial/tests/test_distance.py +15 -1
  453. scipy/spatial/tests/test_kdtree.py +1 -0
  454. scipy/spatial/tests/test_qhull.py +7 -2
  455. scipy/spatial/transform/__init__.py +5 -3
  456. scipy/spatial/transform/_rigid_transform.cpython-312-aarch64-linux-musl.so +0 -0
  457. scipy/spatial/transform/_rotation.cpython-312-aarch64-linux-musl.so +0 -0
  458. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  459. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  460. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  461. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  462. scipy/special/__init__.py +1 -47
  463. scipy/special/_add_newdocs.py +34 -772
  464. scipy/special/_basic.py +22 -25
  465. scipy/special/_comb.cpython-312-aarch64-linux-musl.so +0 -0
  466. scipy/special/_ellip_harm_2.cpython-312-aarch64-linux-musl.so +0 -0
  467. scipy/special/_gufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  468. scipy/special/_logsumexp.py +67 -58
  469. scipy/special/_orthogonal.pyi +1 -1
  470. scipy/special/_specfun.cpython-312-aarch64-linux-musl.so +0 -0
  471. scipy/special/_special_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  472. scipy/special/_spherical_bessel.py +4 -4
  473. scipy/special/_support_alternative_backends.py +212 -119
  474. scipy/special/_test_internal.cpython-312-aarch64-linux-musl.so +0 -0
  475. scipy/special/_testutils.py +4 -4
  476. scipy/special/_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  477. scipy/special/_ufuncs.pyi +1 -0
  478. scipy/special/_ufuncs.pyx +215 -1400
  479. scipy/special/_ufuncs_cxx.cpython-312-aarch64-linux-musl.so +0 -0
  480. scipy/special/_ufuncs_cxx.pxd +2 -15
  481. scipy/special/_ufuncs_cxx.pyx +5 -44
  482. scipy/special/_ufuncs_cxx_defs.h +2 -16
  483. scipy/special/_ufuncs_defs.h +0 -8
  484. scipy/special/cython_special.cpython-312-aarch64-linux-musl.so +0 -0
  485. scipy/special/cython_special.pxd +1 -1
  486. scipy/special/tests/_cython_examples/meson.build +10 -1
  487. scipy/special/tests/test_basic.py +153 -20
  488. scipy/special/tests/test_boost_ufuncs.py +3 -0
  489. scipy/special/tests/test_cdflib.py +35 -11
  490. scipy/special/tests/test_gammainc.py +16 -0
  491. scipy/special/tests/test_hyp2f1.py +2 -2
  492. scipy/special/tests/test_log1mexp.py +85 -0
  493. scipy/special/tests/test_logsumexp.py +206 -64
  494. scipy/special/tests/test_mpmath.py +1 -0
  495. scipy/special/tests/test_nan_inputs.py +1 -1
  496. scipy/special/tests/test_orthogonal.py +17 -18
  497. scipy/special/tests/test_sf_error.py +3 -2
  498. scipy/special/tests/test_sph_harm.py +6 -7
  499. scipy/special/tests/test_support_alternative_backends.py +211 -76
  500. scipy/stats/__init__.py +4 -1
  501. scipy/stats/_ansari_swilk_statistics.cpython-312-aarch64-linux-musl.so +0 -0
  502. scipy/stats/_axis_nan_policy.py +5 -12
  503. scipy/stats/_biasedurn.cpython-312-aarch64-linux-musl.so +0 -0
  504. scipy/stats/_continued_fraction.py +387 -0
  505. scipy/stats/_continuous_distns.py +277 -310
  506. scipy/stats/_correlation.py +1 -1
  507. scipy/stats/_covariance.py +6 -3
  508. scipy/stats/_discrete_distns.py +39 -32
  509. scipy/stats/_distn_infrastructure.py +39 -12
  510. scipy/stats/_distribution_infrastructure.py +900 -238
  511. scipy/stats/_entropy.py +9 -10
  512. scipy/{_lib → stats}/_finite_differences.py +1 -1
  513. scipy/stats/_hypotests.py +83 -50
  514. scipy/stats/_kde.py +53 -49
  515. scipy/stats/_ksstats.py +1 -1
  516. scipy/stats/_levy_stable/__init__.py +7 -15
  517. scipy/stats/_levy_stable/levyst.cpython-312-aarch64-linux-musl.so +0 -0
  518. scipy/stats/_morestats.py +118 -73
  519. scipy/stats/_mstats_basic.py +13 -17
  520. scipy/stats/_mstats_extras.py +8 -8
  521. scipy/stats/_multivariate.py +89 -113
  522. scipy/stats/_new_distributions.py +97 -20
  523. scipy/stats/_page_trend_test.py +12 -5
  524. scipy/stats/_probability_distribution.py +265 -43
  525. scipy/stats/_qmc.py +14 -9
  526. scipy/stats/_qmc_cy.cpython-312-aarch64-linux-musl.so +0 -0
  527. scipy/stats/_qmvnt.py +16 -95
  528. scipy/stats/_qmvnt_cy.cpython-312-aarch64-linux-musl.so +0 -0
  529. scipy/stats/_quantile.py +335 -0
  530. scipy/stats/_rcont/rcont.cpython-312-aarch64-linux-musl.so +0 -0
  531. scipy/stats/_resampling.py +4 -29
  532. scipy/stats/_sampling.py +1 -1
  533. scipy/stats/_sobol.cpython-312-aarch64-linux-musl.so +0 -0
  534. scipy/stats/_stats.cpython-312-aarch64-linux-musl.so +0 -0
  535. scipy/stats/_stats_mstats_common.py +21 -2
  536. scipy/stats/_stats_py.py +550 -476
  537. scipy/stats/_stats_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  538. scipy/stats/_unuran/unuran_wrapper.cpython-312-aarch64-linux-musl.so +0 -0
  539. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  540. scipy/stats/_variation.py +6 -8
  541. scipy/stats/_wilcoxon.py +13 -7
  542. scipy/stats/tests/common_tests.py +6 -4
  543. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  544. scipy/stats/tests/test_continued_fraction.py +173 -0
  545. scipy/stats/tests/test_continuous.py +379 -60
  546. scipy/stats/tests/test_continuous_basic.py +18 -12
  547. scipy/stats/tests/test_discrete_basic.py +14 -8
  548. scipy/stats/tests/test_discrete_distns.py +16 -16
  549. scipy/stats/tests/test_distributions.py +95 -75
  550. scipy/stats/tests/test_entropy.py +40 -48
  551. scipy/stats/tests/test_fit.py +4 -3
  552. scipy/stats/tests/test_hypotests.py +153 -24
  553. scipy/stats/tests/test_kdeoth.py +109 -41
  554. scipy/stats/tests/test_marray.py +289 -0
  555. scipy/stats/tests/test_morestats.py +79 -47
  556. scipy/stats/tests/test_mstats_basic.py +3 -3
  557. scipy/stats/tests/test_multivariate.py +434 -83
  558. scipy/stats/tests/test_qmc.py +13 -10
  559. scipy/stats/tests/test_quantile.py +199 -0
  560. scipy/stats/tests/test_rank.py +119 -112
  561. scipy/stats/tests/test_resampling.py +47 -56
  562. scipy/stats/tests/test_sampling.py +9 -4
  563. scipy/stats/tests/test_stats.py +799 -939
  564. scipy/stats/tests/test_variation.py +8 -6
  565. scipy/version.py +2 -2
  566. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  567. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  568. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +1262 -1269
  569. scipy.libs/libgcc_s-69c45f16.so.1 +0 -0
  570. scipy.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
  571. scipy.libs/{libstdc++-1b614e01.so.6.0.32 → libstdc++-1f1a71be.so.6.0.33} +0 -0
  572. scipy/_lib/array_api_extra/_funcs.py +0 -484
  573. scipy/_lib/array_api_extra/_typing.py +0 -8
  574. scipy/interpolate/_bspl.cpython-312-aarch64-linux-musl.so +0 -0
  575. scipy/optimize/_cobyla.cpython-312-aarch64-linux-musl.so +0 -0
  576. scipy/optimize/_cython_nnls.cpython-312-aarch64-linux-musl.so +0 -0
  577. scipy/optimize/_slsqp.cpython-312-aarch64-linux-musl.so +0 -0
  578. scipy/spatial/qhull_src/COPYING.txt +0 -38
  579. scipy/special/libsf_error_state.so +0 -0
  580. scipy/special/tests/test_log_softmax.py +0 -109
  581. scipy/special/tests/test_xsf_cuda.py +0 -114
  582. scipy/special/xsf/binom.h +0 -89
  583. scipy/special/xsf/cdflib.h +0 -100
  584. scipy/special/xsf/cephes/airy.h +0 -307
  585. scipy/special/xsf/cephes/besselpoly.h +0 -51
  586. scipy/special/xsf/cephes/beta.h +0 -257
  587. scipy/special/xsf/cephes/cbrt.h +0 -131
  588. scipy/special/xsf/cephes/chbevl.h +0 -85
  589. scipy/special/xsf/cephes/chdtr.h +0 -193
  590. scipy/special/xsf/cephes/const.h +0 -87
  591. scipy/special/xsf/cephes/ellie.h +0 -293
  592. scipy/special/xsf/cephes/ellik.h +0 -251
  593. scipy/special/xsf/cephes/ellpe.h +0 -107
  594. scipy/special/xsf/cephes/ellpk.h +0 -117
  595. scipy/special/xsf/cephes/expn.h +0 -260
  596. scipy/special/xsf/cephes/gamma.h +0 -398
  597. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  598. scipy/special/xsf/cephes/hyperg.h +0 -361
  599. scipy/special/xsf/cephes/i0.h +0 -149
  600. scipy/special/xsf/cephes/i1.h +0 -158
  601. scipy/special/xsf/cephes/igam.h +0 -421
  602. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  603. scipy/special/xsf/cephes/igami.h +0 -313
  604. scipy/special/xsf/cephes/j0.h +0 -225
  605. scipy/special/xsf/cephes/j1.h +0 -198
  606. scipy/special/xsf/cephes/jv.h +0 -715
  607. scipy/special/xsf/cephes/k0.h +0 -164
  608. scipy/special/xsf/cephes/k1.h +0 -163
  609. scipy/special/xsf/cephes/kn.h +0 -243
  610. scipy/special/xsf/cephes/lanczos.h +0 -112
  611. scipy/special/xsf/cephes/ndtr.h +0 -275
  612. scipy/special/xsf/cephes/poch.h +0 -85
  613. scipy/special/xsf/cephes/polevl.h +0 -167
  614. scipy/special/xsf/cephes/psi.h +0 -194
  615. scipy/special/xsf/cephes/rgamma.h +0 -111
  616. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  617. scipy/special/xsf/cephes/shichi.h +0 -248
  618. scipy/special/xsf/cephes/sici.h +0 -224
  619. scipy/special/xsf/cephes/sindg.h +0 -221
  620. scipy/special/xsf/cephes/tandg.h +0 -139
  621. scipy/special/xsf/cephes/trig.h +0 -58
  622. scipy/special/xsf/cephes/unity.h +0 -186
  623. scipy/special/xsf/cephes/zeta.h +0 -172
  624. scipy/special/xsf/config.h +0 -304
  625. scipy/special/xsf/digamma.h +0 -205
  626. scipy/special/xsf/error.h +0 -57
  627. scipy/special/xsf/evalpoly.h +0 -47
  628. scipy/special/xsf/expint.h +0 -266
  629. scipy/special/xsf/hyp2f1.h +0 -694
  630. scipy/special/xsf/iv_ratio.h +0 -173
  631. scipy/special/xsf/lambertw.h +0 -150
  632. scipy/special/xsf/loggamma.h +0 -163
  633. scipy/special/xsf/sici.h +0 -200
  634. scipy/special/xsf/tools.h +0 -427
  635. scipy/special/xsf/trig.h +0 -164
  636. scipy/special/xsf/wright_bessel.h +0 -843
  637. scipy/special/xsf/zlog1.h +0 -35
  638. scipy/stats/_mvn.cpython-312-aarch64-linux-musl.so +0 -0
  639. scipy.libs/libgcc_s-7393e603.so.1 +0 -0
  640. scipy.libs/libgfortran-eb933d8e.so.5.0.0 +0 -0
  641. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
@@ -0,0 +1,105 @@
1
+ """Static typing helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from types import EllipsisType
6
+ from typing import Protocol, TypeAlias
7
+
8
+ # TODO import from typing (requires Python >=3.12)
9
+ from typing_extensions import override
10
+
11
+ # TODO: use array-api-typing once it is available
12
+
13
+ class Array(Protocol): # pylint: disable=missing-class-docstring
14
+ # Unary operations
15
+ def __abs__(self) -> Array: ...
16
+ def __pos__(self) -> Array: ...
17
+ def __neg__(self) -> Array: ...
18
+ def __invert__(self) -> Array: ...
19
+ # Binary operations
20
+ def __add__(self, other: Array | complex, /) -> Array: ...
21
+ def __sub__(self, other: Array | complex, /) -> Array: ...
22
+ def __mul__(self, other: Array | complex, /) -> Array: ...
23
+ def __truediv__(self, other: Array | complex, /) -> Array: ...
24
+ def __floordiv__(self, other: Array | complex, /) -> Array: ...
25
+ def __mod__(self, other: Array | complex, /) -> Array: ...
26
+ def __pow__(self, other: Array | complex, /) -> Array: ...
27
+ def __matmul__(self, other: Array, /) -> Array: ...
28
+ def __and__(self, other: Array | int, /) -> Array: ...
29
+ def __or__(self, other: Array | int, /) -> Array: ...
30
+ def __xor__(self, other: Array | int, /) -> Array: ...
31
+ def __lshift__(self, other: Array | int, /) -> Array: ...
32
+ def __rshift__(self, other: Array | int, /) -> Array: ...
33
+ def __lt__(self, other: Array | complex, /) -> Array: ...
34
+ def __le__(self, other: Array | complex, /) -> Array: ...
35
+ def __gt__(self, other: Array | complex, /) -> Array: ...
36
+ def __ge__(self, other: Array | complex, /) -> Array: ...
37
+ @override
38
+ def __eq__(self, other: Array | complex, /) -> Array: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
39
+ @override
40
+ def __ne__(self, other: Array | complex, /) -> Array: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
41
+ # Reflected operations
42
+ def __radd__(self, other: Array | complex, /) -> Array: ...
43
+ def __rsub__(self, other: Array | complex, /) -> Array: ...
44
+ def __rmul__(self, other: Array | complex, /) -> Array: ...
45
+ def __rtruediv__(self, other: Array | complex, /) -> Array: ...
46
+ def __rfloordiv__(self, other: Array | complex, /) -> Array: ...
47
+ def __rmod__(self, other: Array | complex, /) -> Array: ...
48
+ def __rpow__(self, other: Array | complex, /) -> Array: ...
49
+ def __rmatmul__(self, other: Array, /) -> Array: ...
50
+ def __rand__(self, other: Array | int, /) -> Array: ...
51
+ def __ror__(self, other: Array | int, /) -> Array: ...
52
+ def __rxor__(self, other: Array | int, /) -> Array: ...
53
+ def __rlshift__(self, other: Array | int, /) -> Array: ...
54
+ def __rrshift__(self, other: Array | int, /) -> Array: ...
55
+ # Attributes
56
+ @property
57
+ def dtype(self) -> DType: ...
58
+ @property
59
+ def device(self) -> Device: ...
60
+ @property
61
+ def mT(self) -> Array: ... # pylint: disable=invalid-name
62
+ @property
63
+ def ndim(self) -> int: ...
64
+ @property
65
+ def shape(self) -> tuple[int | None, ...]: ...
66
+ @property
67
+ def size(self) -> int | None: ...
68
+ @property
69
+ def T(self) -> Array: ... # pylint: disable=invalid-name
70
+ # Collection operations (note: an Array does not have to be Sized or Iterable)
71
+ def __getitem__(self, key: GetIndex, /) -> Array: ...
72
+ def __setitem__(self, key: SetIndex, value: Array | complex, /) -> None: ...
73
+ # Materialization methods (may raise on lazy arrays)
74
+ def __bool__(self) -> bool: ...
75
+ def __complex__(self) -> complex: ...
76
+ def __float__(self) -> float: ...
77
+ def __index__(self) -> int: ...
78
+ def __int__(self) -> int: ...
79
+
80
+ # Misc methods (frequently not implemented in Arrays wrapped by array-api-compat)
81
+ # def __array_namespace__(*, api_version: str | None) -> ModuleType: ...
82
+ # def __dlpack__(
83
+ # *,
84
+ # stream: int | Any | None = None,
85
+ # max_version: tuple[int, int] | None = None,
86
+ # dl_device: tuple[int, int] | None = None, # tuple[Enum, int]
87
+ # copy: bool | None = None,
88
+ # ) -> Any: ...
89
+ # def __dlpack_device__() -> tuple[int, int]: ... # tuple[Enum, int]
90
+ # def to_device(device: Device, /, *, stream: int | Any | None = None) -> Array: ...
91
+
92
+ class DType(Protocol): # pylint: disable=missing-class-docstring
93
+ pass
94
+
95
+ class Device(Protocol): # pylint: disable=missing-class-docstring
96
+ pass
97
+
98
+ SetIndex: TypeAlias = ( # type: ignore[explicit-any]
99
+ int | slice | EllipsisType | Array | tuple[int | slice | EllipsisType | Array, ...]
100
+ )
101
+ GetIndex: TypeAlias = ( # type: ignore[explicit-any]
102
+ SetIndex | None | tuple[int | slice | EllipsisType | None | Array, ...]
103
+ )
104
+
105
+ __all__ = ["Array", "DType", "Device", "GetIndex", "SetIndex"]
@@ -0,0 +1,359 @@
1
+ """
2
+ Public testing utilities.
3
+
4
+ See also _lib._testing for additional private testing utilities.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import contextlib
10
+ import enum
11
+ import warnings
12
+ from collections.abc import Callable, Iterator, Sequence
13
+ from functools import wraps
14
+ from types import ModuleType
15
+ from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar, cast
16
+
17
+ from ._lib._utils._compat import is_dask_namespace, is_jax_namespace
18
+ from ._lib._utils._helpers import jax_autojit, pickle_flatten, pickle_unflatten
19
+
20
+ __all__ = ["lazy_xp_function", "patch_lazy_xp_functions"]
21
+
22
+ if TYPE_CHECKING: # pragma: no cover
23
+ # TODO import override from typing (requires Python >=3.12)
24
+ import pytest
25
+ from dask.typing import Graph, Key, SchedulerGetCallable
26
+ from typing_extensions import override
27
+
28
+ else:
29
+ # Sphinx hacks
30
+ SchedulerGetCallable = object
31
+
32
+ def override(func):
33
+ return func
34
+
35
+
36
+ P = ParamSpec("P")
37
+ T = TypeVar("T")
38
+
39
+ _ufuncs_tags: dict[object, dict[str, Any]] = {} # type: ignore[explicit-any]
40
+
41
+
42
+ class Deprecated(enum.Enum):
43
+ """Unique type for deprecated parameters."""
44
+
45
+ DEPRECATED = 1
46
+
47
+
48
+ DEPRECATED = Deprecated.DEPRECATED
49
+
50
+
51
+ def lazy_xp_function( # type: ignore[explicit-any]
52
+ func: Callable[..., Any],
53
+ *,
54
+ allow_dask_compute: bool | int = False,
55
+ jax_jit: bool = True,
56
+ static_argnums: Deprecated = DEPRECATED,
57
+ static_argnames: Deprecated = DEPRECATED,
58
+ ) -> None: # numpydoc ignore=GL07
59
+ """
60
+ Tag a function to be tested on lazy backends.
61
+
62
+ Tag a function so that when any tests are executed with ``xp=jax.numpy`` the
63
+ function is replaced with a jitted version of itself, and when it is executed with
64
+ ``xp=dask.array`` the function will raise if it attempts to materialize the graph.
65
+ This will be later expanded to provide test coverage for other lazy backends.
66
+
67
+ In order for the tag to be effective, the test or a fixture must call
68
+ :func:`patch_lazy_xp_functions`.
69
+
70
+ Parameters
71
+ ----------
72
+ func : callable
73
+ Function to be tested.
74
+ allow_dask_compute : bool | int, optional
75
+ Whether `func` is allowed to internally materialize the Dask graph, or maximum
76
+ number of times it is allowed to do so. This is typically triggered by
77
+ ``bool()``, ``float()``, or ``np.asarray()``.
78
+
79
+ Set to 1 if you are aware that `func` converts the input parameters to NumPy and
80
+ want to let it do so at least for the time being, knowing that it is going to be
81
+ extremely detrimental for performance.
82
+
83
+ If a test needs values higher than 1 to pass, it is a canary that the conversion
84
+ to NumPy/bool/float is happening multiple times, which translates to multiple
85
+ computations of the whole graph. Short of making the function fully lazy, you
86
+ should at least add explicit calls to ``np.asarray()`` early in the function.
87
+ *Note:* the counter of `allow_dask_compute` resets after each call to `func`, so
88
+ a test function that invokes `func` multiple times should still work with this
89
+ parameter set to 1.
90
+
91
+ Set to True to allow `func` to materialize the graph an unlimited number
92
+ of times.
93
+
94
+ Default: False, meaning that `func` must be fully lazy and never materialize the
95
+ graph.
96
+ jax_jit : bool, optional
97
+ Set to True to replace `func` with a smart variant of ``jax.jit(func)`` after
98
+ calling the :func:`patch_lazy_xp_functions` test helper with ``xp=jax.numpy``.
99
+ Set to False if `func` is only compatible with eager (non-jitted) JAX.
100
+
101
+ Unlike with vanilla ``jax.jit``, all arguments and return types that are not JAX
102
+ arrays are treated as static; the function can accept and return arbitrary
103
+ wrappers around JAX arrays. This difference is because, in real life, most users
104
+ won't wrap the function directly with ``jax.jit`` but rather they will use it
105
+ within their own code, which is itself then wrapped by ``jax.jit``, and
106
+ internally consume the function's outputs.
107
+
108
+ In other words, the pattern that is being tested is::
109
+
110
+ >>> @jax.jit
111
+ ... def user_func(x):
112
+ ... y = user_prepares_inputs(x)
113
+ ... z = func(y, some_static_arg=True)
114
+ ... return user_consumes(z)
115
+
116
+ Default: True.
117
+ static_argnums :
118
+ Deprecated; ignored
119
+ static_argnames :
120
+ Deprecated; ignored
121
+
122
+ See Also
123
+ --------
124
+ patch_lazy_xp_functions : Companion function to call from the test or fixture.
125
+ jax.jit : JAX function to compile a function for performance.
126
+
127
+ Examples
128
+ --------
129
+ In ``test_mymodule.py``::
130
+
131
+ from array_api_extra.testing import lazy_xp_function from mymodule import myfunc
132
+
133
+ lazy_xp_function(myfunc)
134
+
135
+ def test_myfunc(xp):
136
+ a = xp.asarray([1, 2])
137
+ # When xp=jax.numpy, this is similar to `b = jax.jit(myfunc)(a)`
138
+ # When xp=dask.array, crash on compute() or persist()
139
+ b = myfunc(a)
140
+
141
+ Notes
142
+ -----
143
+ In order for this tag to be effective, the test function must be imported into the
144
+ test module globals without its namespace; alternatively its namespace must be
145
+ declared in a ``lazy_xp_modules`` list in the test module globals.
146
+
147
+ Example 1::
148
+
149
+ from mymodule import myfunc
150
+
151
+ lazy_xp_function(myfunc)
152
+
153
+ def test_myfunc(xp):
154
+ x = myfunc(xp.asarray([1, 2]))
155
+
156
+ Example 2::
157
+
158
+ import mymodule
159
+
160
+ lazy_xp_modules = [mymodule]
161
+ lazy_xp_function(mymodule.myfunc)
162
+
163
+ def test_myfunc(xp):
164
+ x = mymodule.myfunc(xp.asarray([1, 2]))
165
+
166
+ A test function can circumvent this monkey-patching system by using a namespace
167
+ outside of the two above patterns. You need to sanitize your code to make sure this
168
+ only happens intentionally.
169
+
170
+ Example 1::
171
+
172
+ import mymodule
173
+ from mymodule import myfunc
174
+
175
+ lazy_xp_function(myfunc)
176
+
177
+ def test_myfunc(xp):
178
+ a = xp.asarray([1, 2])
179
+ b = myfunc(a) # This is wrapped when xp=jax.numpy or xp=dask.array
180
+ c = mymodule.myfunc(a) # This is not
181
+
182
+ Example 2::
183
+
184
+ import mymodule
185
+
186
+ class naked:
187
+ myfunc = mymodule.myfunc
188
+
189
+ lazy_xp_modules = [mymodule]
190
+ lazy_xp_function(mymodule.myfunc)
191
+
192
+ def test_myfunc(xp):
193
+ a = xp.asarray([1, 2])
194
+ b = mymodule.myfunc(a) # This is wrapped when xp=jax.numpy or xp=dask.array
195
+ c = naked.myfunc(a) # This is not
196
+ """
197
+ if static_argnums is not DEPRECATED or static_argnames is not DEPRECATED:
198
+ warnings.warn(
199
+ (
200
+ "The `static_argnums` and `static_argnames` parameters are deprecated "
201
+ "and ignored. They will be removed in a future version."
202
+ ),
203
+ DeprecationWarning,
204
+ stacklevel=2,
205
+ )
206
+ tags = {
207
+ "allow_dask_compute": allow_dask_compute,
208
+ "jax_jit": jax_jit,
209
+ }
210
+
211
+ try:
212
+ func._lazy_xp_function = tags # type: ignore[attr-defined] # pylint: disable=protected-access # pyright: ignore[reportFunctionMemberAccess]
213
+ except AttributeError: # @cython.vectorize
214
+ _ufuncs_tags[func] = tags
215
+
216
+
217
+ def patch_lazy_xp_functions(
218
+ request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch, *, xp: ModuleType
219
+ ) -> None:
220
+ """
221
+ Test lazy execution of functions tagged with :func:`lazy_xp_function`.
222
+
223
+ If ``xp==jax.numpy``, search for all functions which have been tagged with
224
+ :func:`lazy_xp_function` in the globals of the module that defines the current test,
225
+ as well as in the ``lazy_xp_modules`` list in the globals of the same module,
226
+ and wrap them with :func:`jax.jit`. Unwrap them at the end of the test.
227
+
228
+ If ``xp==dask.array``, wrap the functions with a decorator that disables
229
+ ``compute()`` and ``persist()`` and ensures that exceptions and warnings are raised
230
+ eagerly.
231
+
232
+ This function should be typically called by your library's `xp` fixture that runs
233
+ tests on multiple backends::
234
+
235
+ @pytest.fixture(params=[numpy, array_api_strict, jax.numpy, dask.array])
236
+ def xp(request, monkeypatch):
237
+ patch_lazy_xp_functions(request, monkeypatch, xp=request.param)
238
+ return request.param
239
+
240
+ but it can be otherwise be called by the test itself too.
241
+
242
+ Parameters
243
+ ----------
244
+ request : pytest.FixtureRequest
245
+ Pytest fixture, as acquired by the test itself or by one of its fixtures.
246
+ monkeypatch : pytest.MonkeyPatch
247
+ Pytest fixture, as acquired by the test itself or by one of its fixtures.
248
+ xp : array_namespace
249
+ Array namespace to be tested.
250
+
251
+ See Also
252
+ --------
253
+ lazy_xp_function : Tag a function to be tested on lazy backends.
254
+ pytest.FixtureRequest : `request` test function parameter.
255
+ """
256
+ mod = cast(ModuleType, request.module)
257
+ mods = [mod, *cast(list[ModuleType], getattr(mod, "lazy_xp_modules", []))]
258
+
259
+ def iter_tagged() -> ( # type: ignore[explicit-any]
260
+ Iterator[tuple[ModuleType, str, Callable[..., Any], dict[str, Any]]]
261
+ ):
262
+ for mod in mods:
263
+ for name, func in mod.__dict__.items():
264
+ tags: dict[str, Any] | None = None # type: ignore[explicit-any]
265
+ with contextlib.suppress(AttributeError):
266
+ tags = func._lazy_xp_function # pylint: disable=protected-access
267
+ if tags is None:
268
+ with contextlib.suppress(KeyError, TypeError):
269
+ tags = _ufuncs_tags[func]
270
+ if tags is not None:
271
+ yield mod, name, func, tags
272
+
273
+ if is_dask_namespace(xp):
274
+ for mod, name, func, tags in iter_tagged():
275
+ n = tags["allow_dask_compute"]
276
+ if n is True:
277
+ n = 1_000_000
278
+ elif n is False:
279
+ n = 0
280
+ wrapped = _dask_wrap(func, n)
281
+ monkeypatch.setattr(mod, name, wrapped)
282
+
283
+ elif is_jax_namespace(xp):
284
+ for mod, name, func, tags in iter_tagged():
285
+ if tags["jax_jit"]:
286
+ wrapped = jax_autojit(func)
287
+ monkeypatch.setattr(mod, name, wrapped)
288
+
289
+
290
+ class CountingDaskScheduler(SchedulerGetCallable):
291
+ """
292
+ Dask scheduler that counts how many times `dask.compute` is called.
293
+
294
+ If the number of times exceeds 'max_count', it raises an error.
295
+ This is a wrapper around Dask's own 'synchronous' scheduler.
296
+
297
+ Parameters
298
+ ----------
299
+ max_count : int
300
+ Maximum number of allowed calls to `dask.compute`.
301
+ msg : str
302
+ Assertion to raise when the count exceeds `max_count`.
303
+ """
304
+
305
+ count: int
306
+ max_count: int
307
+ msg: str
308
+
309
+ def __init__(self, max_count: int, msg: str): # numpydoc ignore=GL08
310
+ self.count = 0
311
+ self.max_count = max_count
312
+ self.msg = msg
313
+
314
+ @override
315
+ def __call__(self, dsk: Graph, keys: Sequence[Key] | Key, **kwargs: Any) -> Any: # type: ignore[decorated-any,explicit-any] # numpydoc ignore=GL08
316
+ import dask
317
+
318
+ self.count += 1
319
+ # This should yield a nice traceback to the
320
+ # offending line in the user's code
321
+ assert self.count <= self.max_count, self.msg
322
+
323
+ return dask.get(dsk, keys, **kwargs) # type: ignore[attr-defined,no-untyped-call] # pyright: ignore[reportPrivateImportUsage]
324
+
325
+
326
+ def _dask_wrap(
327
+ func: Callable[P, T], n: int
328
+ ) -> Callable[P, T]: # numpydoc ignore=PR01,RT01
329
+ """
330
+ Wrap `func` to raise if it attempts to call `dask.compute` more than `n` times.
331
+
332
+ After the function returns, materialize the graph in order to re-raise exceptions.
333
+ """
334
+ import dask
335
+ import dask.array as da
336
+
337
+ func_name = getattr(func, "__name__", str(func))
338
+ n_str = f"only up to {n}" if n else "no"
339
+ msg = (
340
+ f"Called `dask.compute()` or `dask.persist()` {n + 1} times, "
341
+ f"but {n_str} calls are allowed. Set "
342
+ f"`lazy_xp_function({func_name}, allow_dask_compute={n + 1})` "
343
+ "to allow for more (but note that this will harm performance). "
344
+ )
345
+
346
+ @wraps(func)
347
+ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: # numpydoc ignore=GL08
348
+ scheduler = CountingDaskScheduler(n, msg)
349
+ with dask.config.set({"scheduler": scheduler}): # pyright: ignore[reportPrivateImportUsage]
350
+ out = func(*args, **kwargs)
351
+
352
+ # Block until the graph materializes and reraise exceptions. This allows
353
+ # `pytest.raises` and `pytest.warns` to work as expected. Note that this would
354
+ # not work on scheduler='distributed', as it would not block.
355
+ arrays, rest = pickle_flatten(out, da.Array)
356
+ arrays = dask.persist(arrays, scheduler="threads")[0] # type: ignore[attr-defined,no-untyped-call,func-returns-value,index] # pyright: ignore[reportPrivateImportUsage]
357
+ return pickle_unflatten(arrays, rest) # pyright: ignore[reportUnknownArgumentType]
358
+
359
+ return wrapper
scipy/_lib/decorator.py CHANGED
@@ -89,7 +89,7 @@ class FunctionMaker:
89
89
  'kwonlydefaults'):
90
90
  setattr(self, a, getattr(argspec, a))
91
91
  for i, arg in enumerate(self.args):
92
- setattr(self, 'arg%d' % i, arg)
92
+ setattr(self, f'arg{i}', arg)
93
93
  allargs = list(self.args)
94
94
  allshortargs = list(self.args)
95
95
  if self.varargs:
@@ -160,7 +160,7 @@ class FunctionMaker:
160
160
  # Ensure each generated function has a unique filename for profilers
161
161
  # (such as cProfile) that depend on the tuple of (<filename>,
162
162
  # <definition line>, <function name>) being unique.
163
- filename = '<decorator-gen-%d>' % (next(self._compile_count),)
163
+ filename = f'<decorator-gen-{next(self._compile_count)}>'
164
164
  try:
165
165
  code = compile(src, filename, 'single')
166
166
  exec(code, evaldict)
scipy/_lib/doccer.py CHANGED
@@ -75,13 +75,7 @@ def docformat(docstring: str, docdict: Mapping[str, str] | None = None) -> str:
75
75
  indented = {}
76
76
  for name, dstr in docdict.items():
77
77
  lines = dstr.expandtabs().splitlines()
78
- try:
79
- newlines = [lines[0]]
80
- for line in lines[1:]:
81
- newlines.append(indent + line)
82
- indented[name] = "\n".join(newlines)
83
- except IndexError:
84
- indented[name] = dstr
78
+ indented[name] = ("\n" + indent).join(lines)
85
79
  return docstring % indented
86
80
 
87
81