Repository: numpy/numpy
File: numpy/_core/numeric.py (Python)

Code before:
    # Turn all but python scalars into arrays.
    x, y, atol, rtol = (
        a if isinstance(a, (int, float, complex)) else asanyarray(a)
        for a in (a, b, atol, rtol))

    # Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
    # This will cause casting of x later. Also, make sure to allow subclasses
    # (e.g., for numpy.ma).
    # NOTE: We explicitly allow timedelta, which used to work. This could
    #       possibly be deprecated. See also gh-18286.
    #       timedelta works if `atol` is an integer or also a timedelta.
    #       Although, the default tolerances are unlikely to be useful
    if (dtype := getattr(y, "dtype", None)) is not None and dtype.kind != "m":
        dt = multiarray.result_type(y, 1.)
        y = asanyarray(y, dtype=dt)
    elif isinstance(y, int):
        y = float(y)

    with errstate(invalid='ignore'):

        if np.any(np.isinf(atol)) or np.any(np.isinf(rtol)):
            warnings.warn("At least one of rtol and atol are infinite", stacklevel=2)

        if np.any(np.isnan(atol)) or np.any(np.isnan(rtol)):
            warnings.warn("At least one of rtol and atol are not a number", stacklevel=2)
        
        result = (less_equal(abs(x - y), atol + rtol * abs(y))
                  & isfinite(y)
                  | (x == y))
        if equal_nan:
            result |= isnan(x) & isnan(y)

    return result[()]  # Flatten 0d arrays to scalars


def _array_equal_dispatcher(a1, a2, equal_nan=None):
    return (a1, a2)


_no_nan_types = {
    # should use np.dtype.BoolDType, but as of writing
    # that fails the reloading test.
    type(dtype(nt.bool)),
    type(dtype(nt.int8)),
    type(dtype(nt.int16)),
    type(dtype(nt.int32)),
    type(dtype(nt.int64)),
}


def _dtype_cannot_hold_nan(dtype):

Review comment (suggestion):
If you use f-strings you can pretty easily make these warnings nicer, e.g. actually print out which one was nan or inf.

Code after:
    # Turn all but python scalars into arrays.
    x, y, atol, rtol = (
        a if isinstance(a, (int, float, complex)) else asanyarray(a)
        for a in (a, b, atol, rtol))

    # Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
    # This will cause casting of x later. Also, make sure to allow subclasses
    # (e.g., for numpy.ma).
    # NOTE: We explicitly allow timedelta, which used to work. This could
    #       possibly be deprecated. See also gh-18286.
    #       timedelta works if `atol` is an integer or also a timedelta.
    #       Although, the default tolerances are unlikely to be useful
    if (dtype := getattr(y, "dtype", None)) is not None and dtype.kind != "m":
        dt = multiarray.result_type(y, 1.)
        y = asanyarray(y, dtype=dt)
    elif isinstance(y, int):
        y = float(y)

    # atol and rtol can be arrays
    if not (np.all(np.isfinite(atol)) and np.all(np.isfinite(rtol))):
        err_s = np.geterr()["invalid"]
        err_msg = f"One of rtol or atol is not valid, atol: {atol}, rtol: {rtol}"

        if err_s == "warn":
            warnings.warn(err_msg, RuntimeWarning, stacklevel=2)
        elif err_s == "raise":
            raise FloatingPointError(err_msg)
        elif err_s == "print":
            print(err_msg)
              
    with errstate(invalid='ignore'):
  
        result = (less_equal(abs(x - y), atol + rtol * abs(y))
                  & isfinite(y)
                  | (x == y))
        if equal_nan:
            result |= isnan(x) & isnan(y)

    return result[()]  # Flatten 0d arrays to scalars


def _array_equal_dispatcher(a1, a2, equal_nan=None):
    return (a1, a2)


_no_nan_types = {
    # should use np.dtype.BoolDType, but as of writing
    # that fails the reloading test.
    type(dtype(nt.bool)),
    type(dtype(nt.int8)),
    type(dtype(nt.int16)),