scipy 1.15.3__cp312-cp312-macosx_12_0_arm64.whl → 1.16.0rc2__cp312-cp312-macosx_12_0_arm64.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 (629) hide show
  1. scipy/.dylibs/libscipy_openblas.dylib +0 -0
  2. scipy/__config__.py +8 -8
  3. scipy/__init__.py +3 -6
  4. scipy/_cyutility.cpython-312-darwin.so +0 -0
  5. scipy/_lib/_array_api.py +486 -161
  6. scipy/_lib/_array_api_compat_vendor.py +9 -0
  7. scipy/_lib/_bunch.py +4 -0
  8. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  9. scipy/_lib/_docscrape.py +1 -1
  10. scipy/_lib/_elementwise_iterative_method.py +15 -26
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  14. scipy/_lib/_testutils.py +6 -2
  15. scipy/_lib/_util.py +222 -125
  16. scipy/_lib/array_api_compat/__init__.py +4 -4
  17. scipy/_lib/array_api_compat/_internal.py +19 -6
  18. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  19. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  20. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  21. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  22. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  23. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  24. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  25. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  26. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  27. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  28. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  29. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  30. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  31. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  32. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  33. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  34. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  35. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  36. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  37. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  38. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  39. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  40. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  41. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  42. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  43. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  44. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  45. scipy/_lib/array_api_extra/__init__.py +26 -3
  46. scipy/_lib/array_api_extra/_delegation.py +171 -0
  47. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  48. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  49. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  50. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  51. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  52. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  59. scipy/_lib/array_api_extra/testing.py +359 -0
  60. scipy/_lib/decorator.py +2 -2
  61. scipy/_lib/doccer.py +1 -7
  62. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  63. scipy/_lib/pyprima/__init__.py +212 -0
  64. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  65. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  66. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  67. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  68. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  69. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  70. scipy/_lib/pyprima/cobyla/update.py +289 -0
  71. scipy/_lib/pyprima/common/__init__.py +0 -0
  72. scipy/_lib/pyprima/common/_bounds.py +34 -0
  73. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  74. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  75. scipy/_lib/pyprima/common/_project.py +173 -0
  76. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  77. scipy/_lib/pyprima/common/consts.py +47 -0
  78. scipy/_lib/pyprima/common/evaluate.py +99 -0
  79. scipy/_lib/pyprima/common/history.py +38 -0
  80. scipy/_lib/pyprima/common/infos.py +30 -0
  81. scipy/_lib/pyprima/common/linalg.py +435 -0
  82. scipy/_lib/pyprima/common/message.py +290 -0
  83. scipy/_lib/pyprima/common/powalg.py +131 -0
  84. scipy/_lib/pyprima/common/preproc.py +277 -0
  85. scipy/_lib/pyprima/common/present.py +5 -0
  86. scipy/_lib/pyprima/common/ratio.py +54 -0
  87. scipy/_lib/pyprima/common/redrho.py +47 -0
  88. scipy/_lib/pyprima/common/selectx.py +296 -0
  89. scipy/_lib/tests/test__util.py +105 -121
  90. scipy/_lib/tests/test_array_api.py +166 -35
  91. scipy/_lib/tests/test_bunch.py +7 -0
  92. scipy/_lib/tests/test_ccallback.py +2 -10
  93. scipy/_lib/tests/test_public_api.py +13 -0
  94. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  97. scipy/cluster/hierarchy.py +393 -223
  98. scipy/cluster/tests/test_hierarchy.py +273 -335
  99. scipy/cluster/tests/test_vq.py +45 -61
  100. scipy/cluster/vq.py +39 -35
  101. scipy/conftest.py +263 -157
  102. scipy/constants/_constants.py +4 -1
  103. scipy/constants/tests/test_codata.py +2 -2
  104. scipy/constants/tests/test_constants.py +11 -18
  105. scipy/datasets/_download_all.py +15 -1
  106. scipy/datasets/_fetchers.py +7 -1
  107. scipy/datasets/_utils.py +1 -1
  108. scipy/differentiate/_differentiate.py +25 -25
  109. scipy/differentiate/tests/test_differentiate.py +24 -25
  110. scipy/fft/_basic.py +20 -0
  111. scipy/fft/_helper.py +3 -34
  112. scipy/fft/_pocketfft/helper.py +29 -1
  113. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  114. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  115. scipy/fft/_realtransforms.py +13 -0
  116. scipy/fft/tests/test_basic.py +27 -25
  117. scipy/fft/tests/test_fftlog.py +16 -7
  118. scipy/fft/tests/test_helper.py +18 -34
  119. scipy/fft/tests/test_real_transforms.py +8 -10
  120. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  121. scipy/fftpack/tests/test_basic.py +2 -4
  122. scipy/fftpack/tests/test_real_transforms.py +8 -9
  123. scipy/integrate/_bvp.py +9 -3
  124. scipy/integrate/_cubature.py +3 -2
  125. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  127. scipy/integrate/_ode.py +9 -2
  128. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  129. scipy/integrate/_quad_vec.py +21 -29
  130. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  131. scipy/integrate/_quadpack_py.py +11 -7
  132. scipy/integrate/_quadrature.py +3 -3
  133. scipy/integrate/_rules/_base.py +2 -2
  134. scipy/integrate/_tanhsinh.py +48 -47
  135. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  136. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  137. scipy/integrate/tests/test__quad_vec.py +0 -6
  138. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  139. scipy/integrate/tests/test_cubature.py +21 -35
  140. scipy/integrate/tests/test_quadrature.py +6 -8
  141. scipy/integrate/tests/test_tanhsinh.py +56 -48
  142. scipy/interpolate/__init__.py +70 -58
  143. scipy/interpolate/_bary_rational.py +22 -22
  144. scipy/interpolate/_bsplines.py +119 -66
  145. scipy/interpolate/_cubic.py +65 -50
  146. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  147. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  148. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  149. scipy/interpolate/_fitpack2.py +9 -6
  150. scipy/interpolate/_fitpack_impl.py +32 -26
  151. scipy/interpolate/_fitpack_repro.py +23 -19
  152. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  153. scipy/interpolate/_interpolate.py +30 -12
  154. scipy/interpolate/_ndbspline.py +13 -18
  155. scipy/interpolate/_ndgriddata.py +5 -8
  156. scipy/interpolate/_polyint.py +95 -31
  157. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  158. scipy/interpolate/_rbf.py +2 -2
  159. scipy/interpolate/_rbfinterp.py +1 -1
  160. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  161. scipy/interpolate/_rgi.py +31 -26
  162. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  163. scipy/interpolate/dfitpack.py +0 -20
  164. scipy/interpolate/interpnd.py +1 -2
  165. scipy/interpolate/tests/test_bary_rational.py +2 -2
  166. scipy/interpolate/tests/test_bsplines.py +97 -1
  167. scipy/interpolate/tests/test_fitpack2.py +39 -1
  168. scipy/interpolate/tests/test_interpnd.py +32 -20
  169. scipy/interpolate/tests/test_interpolate.py +48 -4
  170. scipy/interpolate/tests/test_rgi.py +2 -1
  171. scipy/io/_fast_matrix_market/__init__.py +2 -0
  172. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  173. scipy/io/_harwell_boeing/hb.py +7 -11
  174. scipy/io/_idl.py +5 -7
  175. scipy/io/_netcdf.py +15 -5
  176. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  177. scipy/io/arff/tests/test_arffread.py +3 -3
  178. scipy/io/matlab/__init__.py +5 -3
  179. scipy/io/matlab/_mio.py +4 -1
  180. scipy/io/matlab/_mio5.py +19 -13
  181. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  182. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  183. scipy/io/matlab/_miobase.py +4 -1
  184. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  185. scipy/io/matlab/tests/test_mio.py +46 -18
  186. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  187. scipy/io/tests/test_mmio.py +7 -1
  188. scipy/io/tests/test_wavfile.py +41 -0
  189. scipy/io/wavfile.py +57 -10
  190. scipy/linalg/_basic.py +113 -86
  191. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  192. scipy/linalg/_decomp.py +22 -9
  193. scipy/linalg/_decomp_cholesky.py +28 -13
  194. scipy/linalg/_decomp_cossin.py +45 -30
  195. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  196. scipy/linalg/_decomp_ldl.py +4 -1
  197. scipy/linalg/_decomp_lu.py +18 -6
  198. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  199. scipy/linalg/_decomp_polar.py +2 -0
  200. scipy/linalg/_decomp_qr.py +6 -2
  201. scipy/linalg/_decomp_qz.py +3 -0
  202. scipy/linalg/_decomp_schur.py +3 -1
  203. scipy/linalg/_decomp_svd.py +13 -2
  204. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_expm_frechet.py +4 -0
  206. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  208. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  209. scipy/linalg/_matfuncs.py +187 -4
  210. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  212. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  213. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  214. scipy/linalg/_procrustes.py +2 -0
  215. scipy/linalg/_sketches.py +17 -6
  216. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  217. scipy/linalg/_solvers.py +7 -2
  218. scipy/linalg/_special_matrices.py +26 -36
  219. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  220. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  221. scipy/linalg/lapack.py +22 -2
  222. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  223. scipy/linalg/tests/test_basic.py +31 -16
  224. scipy/linalg/tests/test_batch.py +588 -0
  225. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  226. scipy/linalg/tests/test_decomp.py +40 -3
  227. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  228. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  229. scipy/linalg/tests/test_lapack.py +115 -7
  230. scipy/linalg/tests/test_matfuncs.py +157 -102
  231. scipy/linalg/tests/test_procrustes.py +0 -7
  232. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  233. scipy/linalg/tests/test_special_matrices.py +1 -5
  234. scipy/ndimage/__init__.py +1 -0
  235. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  236. scipy/ndimage/_delegators.py +8 -2
  237. scipy/ndimage/_filters.py +453 -5
  238. scipy/ndimage/_interpolation.py +36 -6
  239. scipy/ndimage/_measurements.py +4 -2
  240. scipy/ndimage/_morphology.py +5 -0
  241. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  242. scipy/ndimage/_ni_docstrings.py +5 -1
  243. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  244. scipy/ndimage/_ni_support.py +1 -5
  245. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  246. scipy/ndimage/_support_alternative_backends.py +18 -6
  247. scipy/ndimage/tests/test_filters.py +370 -259
  248. scipy/ndimage/tests/test_fourier.py +7 -9
  249. scipy/ndimage/tests/test_interpolation.py +68 -61
  250. scipy/ndimage/tests/test_measurements.py +18 -35
  251. scipy/ndimage/tests/test_morphology.py +143 -131
  252. scipy/ndimage/tests/test_splines.py +1 -3
  253. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  254. scipy/optimize/_basinhopping.py +13 -7
  255. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  256. scipy/optimize/_bracket.py +17 -24
  257. scipy/optimize/_chandrupatla.py +9 -10
  258. scipy/optimize/_cobyla_py.py +104 -123
  259. scipy/optimize/_constraints.py +14 -10
  260. scipy/optimize/_differentiable_functions.py +371 -230
  261. scipy/optimize/_differentialevolution.py +4 -3
  262. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  263. scipy/optimize/_dual_annealing.py +1 -1
  264. scipy/optimize/_elementwise.py +1 -4
  265. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  266. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  267. scipy/optimize/_lbfgsb_py.py +57 -16
  268. scipy/optimize/_linprog_doc.py +2 -2
  269. scipy/optimize/_linprog_highs.py +2 -2
  270. scipy/optimize/_linprog_ip.py +25 -10
  271. scipy/optimize/_linprog_util.py +14 -16
  272. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  273. scipy/optimize/_lsq/common.py +3 -3
  274. scipy/optimize/_lsq/dogbox.py +16 -2
  275. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  276. scipy/optimize/_lsq/least_squares.py +198 -126
  277. scipy/optimize/_lsq/lsq_linear.py +6 -6
  278. scipy/optimize/_lsq/trf.py +35 -8
  279. scipy/optimize/_milp.py +3 -1
  280. scipy/optimize/_minimize.py +105 -36
  281. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  282. scipy/optimize/_minpack_py.py +21 -14
  283. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  284. scipy/optimize/_nnls.py +20 -21
  285. scipy/optimize/_nonlin.py +34 -3
  286. scipy/optimize/_numdiff.py +288 -110
  287. scipy/optimize/_optimize.py +86 -48
  288. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  289. scipy/optimize/_remove_redundancy.py +5 -5
  290. scipy/optimize/_root_scalar.py +1 -1
  291. scipy/optimize/_shgo.py +6 -0
  292. scipy/optimize/_shgo_lib/_complex.py +1 -1
  293. scipy/optimize/_slsqp_py.py +216 -124
  294. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  295. scipy/optimize/_spectral.py +1 -1
  296. scipy/optimize/_tnc.py +8 -1
  297. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  298. scipy/optimize/_trustregion.py +20 -6
  299. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  300. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  301. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  302. scipy/optimize/_trustregion_constr/projections.py +12 -8
  303. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  304. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  305. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  306. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  307. scipy/optimize/_trustregion_exact.py +0 -1
  308. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  309. scipy/optimize/_zeros_py.py +97 -17
  310. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  311. scipy/optimize/slsqp.py +0 -1
  312. scipy/optimize/tests/test__basinhopping.py +1 -1
  313. scipy/optimize/tests/test__differential_evolution.py +4 -4
  314. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  315. scipy/optimize/tests/test__numdiff.py +66 -22
  316. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  317. scipy/optimize/tests/test__shgo.py +9 -1
  318. scipy/optimize/tests/test_bracket.py +36 -46
  319. scipy/optimize/tests/test_chandrupatla.py +133 -135
  320. scipy/optimize/tests/test_cobyla.py +74 -45
  321. scipy/optimize/tests/test_constraints.py +1 -1
  322. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  323. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  324. scipy/optimize/tests/test_least_squares.py +125 -13
  325. scipy/optimize/tests/test_linear_assignment.py +3 -3
  326. scipy/optimize/tests/test_linprog.py +3 -3
  327. scipy/optimize/tests/test_lsq_linear.py +6 -6
  328. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  329. scipy/optimize/tests/test_minpack.py +4 -4
  330. scipy/optimize/tests/test_nnls.py +43 -3
  331. scipy/optimize/tests/test_nonlin.py +36 -0
  332. scipy/optimize/tests/test_optimize.py +95 -17
  333. scipy/optimize/tests/test_slsqp.py +36 -4
  334. scipy/optimize/tests/test_zeros.py +34 -1
  335. scipy/signal/__init__.py +12 -23
  336. scipy/signal/_delegators.py +568 -0
  337. scipy/signal/_filter_design.py +459 -241
  338. scipy/signal/_fir_filter_design.py +262 -90
  339. scipy/signal/_lti_conversion.py +3 -2
  340. scipy/signal/_ltisys.py +118 -91
  341. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  342. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  343. scipy/signal/_polyutils.py +172 -0
  344. scipy/signal/_short_time_fft.py +519 -70
  345. scipy/signal/_signal_api.py +30 -0
  346. scipy/signal/_signaltools.py +719 -399
  347. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  348. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  349. scipy/signal/_spectral_py.py +230 -50
  350. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  351. scipy/signal/_spline_filters.py +108 -68
  352. scipy/signal/_support_alternative_backends.py +73 -0
  353. scipy/signal/_upfirdn.py +4 -1
  354. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  355. scipy/signal/_waveforms.py +2 -11
  356. scipy/signal/_wavelets.py +1 -1
  357. scipy/signal/fir_filter_design.py +1 -0
  358. scipy/signal/spline.py +4 -11
  359. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  360. scipy/signal/tests/test_bsplines.py +114 -79
  361. scipy/signal/tests/test_cont2discrete.py +9 -2
  362. scipy/signal/tests/test_filter_design.py +721 -481
  363. scipy/signal/tests/test_fir_filter_design.py +332 -140
  364. scipy/signal/tests/test_savitzky_golay.py +4 -3
  365. scipy/signal/tests/test_short_time_fft.py +221 -3
  366. scipy/signal/tests/test_signaltools.py +2144 -1348
  367. scipy/signal/tests/test_spectral.py +50 -6
  368. scipy/signal/tests/test_splines.py +161 -96
  369. scipy/signal/tests/test_upfirdn.py +84 -50
  370. scipy/signal/tests/test_waveforms.py +20 -0
  371. scipy/signal/tests/test_windows.py +607 -466
  372. scipy/signal/windows/_windows.py +287 -148
  373. scipy/sparse/__init__.py +23 -4
  374. scipy/sparse/_base.py +270 -108
  375. scipy/sparse/_bsr.py +7 -4
  376. scipy/sparse/_compressed.py +59 -231
  377. scipy/sparse/_construct.py +90 -38
  378. scipy/sparse/_coo.py +115 -181
  379. scipy/sparse/_csc.py +4 -4
  380. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  381. scipy/sparse/_csr.py +2 -2
  382. scipy/sparse/_data.py +48 -48
  383. scipy/sparse/_dia.py +105 -18
  384. scipy/sparse/_dok.py +0 -23
  385. scipy/sparse/_index.py +4 -4
  386. scipy/sparse/_matrix.py +23 -0
  387. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  388. scipy/sparse/_sputils.py +37 -22
  389. scipy/sparse/base.py +0 -9
  390. scipy/sparse/bsr.py +0 -14
  391. scipy/sparse/compressed.py +0 -23
  392. scipy/sparse/construct.py +0 -6
  393. scipy/sparse/coo.py +0 -14
  394. scipy/sparse/csc.py +0 -3
  395. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  396. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  397. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  398. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  399. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  400. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  401. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  402. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  403. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  404. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  405. scipy/sparse/csr.py +0 -5
  406. scipy/sparse/data.py +1 -6
  407. scipy/sparse/dia.py +0 -7
  408. scipy/sparse/dok.py +0 -10
  409. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  410. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  411. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  412. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  413. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  414. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  415. scipy/sparse/linalg/_interface.py +17 -18
  416. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  417. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  418. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  419. scipy/sparse/linalg/_isolve/minres.py +5 -5
  420. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  421. scipy/sparse/linalg/_isolve/utils.py +2 -8
  422. scipy/sparse/linalg/_matfuncs.py +1 -1
  423. scipy/sparse/linalg/_norm.py +1 -1
  424. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  427. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  428. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  429. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  430. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  431. scipy/sparse/tests/test_base.py +214 -42
  432. scipy/sparse/tests/test_common1d.py +7 -7
  433. scipy/sparse/tests/test_construct.py +1 -1
  434. scipy/sparse/tests/test_coo.py +272 -4
  435. scipy/sparse/tests/test_sparsetools.py +5 -0
  436. scipy/sparse/tests/test_sputils.py +36 -7
  437. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  438. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  439. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  440. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  441. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  442. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  443. scipy/spatial/distance.py +49 -42
  444. scipy/spatial/tests/test_distance.py +15 -1
  445. scipy/spatial/tests/test_kdtree.py +1 -0
  446. scipy/spatial/tests/test_qhull.py +7 -2
  447. scipy/spatial/transform/__init__.py +5 -3
  448. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  449. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  450. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  451. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  452. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  453. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  454. scipy/special/__init__.py +1 -47
  455. scipy/special/_add_newdocs.py +34 -772
  456. scipy/special/_basic.py +22 -25
  457. scipy/special/_comb.cpython-312-darwin.so +0 -0
  458. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  459. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  460. scipy/special/_logsumexp.py +67 -58
  461. scipy/special/_orthogonal.pyi +1 -1
  462. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  463. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  464. scipy/special/_spherical_bessel.py +4 -4
  465. scipy/special/_support_alternative_backends.py +212 -119
  466. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  467. scipy/special/_testutils.py +4 -4
  468. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  469. scipy/special/_ufuncs.pyi +1 -0
  470. scipy/special/_ufuncs.pyx +215 -1400
  471. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  472. scipy/special/_ufuncs_cxx.pxd +2 -15
  473. scipy/special/_ufuncs_cxx.pyx +5 -44
  474. scipy/special/_ufuncs_cxx_defs.h +2 -16
  475. scipy/special/_ufuncs_defs.h +0 -8
  476. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  477. scipy/special/cython_special.pxd +1 -1
  478. scipy/special/tests/_cython_examples/meson.build +10 -1
  479. scipy/special/tests/test_basic.py +153 -20
  480. scipy/special/tests/test_boost_ufuncs.py +3 -0
  481. scipy/special/tests/test_cdflib.py +35 -11
  482. scipy/special/tests/test_gammainc.py +16 -0
  483. scipy/special/tests/test_hyp2f1.py +2 -2
  484. scipy/special/tests/test_log1mexp.py +85 -0
  485. scipy/special/tests/test_logsumexp.py +206 -64
  486. scipy/special/tests/test_mpmath.py +1 -0
  487. scipy/special/tests/test_nan_inputs.py +1 -1
  488. scipy/special/tests/test_orthogonal.py +17 -18
  489. scipy/special/tests/test_sf_error.py +3 -2
  490. scipy/special/tests/test_sph_harm.py +6 -7
  491. scipy/special/tests/test_support_alternative_backends.py +211 -76
  492. scipy/stats/__init__.py +4 -1
  493. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  494. scipy/stats/_axis_nan_policy.py +5 -12
  495. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  496. scipy/stats/_continued_fraction.py +387 -0
  497. scipy/stats/_continuous_distns.py +277 -310
  498. scipy/stats/_correlation.py +1 -1
  499. scipy/stats/_covariance.py +6 -3
  500. scipy/stats/_discrete_distns.py +39 -32
  501. scipy/stats/_distn_infrastructure.py +39 -12
  502. scipy/stats/_distribution_infrastructure.py +900 -238
  503. scipy/stats/_entropy.py +9 -10
  504. scipy/{_lib → stats}/_finite_differences.py +1 -1
  505. scipy/stats/_hypotests.py +83 -50
  506. scipy/stats/_kde.py +53 -49
  507. scipy/stats/_ksstats.py +1 -1
  508. scipy/stats/_levy_stable/__init__.py +7 -15
  509. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  510. scipy/stats/_morestats.py +118 -73
  511. scipy/stats/_mstats_basic.py +13 -17
  512. scipy/stats/_mstats_extras.py +8 -8
  513. scipy/stats/_multivariate.py +89 -113
  514. scipy/stats/_new_distributions.py +97 -20
  515. scipy/stats/_page_trend_test.py +12 -5
  516. scipy/stats/_probability_distribution.py +265 -43
  517. scipy/stats/_qmc.py +14 -9
  518. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  519. scipy/stats/_qmvnt.py +16 -95
  520. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  521. scipy/stats/_quantile.py +335 -0
  522. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  523. scipy/stats/_resampling.py +4 -29
  524. scipy/stats/_sampling.py +1 -1
  525. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  526. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  527. scipy/stats/_stats_mstats_common.py +21 -2
  528. scipy/stats/_stats_py.py +550 -476
  529. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  530. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  531. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  532. scipy/stats/_variation.py +6 -8
  533. scipy/stats/_wilcoxon.py +13 -7
  534. scipy/stats/tests/common_tests.py +6 -4
  535. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  536. scipy/stats/tests/test_continued_fraction.py +173 -0
  537. scipy/stats/tests/test_continuous.py +379 -60
  538. scipy/stats/tests/test_continuous_basic.py +18 -12
  539. scipy/stats/tests/test_discrete_basic.py +14 -8
  540. scipy/stats/tests/test_discrete_distns.py +16 -16
  541. scipy/stats/tests/test_distributions.py +95 -75
  542. scipy/stats/tests/test_entropy.py +40 -48
  543. scipy/stats/tests/test_fit.py +4 -3
  544. scipy/stats/tests/test_hypotests.py +153 -24
  545. scipy/stats/tests/test_kdeoth.py +109 -41
  546. scipy/stats/tests/test_marray.py +289 -0
  547. scipy/stats/tests/test_morestats.py +79 -47
  548. scipy/stats/tests/test_mstats_basic.py +3 -3
  549. scipy/stats/tests/test_multivariate.py +434 -83
  550. scipy/stats/tests/test_qmc.py +13 -10
  551. scipy/stats/tests/test_quantile.py +199 -0
  552. scipy/stats/tests/test_rank.py +119 -112
  553. scipy/stats/tests/test_resampling.py +47 -56
  554. scipy/stats/tests/test_sampling.py +9 -4
  555. scipy/stats/tests/test_stats.py +799 -939
  556. scipy/stats/tests/test_variation.py +8 -6
  557. scipy/version.py +2 -2
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  559. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  560. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +561 -568
  561. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  562. scipy/_lib/array_api_extra/_funcs.py +0 -484
  563. scipy/_lib/array_api_extra/_typing.py +0 -8
  564. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  565. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  566. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  567. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  568. scipy/spatial/qhull_src/COPYING.txt +0 -38
  569. scipy/special/libsf_error_state.dylib +0 -0
  570. scipy/special/tests/test_log_softmax.py +0 -109
  571. scipy/special/tests/test_xsf_cuda.py +0 -114
  572. scipy/special/xsf/binom.h +0 -89
  573. scipy/special/xsf/cdflib.h +0 -100
  574. scipy/special/xsf/cephes/airy.h +0 -307
  575. scipy/special/xsf/cephes/besselpoly.h +0 -51
  576. scipy/special/xsf/cephes/beta.h +0 -257
  577. scipy/special/xsf/cephes/cbrt.h +0 -131
  578. scipy/special/xsf/cephes/chbevl.h +0 -85
  579. scipy/special/xsf/cephes/chdtr.h +0 -193
  580. scipy/special/xsf/cephes/const.h +0 -87
  581. scipy/special/xsf/cephes/ellie.h +0 -293
  582. scipy/special/xsf/cephes/ellik.h +0 -251
  583. scipy/special/xsf/cephes/ellpe.h +0 -107
  584. scipy/special/xsf/cephes/ellpk.h +0 -117
  585. scipy/special/xsf/cephes/expn.h +0 -260
  586. scipy/special/xsf/cephes/gamma.h +0 -398
  587. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  588. scipy/special/xsf/cephes/hyperg.h +0 -361
  589. scipy/special/xsf/cephes/i0.h +0 -149
  590. scipy/special/xsf/cephes/i1.h +0 -158
  591. scipy/special/xsf/cephes/igam.h +0 -421
  592. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  593. scipy/special/xsf/cephes/igami.h +0 -313
  594. scipy/special/xsf/cephes/j0.h +0 -225
  595. scipy/special/xsf/cephes/j1.h +0 -198
  596. scipy/special/xsf/cephes/jv.h +0 -715
  597. scipy/special/xsf/cephes/k0.h +0 -164
  598. scipy/special/xsf/cephes/k1.h +0 -163
  599. scipy/special/xsf/cephes/kn.h +0 -243
  600. scipy/special/xsf/cephes/lanczos.h +0 -112
  601. scipy/special/xsf/cephes/ndtr.h +0 -275
  602. scipy/special/xsf/cephes/poch.h +0 -85
  603. scipy/special/xsf/cephes/polevl.h +0 -167
  604. scipy/special/xsf/cephes/psi.h +0 -194
  605. scipy/special/xsf/cephes/rgamma.h +0 -111
  606. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  607. scipy/special/xsf/cephes/shichi.h +0 -248
  608. scipy/special/xsf/cephes/sici.h +0 -224
  609. scipy/special/xsf/cephes/sindg.h +0 -221
  610. scipy/special/xsf/cephes/tandg.h +0 -139
  611. scipy/special/xsf/cephes/trig.h +0 -58
  612. scipy/special/xsf/cephes/unity.h +0 -186
  613. scipy/special/xsf/cephes/zeta.h +0 -172
  614. scipy/special/xsf/config.h +0 -304
  615. scipy/special/xsf/digamma.h +0 -205
  616. scipy/special/xsf/error.h +0 -57
  617. scipy/special/xsf/evalpoly.h +0 -47
  618. scipy/special/xsf/expint.h +0 -266
  619. scipy/special/xsf/hyp2f1.h +0 -694
  620. scipy/special/xsf/iv_ratio.h +0 -173
  621. scipy/special/xsf/lambertw.h +0 -150
  622. scipy/special/xsf/loggamma.h +0 -163
  623. scipy/special/xsf/sici.h +0 -200
  624. scipy/special/xsf/tools.h +0 -427
  625. scipy/special/xsf/trig.h +0 -164
  626. scipy/special/xsf/wright_bessel.h +0 -843
  627. scipy/special/xsf/zlog1.h +0 -35
  628. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  629. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -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