Skip to content

confit.utils.eval

Transformer

Bases: ast.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
64
class Transformer(ast.NodeTransformer):
    """
    An ast NodeTransformer that only allows a subset of the Python AST.
    """

    ALLOWED_NODE_TYPES = set(
        [
            "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",
        ]
    )

    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
56
57
58
59
60
61
62
63
64
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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