pure-eval

0.2.3 · active · verified Sat Mar 28

pure-eval is a Python library (current version 0.2.3) designed to safely evaluate Abstract Syntax Tree (AST) nodes without allowing arbitrary code execution or unwanted side effects. It provides a controlled way to inspect and compute values from Python expressions, making it suitable for static analysis and secure evaluation contexts. The library is actively maintained, with updates released periodically.

Warnings

Install

Imports

Quickstart

This example demonstrates how to use `pure-eval` to safely evaluate an AST node representing a pure mathematical expression. It also shows how the library prevents evaluation of expressions that might cause side effects, such as accessing a property that modifies internal state, by raising a `CannotEval` exception. For security, `__builtins__` are explicitly disabled in the evaluator context.

import ast
from pure_eval import Evaluator, CannotEval

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.area_computed = False

    @property
    def area(self):
        self.area_computed = True # This is a side effect
        return self.width * self.height

# Create an AST node representing a pure expression
rect_node = ast.parse("rect.width * rect.height").body[0].value
rect_instance = Rectangle(10, 5)

# Initialize Evaluator with the context. Disable builtins for security.
evaluator = Evaluator({
    "rect": rect_instance,
    "__builtins__": {} 
})

try:
    result = evaluator.evaluate(rect_node)
    print(f"Evaluated pure result: {result}")
except CannotEval as e:
    print(f"Could not evaluate pure expression: {e}")

# Create an AST node representing an expression with a potential side effect
side_effect_node = ast.parse("rect.area").body[0].value

try:
    evaluator.evaluate(side_effect_node)
except CannotEval as e:
    print(f"Refused to evaluate expression with potential side effect: {e}")

# Verify no side effect occurred from the attempted evaluation
print(f"Area computed flag: {rect_instance.area_computed}")

view raw JSON →