SimpleEval

raw JSON →
1.0.7 verified Tue May 12 auth: no python install: verified

SimpleEval is a Python library designed for safely evaluating simple expressions provided by untrusted users. It acts as a controlled alternative to Python's built-in `eval()` function, parsing expressions using the `ast` module to restrict executable operations, functions, and names. This prevents malicious code execution while allowing flexible, user-defined calculations. The current version is 1.0.7, and the library maintains an active development and release cadence.

pip install simpleeval
error ModuleNotFoundError: No module named 'simpleeval'
cause The `simpleeval` library has not been installed in your Python environment or is not accessible.
fix
pip install simpleeval
error simpleeval.InvalidExpression: Invalid name 'my_variable'
cause The expression attempts to use a variable or function name (`my_variable`) that has not been explicitly provided or registered with the `SimpleEval` instance.
fix
from simpleeval import SimpleEval

# For variables
s = SimpleEval(names={"my_variable": 10})
result = s.eval("my_variable + 5")
print(result)

# For functions
def my_custom_func(x):
    return x * 2

s = SimpleEval(functions={"my_custom_func": my_custom_func})
result = s.eval("my_custom_func(7)")
print(result)
error simpleeval.InvalidExpression: invalid syntax (<string>, line 1)
cause The string passed to `eval()` is not syntactically valid Python code, preventing `simpleeval` from parsing it.
fix
from simpleeval import SimpleEval

s = SimpleEval()
# Corrected: ensure the expression is valid Python syntax
result = s.eval("(10 + 2) * 3") # Example: user might have written "(10 + 2 * 3"
print(result)
error simpleeval.InvalidExpression: Invalid node type 'Lambda'
cause The expression contains a Python construct (like `lambda` functions, list comprehensions, or `import` statements) that `simpleeval` explicitly disallows for security and simplicity, as it only permits a restricted set of AST nodes.
fix
from simpleeval import SimpleEval

s = SimpleEval()

# SimpleEval does not allow complex constructs like lambda functions.
# Instead, define functions in Python and pass them to SimpleEval:
def calculate_discount(price, rate):
    return price * (1 - rate)

s.functions['calculate_discount'] = calculate_discount
result = s.eval('calculate_discount(100, 0.1)')
print(result) # Output: 90.0
error NameError: name 'some_variable_or_function' is not defined
cause The expression attempted to use a variable or function name that was not explicitly passed to SimpleEval via its `names` or `functions` parameters, adhering to simpleeval's security model.
fix
Pass the required names or functions as dictionaries to the SimpleEval constructor to make them available within the evaluated expression.
from simpleeval import SimpleEval
s = SimpleEval(names={'x': 10, 'y': 20}, functions={'add': lambda a, b: a + b})
result = s.eval('add(x, y)')
breaking SimpleEval 1.0.0 and later versions dropped support for Python versions prior to 3.9. If you need to support older Python environments, you must use an older version of SimpleEval.
fix Upgrade your Python environment to 3.9 or higher, or pin simpleeval to a version below 1.0.0 (e.g., `pip install simpleeval<1.0.0`).
breaking A critical vulnerability (CVE-2026-32640) allows objects passed into SimpleEval to potentially leak dangerous modules (like `os` or `sys`) through attributes or callbacks, leading to sandbox escapes. This could allow an attacker to execute arbitrary code.
fix Upgrade to simpleeval version 1.0.7 or later immediately. Carefully review any objects, functions, or modules you expose to the evaluator via `names` or `functions` parameters, ensuring they do not transitively expose dangerous functionality.
gotcha The default configuration of SimpleEval limits the `**` (power) operator to prevent Denial-of-Service (DoS) attacks from extremely large calculations. Similarly, string and comprehension lengths are capped.
fix While defaults are safe, be aware that you can modify `simpleeval.MAX_POWER`, `simpleeval.MAX_STRING_LENGTH`, or `simpleeval.MAX_COMPREHENSION_LENGTH` if your use case genuinely requires higher limits. Exercise caution as this increases DoS risk.
gotcha In Python, the `^` operator performs a bitwise XOR, not exponentiation. Users expecting `3 ^ 2` to yield 9 (like in some other languages) will get 1 (3 XOR 2).
fix If exponentiation is desired, you must explicitly replace the operator by modifying `s.operators[ast.BitXor] = simpleeval.safe_power` on a `SimpleEval` instance, or use the `**` operator.
gotcha By default, SimpleEval restricts access to object attributes (especially those starting with `_` or `func_`) and disallows sensitive built-in functions (e.g., `type`, `open`). Module access is also highly restricted.
fix To allow safe attribute access, pass `allowed_attrs=BASIC_ALLOWED_ATTRS` to `SimpleEval`. For controlled module exposure, use `ModuleWrapper`. If you need to expose custom functions, wrap them carefully to avoid security pitfalls.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.01s 17.9M
3.10 alpine (musl) - - 0.01s 17.9M
3.10 slim (glibc) wheel 1.5s 0.01s 18M
3.10 slim (glibc) - - 0.01s 18M
3.11 alpine (musl) wheel - 0.02s 19.7M
3.11 alpine (musl) - - 0.03s 19.7M
3.11 slim (glibc) wheel 1.5s 0.02s 20M
3.11 slim (glibc) - - 0.02s 20M
3.12 alpine (musl) wheel - 0.02s 11.6M
3.12 alpine (musl) - - 0.02s 11.6M
3.12 slim (glibc) wheel 1.4s 0.02s 12M
3.12 slim (glibc) - - 0.02s 12M
3.13 alpine (musl) wheel - 0.02s 11.3M
3.13 alpine (musl) - - 0.02s 11.2M
3.13 slim (glibc) wheel 1.4s 0.02s 12M
3.13 slim (glibc) - - 0.02s 12M
3.9 alpine (musl) wheel - 0.01s 17.4M
3.9 alpine (musl) - - 0.01s 17.4M
3.9 slim (glibc) wheel 1.7s 0.01s 18M
3.9 slim (glibc) - - 0.01s 18M

Demonstrates basic expression evaluation using `simple_eval` and more advanced usage with the `SimpleEval` class, including custom variables, functions, and safe attribute access.

from simpleeval import simple_eval, SimpleEval

# Basic evaluation
result1 = simple_eval("21 + 21")
print(f"Basic evaluation: {result1}") # Expected: 42

# Evaluation with custom names and functions
s = SimpleEval(names={'x': 10, 'y': 5}, functions={'add_one': lambda val: val + 1})
result2 = s.eval("x * y + add_one(2)")
print(f"Custom evaluation: {result2}") # Expected: 52 (10 * 5 + 3)

# Allowing safe attribute access
from simpleeval import BASIC_ALLOWED_ATTRS
s_attrs = SimpleEval(names={'my_string': '  hello '}, allowed_attrs=BASIC_ALLOWED_ATTRS)
result3 = s_attrs.eval("my_string.strip().upper()")
print(f"Attribute access: {result3}") # Expected: '  HELLO '