⚠️ CI failed on Linux_Nightly.pylatest_pip_scipy_dev (last failure: Dec 05, 2024) ⚠️

**CI is still failing on [Linux_Nightly.pylatest_pip_scipy_dev](https://dev.azure.com/scikit-learn/scikit-learn/_build/results?buildId=72598&view=logs&j=dfe99b15-50db-5d7b-b1e9-4105c42527cf)** (Dec 05, 2024)
- test_partial_dependence_binary_model_grid_resolution[features0-10-10]

COMMENT:
The latest in `test_csr_polynomial_expansion_index_overflow` one seems like a scipy change in `main`, here is an excerpt from the wheel build log (the assertion rewriting works and we have more info because we are not using meson editable install). 

```
 E       AssertionError: assert dtype('int64') == <class 'numpy.int32'>
 E        +  where dtype('int64') = array([65534]).dtype
 E        +    where array([65534]) = <Compressed Sparse Row sparse array of dtype 'float64'\n	with 1 stored elements and shape (1, 2147450880)>.indices
```

```
  __ test_csr_polynomial_expansion_index_overflow[csr_array-False-True-2-65535] __
  
  degree = 2, n_features = 65535, interaction_only = True, include_bias = False
  csr_container = <class 'scipy.sparse._csr.csr_array'>
  
      @pytest.mark.parametrize(
          "degree, n_features",
          [
              # Needs promotion to int64 when interaction_only=False
              (2, 65535),
              (3, 2344),
              # This guarantees that the intermediate operation when calculating
              # output columns would overflow a C-long, hence checks that python-
              # longs are being used.
              (2, int(np.sqrt(np.iinfo(np.int64).max) + 1)),
              (3, 65535),
              # This case tests the second clause of the overflow check which
              # takes into account the value of `n_features` itself.
              (2, int(np.sqrt(np.iinfo(np.int64).max))),
          ],
      )
      @pytest.mark.parametrize("interaction_only", [True, False])
      @pytest.mark.parametrize("include_bias", [True, False])
      @pytest.mark.parametrize("csr_container", CSR_CONTAINERS)
      def test_csr_polynomial_expansion_index_overflow(
          degree, n_features, interaction_only, include_bias, csr_container
      ):
          """Tests known edge-cases to the dtype promotion strategy and custom
          Cython code, including a current bug in the upstream
          `scipy.sparse.hstack`.
          """
          data = [1.0]
          row = [0]
          col = [n_features - 1]
      
          # First degree index
          expected_indices = [
              n_features - 1 + int(include_bias),
          ]
          # Second degree index
          expected_indices.append(n_features * (n_features + 1) // 2 + expected_indices[0])
          # Third degree index
          expected_indices.append(
              n_features * (n_features + 1) * (n_features + 2) // 6 + expected_indices[1]
          )
      
          X = csr_container((data, (row, col)))
          pf = PolynomialFeatures(
              interaction_only=interaction_only, include_bias=include_bias, degree=degree
          )
      
          # Calculate the number of combinations a-priori, and if needed check for
          # the correct ValueError and terminate the test early.
          num_combinations = pf._num_combinations(
              n_features=n_features,
              min_degree=0,
              max_degree=degree,
              interaction_only=pf.interaction_only,
              include_bias=pf.include_bias,
          )
          if num_combinations > np.iinfo(np.intp).max:
              msg = (
                  r"The output that would result from the current configuration would have"
                  r" \d* features which is too large to be indexed"
              )
              with pytest.raises(ValueError, match=msg):
                  pf.fit(X)
              return
      
          # In SciPy < 1.8, a bug occurs when an intermediate matrix in
          # `to_stack` in `hstack` fits within int32 however would require int64 when
          # combined with all previous matrices in `to_stack`.
          if sp_version < parse_version("1.8.0"):
              has_bug = False
              max_int32 = np.iinfo(np.int32).max
              cumulative_size = n_features + include_bias
              for deg in range(2, degree + 1):
                  max_indptr = _calc_total_nnz(X.indptr, interaction_only, deg)
                  max_indices = _calc_expanded_nnz(n_features, interaction_only, deg) - 1
                  cumulative_size += max_indices + 1
                  needs_int64 = max(max_indices, max_indptr) > max_int32
                  has_bug |= not needs_int64 and cumulative_size > max_int32
              if has_bug:
                  msg = r"In scipy versions `<1.8.0`, the function `scipy.sparse.hstack`"
                  with pytest.raises(ValueError, match=msg):
                      X_trans = pf.fit_transform(X)
                  return
      
          # When `n_features>=65535`, `scipy.sparse.hstack` may not use the right
          # dtype for representing indices and indptr if `n_features` is still
          # small enough so that each block matrix's indices and indptr arrays
          # can be represented with `np.int32`. We test `n_features==65535`
          # since it is guaranteed to run into this bug.
          if (
              sp_version < parse_version("1.9.2")
              and n_features == 65535
              and degree == 2
              and not interaction_only
          ):  # pragma: no cover
              msg = r"In scipy versions `<1.9.2`, the function `scipy.sparse.hstack`"
              with pytest.raises(ValueError, match=msg):
                  X_trans = pf.fit_transform(X)
              return
          X_trans = pf.fit_transform(X)
      
          expected_dtype = np.int64 if num_combinations > np.iinfo(np.int32).max else np.int32
          # Terms higher than first degree
          non_bias_terms = 1 + (degree - 1) * int(not interaction_only)
          expected_nnz = int(include_bias) + non_bias_terms
          assert X_trans.dtype == X.dtype
          assert X_trans.shape == (1, pf.n_output_features_)
  >       assert X_trans.indptr.dtype == X_trans.indices.dtype == expected_dtype
  E       AssertionError: assert dtype('int64') == <class 'numpy.int32'>
  E        +  where dtype('int64') = array([65534]).dtype
  E        +    where array([65534]) = <Compressed Sparse Row sparse array of dtype 'float64'\n	with 1 stored elements and shape (1, 2147450880)>.indices
  
  ../venv/lib/python3.13t/site-packages/sklearn/preprocessing/tests/test_polynomial.py:1132: AssertionError
```

Labels: Bug