Repository: numpy/numpy
File: numpy/lib/_function_base_impl.py (Python)

Code before:
    # Use dtype of array if possible (e.g., if q is a python int or float).
    if isinstance(q, (int, float)) and a.dtype.kind == "f":
        q = np.asanyarray(q, dtype=a.dtype)
    else:
        q = np.asanyarray(q)

    if not _quantile_is_valid(q):
        raise ValueError("Quantiles must be in the range [0, 1]")

    if weights is not None:
        if method != "inverted_cdf":
            msg = ("Only method 'inverted_cdf' supports weights. "
                   f"Got: {method}.")
            raise ValueError(msg)
        if axis is not None:
            axis = _nx.normalize_axis_tuple(axis, a.ndim, argname="axis")
        weights = _weights_are_valid(weights=weights, a=a, axis=axis)
        if weights.dtype != object:
            if np.any(np.isinf(weights)):
                raise ValueError("Weights must be finite.")
            elif np.any(np.isnan(weights)):
                raise ValueError("At least one weight is nan.")
        # Since np.isinf and np.isnan do not work in dtype object arrays
        # Also, dtpye object arrays with np.nan in them break <, > and == opperators
        # This specific handling had to be done (Can be improved)   
        elif weights.dtype == object:
            for w in weights: 
                if np.isnan(w):
                    raise ValueError("At least one weight is nan.")
                if np.isinf(w):
                    raise ValueError("Weights must be finite.")
                
        if np.any(weights < 0):
            raise ValueError("Weights must be non-negative.")
        elif np.all(weights == 0):
            raise ValueError("At least one weight must be non-zero.")
        

    return _quantile_unchecked(
        a, q, axis, out, overwrite_input, method, keepdims, weights)


def _quantile_unchecked(a,
                        q,
                        axis=None,
                        out=None,
                        overwrite_input=False,
                        method="linear",
                        keepdims=False,
                        weights=None):
    """Assumes that q is in [0, 1], and is an ndarray"""

Review comment (bug):
Note that this loop can still give unexpected errors, because you are here counting on object arrays to be turned into their values as scalars. E.g.,
```
np.isnan(np.array([1.,None,np.inf])[1])
# TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
```
This will be an uninformative error!

I think we have two choices: just not check for `object` dtype, or convert to float before checking (and then passing on it that conversion fails).


Code after:
def _compute_virtual_index(n, quantiles, alpha: float, beta: float):
    """
    Compute the floating point indexes of an array for the linear
    interpolation of quantiles.
    n : array_like
        The sample sizes.
    quantiles : array_like
        The quantiles values.
    alpha : float
        A constant used to correct the index computed.
    beta : float
        A constant used to correct the index computed.

    alpha and beta values depend on the chosen method
    (see quantile documentation)

    Reference:
    Hyndman&Fan paper "Sample Quantiles in Statistical Packages",
    DOI: 10.1080/00031305.1996.10473566
    """
    return n * quantiles + (
            alpha + quantiles * (1 - alpha - beta)
    ) - 1


def _get_gamma(virtual_indexes, previous_indexes, method, dtype):
    """
    Compute gamma (a.k.a 'm' or 'weight') for the linear interpolation
    of quantiles.

    virtual_indexes : array_like
        The indexes where the percentile is supposed to be found in the sorted
        sample.
    previous_indexes : array_like
        The floor values of virtual_indexes.
    method : dict
        The interpolation method chosen, which may have a specific rule
        modifying gamma.

    gamma is usually the fractional part of virtual_indexes but can be modified
    by the interpolation method.
    """
    gamma = np.asanyarray(virtual_indexes - previous_indexes)
    gamma = method["fix_gamma"](gamma, virtual_indexes)
    # Ensure both that we have an array, and that we keep the dtype
    # (which may have been matched to the input array).
    return np.asanyarray(gamma, dtype=dtype)


def _lerp(a, b, t, out=None):
    """