from typing import List
from typing import Tuple


def _broads_cores(sigs_in: List[Tuple[str]],
                  shapes: Tuple[Tuple[int, ...]],
                  msg: str
                  ) -> Tuple[List[Tuple[int, ...]], List[Tuple[int, ...]]]:
    """Extract broadcast and core shapes of arrays

    Parameters
    ----------
    sigs_in : Tuple[str, ...]
        Core signatures of input arrays
    shapes : Tuple[int, ...]
        Shapes of input arrays
    msg : str
        Potential error message

    Returns
    -------
    broads : List[Tuple[int, ...]]
        Broadcast shape of input arrays
    cores : List[Tuple[int, ...]]
        Core shape of input arrays

    Raises
    ------
    ValueError
        If arrays do not have enough dimensions.
    """
    dims = [len(sig) for sig in sigs_in]
    broads, cores = [], []
    if any(len(shape) < dim for shape, dim in zip(shapes, dims)):
        raise ValueError('Core array does not have enough ' + msg)
    for shape, dim in zip(shapes, dims):
        if dim:
            broads.append(shape[:-dim])
            cores.append(shape[-dim:])
        else:
            broads.append(shape)
            cores.append(())
    return broads, cores