def na_op(x, y): try: result = op(x, y) except TypeError: assert not isinstance(y, (list, ABCSeries, ABCIndexClass)) if isinstance(y, np.ndarray): # bool-bool dtype operations should be OK, should not get here assert not (is_bool_dtype(x) and is_bool_dtype(y)) x = ensure_object(x) y = ensure_object(y) result = libops.vec_binop(x, y, op) else: # let null fall thru assert lib.is_scalar(y) if not isna(y): y = bool(y) try: result = libops.scalar_binop(x, y, op) except ( TypeError, ValueError, AttributeError, OverflowError, NotImplementedError, ): raise TypeError( "cannot compare a dtyped [{dtype}] array " "with a scalar of type [{typ}]".format( dtype=x.dtype, typ=type(y).__name__ ) ) return result
def na_logical_op(x: np.ndarray, y, op): try: # For exposition, write: # yarr = isinstance(y, np.ndarray) # yint = is_integer(y) or (yarr and y.dtype.kind == "i") # ybool = is_bool(y) or (yarr and y.dtype.kind == "b") # xint = x.dtype.kind == "i" # xbool = x.dtype.kind == "b" # Then Cases where this goes through without raising include: # (xint or xbool) and (yint or bool) result = op(x, y) except TypeError: if isinstance(y, np.ndarray): # bool-bool dtype operations should be OK, should not get here assert not (is_bool_dtype(x.dtype) and is_bool_dtype(y.dtype)) x = ensure_object(x) y = ensure_object(y) result = libops.vec_binop(x, y, op) else: # let null fall thru assert lib.is_scalar(y) if not isna(y): y = bool(y) try: result = libops.scalar_binop(x, y, op) except ( TypeError, ValueError, AttributeError, OverflowError, NotImplementedError, ): raise TypeError( "Cannot perform '{op}' with a dtyped [{dtype}] array " "and scalar of type [{typ}]".format( op=op.__name__, dtype=x.dtype, typ=type(y).__name__ ) ) return result