Skip to content

Enabling array API dispatch causes some estimators without array API support to reject valid NumPy inputs #32837

@ogrisel

Description

@ogrisel

Describe the bug

This might be related to #32836 (or not).

I think we need a common test to check that enabling array API support does not affect estimators (without array API support) when called on regular NumPy (or other valid non-array inputs).

This bug might be a regression.

Steps/Code to Reproduce

# %%
import os

os.environ["SCIPY_ARRAY_API"] = "1"


# %%
import sklearn
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.datasets import load_iris

X_iris, y_iris = load_iris(return_X_y=True)

with sklearn.config_context(array_api_dispatch=True):
    KBinsDiscretizer(
        n_bins=3,
        encode="onehot-dense",
        strategy="uniform",
        quantile_method="averaged_inverted_cdf",
    ).fit_transform(X_iris)

Expected Results

No error.

Actual Results

Traceback (most recent call last):

  Cell In[5], line 14
    ).fit_transform(X_iris)

  File ~/code/scikit-learn/sklearn/utils/_set_output.py:316 in wrapped
    data_to_wrap = f(self, X, *args, **kwargs)

  File ~/code/scikit-learn/sklearn/base.py:907 in fit_transform
    return self.fit(X, **fit_params).transform(X)

  File ~/code/scikit-learn/sklearn/base.py:1336 in wrapper
    return fit_method(estimator, *args, **kwargs)

  File ~/code/scikit-learn/sklearn/preprocessing/_discretization.py:414 in fit
    self._encoder.fit(np.zeros((1, len(self.n_bins_))))

  File ~/code/scikit-learn/sklearn/base.py:1336 in wrapper
    return fit_method(estimator, *args, **kwargs)

  File ~/code/scikit-learn/sklearn/preprocessing/_encoders.py:999 in fit
    self._fit(

  File ~/code/scikit-learn/sklearn/preprocessing/_encoders.py:86 in _fit
    X_list, n_samples, n_features = self._check_X(

  File ~/code/scikit-learn/sklearn/preprocessing/_encoders.py:68 in _check_X
    Xi = _safe_indexing(X, indices=i, axis=1)

  File ~/code/scikit-learn/sklearn/utils/_indexing.py:357 in _safe_indexing
    return _array_indexing(X, indices, indices_dtype, axis=axis)

  File ~/code/scikit-learn/sklearn/utils/_indexing.py:39 in _array_indexing
    key = move_to(key, xp=xp, device=device_)

  File ~/code/scikit-learn/sklearn/utils/_array_api.py:508 in move_to
    xp_array, _, device_array = get_namespace_and_device(array)

  File ~/code/scikit-learn/sklearn/utils/_array_api.py:453 in get_namespace_and_device
    xp, is_array_api = get_namespace(*array_list, **skip_remove_kwargs)

  File ~/code/scikit-learn/sklearn/utils/_array_api.py:404 in get_namespace
    namespace, is_array_api_compliant = array_api_compat.get_namespace(*arrays), True

  File ~/code/scikit-learn/sklearn/externals/array_api_compat/common/_helpers.py:646 in array_namespace
    raise TypeError("Unrecognized array input")

TypeError: Unrecognized array input

Versions

System:
    python: 3.13.7 | packaged by conda-forge | (main, Sep  3 2025, 14:24:46) [Clang 19.1.7 ]
executable: /Users/ogrisel/miniforge3/envs/dev/bin/python
   machine: macOS-15.6.1-arm64-arm-64bit-Mach-O

Python dependencies:
      sklearn: 1.9.dev0
          pip: 25.2
   setuptools: 80.9.0
        numpy: 2.3.3
        scipy: 1.16.3
       Cython: 3.1.4
       pandas: 3.0.0.dev0+2566.g2bb3fef887
   matplotlib: 3.10.6
       joblib: 1.5.2
threadpoolctl: 3.6.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 10
         prefix: libopenblas
       filepath: /Users/ogrisel/miniforge3/envs/dev/lib/libopenblas.0.dylib
        version: 0.3.30
threading_layer: openmp
   architecture: VORTEX

       user_api: openmp
   internal_api: openmp
    num_threads: 10
         prefix: libomp
       filepath: /Users/ogrisel/miniforge3/envs/dev/lib/libomp.dylib
        version: None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions