Repository: scipy/scipy

Issue:
BUG: 1.10.0rc2 Windows wheel tests runs all segfault
The wheel build jobs are here: https://github.com/scipy/scipy/actions/runs/3753070381

The non-informative failures were originally discussed here, and Ralf and I kind of went for trying to build the wheels anyway, because it wasn't clear there was a genuine SciPy issue: https://github.com/scipy/scipy/pull/17640#issuecomment-1362081751

We have just slightly more information from the `cibuildwheel` testing now, but not too much more--we now know it is a segfault:

```
 D:\a\scipy\scipy/tools/wheels/cibw_test_command.sh: line 11:  1391 Segmentation fault      python -c "import sys; import scipy; sys.exit(not scipy.test())"
```

For now, I'm tentatively labeling this is an upstream bug since it started with NumPy `1.24.0`.

Two solutions I can think of:
- try to identify the problematic test and skip it with NumPy >= 1.24.0 pending further investigation, on Windows only
- (easier, I think?): pin the runtime testing for Windows wheel builds on GitHub actions to NumPy < 1.24.0 temporarily


Discussion:
Do you know if there's an incantation of the test call that would give more verbose output?
Yeah, there is, I tried it on my fork here: https://github.com/tylerjereddy/scipy/pull/64

We get a bit more info, pasted below, perhaps a collection stage error/issue of some sort. There's a way to login to GitHub actions runners with a specific addon/action thingy, I've done that before.. could try that perhaps.

```
Run mkdir tmp

    Directory: D:\a\scipy\scipy

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          12/22/[20](https://github.com/tylerjereddy/scipy/actions/runs/3754374273/jobs/6378537293#step:14:21)22  2:41 AM                tmp
============================= test session starts =============================
platform win32 -- Python 3.9.13, pytest-7.2.0, pluggy-1.0.0 -- C:\hostedtoolcache\windows\Python\3.9.13\x64\python.exe
cachedir: .pytest_cache
rootdir: D:\a\scipy\scipy, configfile: pytest.ini
plugins: timeout-2.1.0, xdist-3.1.0
collecting ... 
Error: Process completed with exit code 1.
```
Ah, maybe it doesn't work with the Windows runners though: https://github.com/marketplace/actions/debugging-with-ssh
Not clear to me why the collection process would result in an error. The last pytest release was in late October. 5
Test collection imports all test files, so we get some running code and imports of all scipy submodules. Perhaps there's an invalid instruction or some such thing. Error code 139 in Windows seems to be nontrivial to diagnose, but some sort of memory corruption. There is already a long list of fixes merged for numpy 1.24.1, including for things like comparison operators - which we will be using during test collection.
I'll check `cibuildwheel --platform windows` or whatever on my old windows box tonight if I can

Resolving patch:
diff --git a/scipy/stats/_stats_py.py b/scipy/stats/_stats_py.py
--- a/scipy/stats/_stats_py.py
+++ b/scipy/stats/_stats_py.py
@@ -9441,9 +9441,7 @@ def rankdata(a, method='average', *, axis=None, nan_policy='propagate'):
             nans because ranks relative to nans in the input are undefined.
             When `nan_policy` is 'omit', nans in `a` are ignored when ranking
             the other values, and the corresponding locations of the output
-            are nan. This behavior is the default because it is intuitive and
-            compatible with the behavior before the `nan_policy` parameter
-            was introduced.
+            are nan.
 
         .. versionadded:: 1.10
 
@@ -9499,15 +9497,15 @@ def rankdata(a, method='average', *, axis=None, nan_policy='propagate'):
         return np.apply_along_axis(rankdata, axis, a, method,
                                    nan_policy=nan_policy)
 
-    contains_nan, nan_policy = _contains_nan(a, nan_policy)
+    arr = np.ravel(a)
+    contains_nan, nan_policy = _contains_nan(arr, nan_policy)
     nan_indexes = None
     if contains_nan:
         if nan_policy == 'omit':
-            nan_indexes = np.isnan(a)
+            nan_indexes = np.isnan(arr)
         if nan_policy == 'propagate':
-            return np.full_like(a, np.nan)
+            return np.full_like(arr, np.nan)
 
-    arr = np.ravel(a)
     algo = 'mergesort' if method == 'ordinal' else 'quicksort'
     sorter = np.argsort(arr, kind=algo)
 


Test patch:
diff --git a/scipy/stats/tests/test_rank.py b/scipy/stats/tests/test_rank.py
--- a/scipy/stats/tests/test_rank.py
+++ b/scipy/stats/tests/test_rank.py
@@ -224,6 +224,17 @@ def rank_omit(a, method, axis):
 
         assert_array_equal(res, res0)
 
+    def test_nan_policy_2d_axis_none(self):
+        # 2 2d-array test with axis=None
+        data = [[0, np.nan, 3],
+                [4, 2, np.nan],
+                [1, 2, 2]]
+        assert_array_equal(rankdata(data, axis=None, nan_policy='omit'),
+                           [1., np.nan, 6., 7., 4., np.nan, 2., 4., 4.])
+        assert_array_equal(rankdata(data, axis=None, nan_policy='propagate'),
+                           [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan,
+                            np.nan, np.nan, np.nan])
+
     def test_nan_policy_raise(self):
         # 1 1d-array test
         data = [0, 2, 3, -2, np.nan, np.nan]