Our Engineering Team Ragged Python’s AST to Patch 100,000s of Traces of Code

Our Engineering Team Ragged Python’s AST to Patch 100,000s of Traces of Code

import ast

def is_multi_index_rename_node(node):
    """
    Tests if the given node represents the code: .levels[].name = 
    and returns the corresponding var, idx and val if it does.
    """
    strive:
        if (
            isinstance(node, ast.Build)
            and node.targets[0].attr == "name"
            and node.targets[0].cost.cost.attr == "levels"
        ):
            var = node.targets[0].cost.cost.cost.id
            idx = node.targets[0].cost.nick.cost.n
            val = node.cost

            return Appropriate, var, idx, val
    aside from:
        pass
    return Fraudulent, None, None, None

def get_new_multi_index_rename_node(var, idx, val):
    """
    Returns AST node that represents the code:  = .set_names(, diploma=)
    for the given var, idx and val.
    """
    return ast.Build(
        targets=[ast.Name(id=var)],
        cost=ast.Name(
            func=ast.Attribute(cost=ast.Title(id=var), attr="set_names"),
            args=[val],
            keywords=[ast.keyword(arg="level", value=ast.Num(n=idx))],
        ),
    )

def patch(node):
    """
    Takes an AST rooted at the give node and patches it.
    """
    # If it is a leaf node, then no patching wanted.
    if no longer hasattr(node, "_fields"):
        return node

    # For every child of the node, modify it if wanted and recursively call patch on it.
    for (name, discipline) in ast.iter_fields(node):
        if isinstance(discipline, listing):
            for i in differ(len(discipline)):
                test, var, idx, val = is_multi_index_rename_node(discipline[i])
                if test:
                    discipline[i] = get_new_multi_index_rename_node(var, idx, val)
                else:
                    patch(discipline[i])
        else:
            test, var, idx, val = is_multi_index_rename_node(discipline)
            if test:
                setattr(node, name, get_new_multi_index_rename_node(var, idx, val))
            else:
                patch(discipline)

Of the five scripts, one explicit script was uncommon – a code scrubber and no longer a aged patch. This need stemmed from an exterior occasion hunting for to test the account for of the code, with out sharing the particular common sense and specifics of the code. Hence, we wrote a scrubber, that scrubs common sense and a quantity of key formulation in the code while maintaining most efficient the imports, class and unprejudiced definitions, docstrings, form annotations and a few very explicit recordsdata required for the overview. Therefore, the AST proved to be a precious tool for buiding a code scrubber as effectively.

Read Extra

Share your love