Perform element-wise logical *and* operation on arrays.

    If *values* contains a non-array object with truth_ value **False**, the
    outcome will be an array of **False**\s with suitable shape without arrays
    being evaluated. Non-array objects with truth value **True** are omitted.

    If array shapes do not match (after squeezing when enabled by user),
    :exc:`ValueError` is raised.

    This function uses :obj:`numpy.logical_and` or :obj:`numpy.all`.

def napi_and(values, **kwargs):
    """Perform element-wise logical *and* operation on arrays.

    If *values* contains a non-array object with truth_ value **False**, the
    outcome will be an array of **False**\s with suitable shape without arrays
    being evaluated. Non-array objects with truth value **True** are omitted.

    If array shapes do not match (after squeezing when enabled by user),
    :exc:`ValueError` is raised.

    This function uses :obj:`numpy.logical_and` or :obj:`numpy.all`."""

    arrays = []
    result = None
    shapes = set()

    for value in values:
        if isinstance(value, ndarray) and value.shape:
            arrays.append(value)
            shapes.add(value.shape)
        elif not value:
            result = value

    if len(shapes) > 1 and kwargs.get('sq', kwargs.get('squeeze', False)):
        shapes.clear()
        for i, a in enumerate(arrays):
            a = arrays[i] = a.squeeze()
            shapes.add(a.shape)
        if len(shapes) > 1:
            raise ValueError('array shape mismatch, even after squeezing')

    if len(shapes) > 1:
        raise ValueError('array shape mismatch')

    shape = shapes.pop() if shapes else None

    if result is not None:
        if shape:
            return numpy.zeros(shape, bool)
        else:
            return result
    elif arrays:
        sc = kwargs.get('sc', kwargs.get('shortcircuit', 0))
        if sc and numpy.prod(shape) >= sc:
            return short_circuit_and(arrays, shape)
        elif len(arrays) == 2:
            return numpy.logical_and(*arrays)
        else:
            return numpy.all(arrays, 0)
    else:
        return value