def apply_trial()

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


def apply_trial(node: dict, locals: dict) -> Any:
    """
    Works similarly as `apply_eval` however this method only evaluates
    the parts of `node["$eval"]` which starts with __trial__.
    For more information read the documentation of `apply_eval`.

    >>> apply_trial(
    ...     {"$eval" : "2 + __trial__.something[0]"},
    ...     {"__trial__": {"something":[1,2,3]}}
    ... )
    3

    Parameters
    ----------
    node
        The node which should be processed.
    locals:
        The local variables available for when calling eval.
    Returns
    -------
    Any
        The transformed node.
    """
    if not (isinstance(node, dict) and "$eval" in node):
        return node

    assert len(node) == 1, "$eval needs to be only value"
    text = str(node["$eval"])

    regex = r"""
        (__trial__
            (?:
                \[[\d]+\]|          # digits enclosed in [] i.e. __trial__[0]
                \[\"[\w_\d$]+\"\]|  # words or digits in "[]" i.e. __trial__["0"]
                \[\'[\w_\d$]+\'\]|  # words or digits in '[]' i.e. __trial__['0']
                \.\w+[\w_\d]*       # words or digits prepended with a dot, i.e. __trial__.hell0
            )+
        )
    """

    # find longest working path for each match in locals
    for match in re.finditer(regex, text, flags=re.VERBOSE):
        substring, value = recurse_eval(match[0], locals, apply_trial)

        if isinstance(value, dict) and "$eval" in value:
            raise TypeError("$eval: $trial cannot resolve to value")
        elif type(value) is str:
            text = text.replace(substring, f"'{value}'")
        else:
            text = text.replace(substring, str(value))

    # continue recursion as to handle any $eval nodes
    # generated after evaluating the current node.
    return apply_eval(evaluate(text, locals), locals)