def check_value(arr, shape, name=None):
    """
    Check that the given argument has the expected shape. Shape dimensions can
    be ints or -1 for a wildcard. The wildcard dimensions are returned, which
    allows them to be used for subsequent validation or elsewhere in the
    function.

    Args:
        arr (np.arraylike): An array-like input.
        shape (list): Shape to validate. To require an array with 3 elements,
            pass `(3,)`. To require n by 3, pass `(-1, 3)`.
        name (str): Variable name to embed in the error message.

    Returns:
        object: The wildcard dimension (if one) or a tuple of wildcard
        dimensions (if more than one).

    Example:
        >>> vg.shape.check_value(np.zeros((4, 3)), (-1, 3))
        >>> # Proceed with confidence that `points` is a k x 3 array.

    Example:
        >>> k = vg.shape.check_value(np.zeros((4, 3)), (-1, 3))
        >>> k
        4
    """

    def is_wildcard(dim):
        return dim == -1

    if any(not isinstance(dim, int) and not is_wildcard(dim) for dim in shape):
        raise ValueError("Expected shape dimensions to be int")

    if name is None:
        preamble = "Expected an array"
    else:
        preamble = f"{name} must be an array"

    if arr is None:
        raise ValueError(f"{preamble} with shape {shape}; got None")
    try:
        len(arr.shape)
    except (AttributeError, TypeError):
        raise ValueError(f"{preamble} with shape {shape}; got {arr.__class__.__name__}")

    # Check non-wildcard dimensions.
    if len(arr.shape) != len(shape) or any(
        actual != expected
        for actual, expected in zip(arr.shape, shape)
        if not is_wildcard(expected)
    ):
        raise ValueError(f"{preamble} with shape {shape}; got {arr.shape}")

    wildcard_dims = [
        actual for actual, expected in zip(arr.shape, shape) if is_wildcard(expected)
    ]
    if len(wildcard_dims) == 0:
        return None
    elif len(wildcard_dims) == 1:
        return wildcard_dims[0]
    else:
        return tuple(wildcard_dims)