from typing import Sequence


def shape_broadcast(shape_list: Sequence[tuple]):
    """
    Predict shape of broadcasted tensors with given input shapes

    Code based on Stack Overflow post `here <https://stackoverflow.com/question
    s/54859286/is-there-a-function-that-can-apply-numpys-broadcasting-rules-to-
    a-list-of-shape/>`_

    Args:
        shape_list: Sequence of shapes, each input as a tuple

    Returns:
        b_shape: Broadcasted shape of those input in `shape_list`
    """
    max_shp = max(shape_list, key=len)
    out = list(max_shp)
    for shp in shape_list:
        if shp is max_shp:
            continue
        for i, x in enumerate(shp, -len(shp)):
            if x != 1 and x != out[i]:
                if out[i] != 1:
                    raise ValueError
                out[i] = x
    return tuple(out)