def recursive_apply_list()

in runtool/runtool/recurse_config.py [0:0]


def recursive_apply_list(node: list, fn: Callable) -> Any:
    """
    Calls `recursive_apply` on each element in the node, without applying `fn`.
    Calculates the cartesian product of any `runtool.datatypes.Versions` objects
    in the nodes children. From this a new `runtool.datatypes.Versions`object is
    generated representing the different variants that this node can take.

    NOTE::
        The indexes of the node are maintained throughout this process.
    """
    versions_in_children = []
    child_normal = [None] * len(node)  # maintans indexes
    for index, value in enumerate(node):
        child = recursive_apply(value, fn)
        if isinstance(child, Versions):
            # child = Versions([1,2])
            # ->
            # expanded_child_version = ((index, 1), (index, 2))
            expanded_child_version = itertools.product([index], child)
            versions_in_children.append(expanded_child_version)
        else:
            child_normal[index] = child

    if not versions_in_children:
        return child_normal

    # merge the data from the children which were not Versions objects
    # together with the data from the children which were Versions objects
    new_versions = []
    for version in itertools.product(*versions_in_children):
        new_data = child_normal[:]
        for index, value in version:
            new_data[index] = value
        new_versions.append(new_data)

    return Versions(new_versions)