{"id":558,"library":"pure-eval","title":"pure-eval","description":"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.","status":"active","version":"0.2.3","language":"python","source_language":"en","source_url":"http://github.com/alexmojaki/pure_eval","tags":["AST","evaluation","safe-evaluation","security","abstract-syntax-tree"],"install":[{"cmd":"pip install pure-eval","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"Evaluator","correct":"from pure_eval import Evaluator"},{"symbol":"CannotEval","correct":"from pure_eval import CannotEval"}],"quickstart":{"code":"import ast\nfrom pure_eval import Evaluator, CannotEval\n\nclass Rectangle:\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n        self.area_computed = False\n\n    @property\n    def area(self):\n        self.area_computed = True # This is a side effect\n        return self.width * self.height\n\n# Create an AST node representing a pure expression\nrect_node = ast.parse(\"rect.width * rect.height\").body[0].value\nrect_instance = Rectangle(10, 5)\n\n# Initialize Evaluator with the context. Disable builtins for security.\nevaluator = Evaluator({\n    \"rect\": rect_instance,\n    \"__builtins__\": {} \n})\n\ntry:\n    result = evaluator.evaluate(rect_node)\n    print(f\"Evaluated pure result: {result}\")\nexcept CannotEval as e:\n    print(f\"Could not evaluate pure expression: {e}\")\n\n# Create an AST node representing an expression with a potential side effect\nside_effect_node = ast.parse(\"rect.area\").body[0].value\n\ntry:\n    evaluator.evaluate(side_effect_node)\nexcept CannotEval as e:\n    print(f\"Refused to evaluate expression with potential side effect: {e}\")\n\n# Verify no side effect occurred from the attempted evaluation\nprint(f\"Area computed flag: {rect_instance.area_computed}\")","lang":"python","description":"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."},"warnings":[{"fix":"Ensure that the AST nodes you intend to evaluate represent genuinely pure expressions. Anticipate and handle `CannotEval` exceptions for any expressions that might involve non-pure operations.","message":"pure-eval is explicitly designed to raise a `CannotEval` exception when it encounters expressions that could have side effects, such as calling functions, accessing properties with getters that modify state, or modifying variables. It is not a drop-in replacement for Python's built-in `eval()` function for arbitrary code.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Initialize `Evaluator` with `Evaluator(global_context={'__builtins__': {}})` or a custom safe dictionary for `__builtins__`.","message":"By default, `pure-eval`'s `Evaluator` might inherit built-in functions and names from the execution environment. For maximum security and a truly 'pure' evaluation context, explicitly pass an empty dictionary `{}` or a carefully curated whitelist of safe built-ins to the `__builtins__` key in the `global_context` dictionary when initializing `Evaluator`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure you are using the correct method for evaluation, typically `evaluator.eval(ast_node)`.","message":"The `Evaluator` class in `pure-eval` does not have an `evaluate` method. The primary method for evaluating AST nodes is `eval` (or `exec`). Attempting to call `evaluator.evaluate()` will result in an `AttributeError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Instead of `evaluator.evaluate(node)`, use `evaluator.eval_ast(node)` to evaluate an AST node, or `evaluator.eval_expr(expression_string)` to evaluate a Python expression string. Consult the `pure-eval` library's documentation for the correct method signature and usage based on your input type.","message":"The `Evaluator` class in `pure-eval` does not expose a method named `evaluate`. Attempting to call `evaluator.evaluate(...)` will result in an `AttributeError`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T15:07:18.487Z","next_check":"2026-06-28T00:00:00.000Z","problems":[{"fix":"Review the AST node being evaluated and ensure it consists only of safe expressions and operations that `pure-eval` is designed to handle. Avoid attempting to evaluate statements (like `import`, `def`, `class`) or expressions that access potentially unsafe attributes or functions.","cause":"The `pure-eval` library raised this exception because it encountered an AST node or operation that it deems unsafe or cannot evaluate according to its strict safety rules, such as attempting to execute arbitrary code or access forbidden attributes.","error":"CannotEval"},{"fix":"Install the library using pip: `pip install pure-eval` or ensure your virtual environment is activated and the dependency is correctly listed and installed.","cause":"The `pure-eval` library is not installed in the current Python environment, or the Python interpreter cannot find it.","error":"ModuleNotFoundError: No module named 'pure_eval'"},{"fix":"If you are trying to evaluate expressions, ensure the input string to `eval()` or the AST node passed to `pure-eval`'s evaluator is a valid expression. If you intend to execute statements, consider using `exec()` (with extreme caution due to security risks) or parse the code into an AST and process it using `pure-eval`'s capabilities, understanding that `pure-eval` will likely raise `CannotEval` for inherently unsafe statement nodes.","cause":"This typically occurs when trying to use Python's built-in `eval()` function (not `pure-eval`) with a string that contains a statement (e.g., `import`, `def`, `class`) instead of a pure expression. `eval()` can only evaluate expressions, not statements.","error":"SyntaxError: invalid syntax"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.3,"disk_size":"17.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1.3,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.6,"disk_size":"19.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.6,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.1,"disk_size":"11.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.1,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.3,"disk_size":"11.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"17.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.3,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}