def check_output_shapes(x, node):
    """
    x: list[Var] or tuple[Var]
    node: ParsedTFNode
    """
    if isinstance(x, ListVar):
        # No check on list.
        return
    if not isinstance(x, (list, tuple)):
        x = [x]
    tf_shapes = node.attr.get("_output_shapes", None)
    if tf_shapes is None:
        return
    inf_shapes = []
    for y in x:
        if y is None:
            msg = "TF convert returns None type in TF node {}"
            raise TypeError(msg.format(node.name))
        if types.is_tensor(y.sym_type):
            inf_shapes.append(list(y.shape))
        elif types.is_scalar(y.sym_type):
            inf_shapes.append([])
        else:
            msg = "Output type {} not understood"
            raise ValueError(msg.format(y))

    for t, s in zip(tf_shapes, inf_shapes):
        if not compatible_shapes(t, s):
            msg = (
                "Op {} ({}) type inference ({}) and TF output shape " + "({}) mismatch"
            )
            raise ValueError(msg.format(node.name, node.op, s, t))

    x: list[Var] or tuple[Var]
    node: ParsedTFNode
    
coremltools/converters/mil/frontend/tensorflow/convert_utils.py