def _fill_tensor_fields(tensor_field, ranks=None, shapes=None):
    """
    Fill the tensor fields.
    ranks - ``NONE`` or a list of integers with the same length of number of inputs/outputs
    shapes - ``NONE`` or a list of shapes the same length of number of inputs/outputs. Each shape is a list or tuple
    """
    if ranks is None and shapes is None:
        return

    if ranks is None and shapes is not None:
        ranks = [len(shape) for shape in shapes]

    # Fill ranks only
    for rank in ranks:
        if rank is None:
            continue

        if not issubclass(type(rank), (int, _np.integer)):
            rank = -1  # Variable rank set to -1

        field = tensor_field.add()
        field.rank = rank

    if ranks is not None and shapes is not None:
        if len(ranks) != len(shapes):
            raise ValueError("Number of rank and shape of tensor field does not match.")

        for i in range(0, len(ranks)):
            shape = shapes[i]
            rank = ranks[i]

            # Ignore incomplete info
            if shape is None or rank is None:
                continue

            # Raise error on inconsistent input
            if rank != len(shape):
                raise ValueError("Rank and shape does not match")

            # Add the shape to the proto
            is_symbolic = False
            for s in shape:
                if not issubclass(type(s), (int, _np.integer)):
                    s = -1  # Symbolic shape set to -1
                tensor_field[i].dimValue.append(s)

    Fill the tensor fields.
    ranks - ``NONE`` or a list of integers with the same length of number of inputs/outputs
    shapes - ``NONE`` or a list of shapes the same length of number of inputs/outputs. Each shape is a list or tuple
    
coremltools/models/neural_network/builder.py