Skip to content

confit.utils.eval

Transformer

Bases: NodeTransformer

An ast NodeTransformer that only allows a subset of the Python AST.

Source code in confit/utils/eval.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Transformer(ast.NodeTransformer):
    """
    An ast NodeTransformer that only allows a subset of the Python AST.
    """

    ALLOWED_NODE_TYPES = {
        "Expression",
        "Attribute",
        "Slice",
        "Subscript",
        "Index",
        "Constant",
        "Tuple",
        "Name",
        "Load",
        "Str",
        "BinOp",
        "Num",
        "List",
        "Dict",
        "Set",
        "Add",
        "Sub",
        "Mult",
        "Div",
        "FloorDiv",
        "Mod",
        "Pow",
        "LShift",
        "RShift",
        "BitOr",
        "BitXor",
        "BitAnd",
        "MatMult",
        "And",
        "Or",
        "Compare",
        "Eq",
        "NotEq",
        "Lt",
        "LtE",
        "Gt",
        "GtE",
        "Is",
        "IsNot",
        "In",
        "NotIn",
        "Starred",
    }

    def generic_visit(self, node):
        """
        Checks that the node type is allowed.
        """
        nodetype = type(node).__name__
        if nodetype not in self.ALLOWED_NODE_TYPES:
            raise RuntimeError(f"Invalid expression: {nodetype} not allowed !")

        return ast.NodeTransformer.generic_visit(self, node)

generic_visit(node)

Checks that the node type is allowed.

Source code in confit/utils/eval.py
55
56
57
58
59
60
61
62
63
def generic_visit(self, node):
    """
    Checks that the node type is allowed.
    """
    nodetype = type(node).__name__
    if nodetype not in self.ALLOWED_NODE_TYPES:
        raise RuntimeError(f"Invalid expression: {nodetype} not allowed !")

    return ast.NodeTransformer.generic_visit(self, node)

safe_eval(source, locals_dict=None)

Evaluate a Python string expression in a safe way. For instance, imports, function calls and builtins are disabled.

PARAMETER DESCRIPTION
source

The expression to evaluate

TYPE: str

locals_dict

The local variables to use in the evaluation

TYPE: Optional[Dict[str, Any]] DEFAULT: None

RETURNS DESCRIPTION
Any

The result of the evaluation

Source code in confit/utils/eval.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def safe_eval(source: str, locals_dict: Optional[Dict[str, Any]] = None):
    """
    Evaluate a Python string expression in a safe way.
    For instance, imports, function calls and builtins are disabled.


    Parameters
    ----------
    source: str
        The expression to evaluate
    locals_dict: Optional[Dict[str, Any]]
        The local variables to use in the evaluation

    Returns
    -------
    Any
        The result of the evaluation
    """
    tree = ast.parse(source, mode="eval")

    transformer.visit(tree)
    clause = compile(tree, "<AST>", "eval")
    result = eval(clause, {"__builtins__": {}}, locals_dict)

    return result