Repository: scikit-learn/scikit-learn
File: sklearn/utils/_array_api.py (Python)

Code before:
    arrays_device = device(*array_list, **skip_remove_kwargs)

    if xp is None:
        xp, is_array_api = get_namespace(*array_list, **skip_remove_kwargs)
    else:
        xp, is_array_api = xp, True

    if is_array_api:
        return xp, is_array_api, arrays_device
    else:
        return xp, False, arrays_device


def _convert_to_reference(*, reference, arrays):
    """Convert `arrays` to `reference` array's namespace and device."""
    xp_ref, _, device_ref = get_namespace_and_device(reference)
    arrays_converted_list = []
    for array in arrays:
        xp_array, _, device_array = get_namespace_and_device(array)
        if xp_ref == xp_array and device_ref == device_array:
            arrays_converted_list.append(array)
        else:
            try:
                # Note will copy if required
                array_converted = xp_ref.from_dlpack(array, device=device_ref)
            except AttributeError:
                # Convert to numpy
                if _is_numpy_namespace(xp_ref):
                    array_converted = _convert_to_numpy(array)
                # Convert from numpy
                elif _is_numpy_namespace(xp_array):
                    array_converted = xp_ref.asarray(array, device=device_ref)
                else:
                    # Convert to numpy then to reference
                    array_np = _convert_to_numpy(array)
                    array_converted = xp_ref.asarray(array_np, device=device_ref)
            arrays_converted_list.append(array_converted)

    return tuple(arrays_converted_list)


def _expit(X, xp=None):
    xp, _ = get_namespace(X, xp=xp)
    if _is_numpy_namespace(xp):
        return xp.asarray(special.expit(numpy.asarray(X)))

    return 1.0 / (1.0 + xp.exp(-X))


def _validate_diagonal_args(array, value, xp):
    """Validate arguments to `_fill_diagonal`/`_add_to_diagonal`."""

Review comment (bug):
I decided to only `except AttributeError`, which I think occurs if input or output namespace does not support dlpack.

[`from_dlpack`](https://data-apis.org/array-api/latest/API_specification/generated/array_api.from_dlpack.html#from-dlpack) can give 2 (or more) other errors

* BufferError - The __dlpack__ and __dlpack_device__ methods on the input array may raise BufferError when the data cannot be exported as DLPack (e.g., incompatible dtype, strides, or device). It may also raise other errors when export fails for other reasons (e.g., not enough memory available to materialize the data). from_dlpack must propagate such exceptions.
   * I thought that if dlpack fails to convert due to one of the above errors, it would not make sense to try ourselves manually.
* ValueError - If data exchange is possible via an explicit copy but copy is set to False.
   * I've left `copy=None`, allowing it to copy if need be, so this error is not relevant. I am not sure about the `copy=None` setting though, it is a lot of memory usage. 

Code after:

    if is_array_api:
        return xp, is_array_api, arrays_device
    else:
        return xp, False, arrays_device


def move_to(*arrays, xp, device):
    """Move all arrays to `xp` and `device`.

    Each array will be moved to the reference namespace and device if
    it is not already using it. Otherwise the array is left unchanged.

    `array` may contain `None` entries, these are left unchanged.

    Sparse arrays are accepted (as pass through) if the reference namespace is
    Numpy, in which case they are returned unchanged. Otherwise a `TypeError`
    is raised.

    Parameters
    ----------
    *arrays : iterable of arrays
        Arrays to (potentially) move.

    xp : namespace
        Array API namespace to move arrays to.

    device : device
        Array API device to move arrays to.

    Returns
    -------
    arrays : tuple or array
        Tuple of arrays with the same namespace and device as reference. Single array
        returned if only one `arrays` input.
    """
    sparse_mask = [sp.issparse(array) for array in arrays]
    none_mask = [array is None for array in arrays]
    if any(sparse_mask) and not _is_numpy_namespace(xp):
        raise TypeError(
            "Sparse arrays are only accepted (and passed through) when the target "
            "namespace is Numpy"
        )

    converted_arrays = []

    for array, is_sparse, is_none in zip(arrays, sparse_mask, none_mask):
        if is_none:
            converted_arrays.append(None)
        elif is_sparse:
            converted_arrays.append(array)