https://github.com/b-kiiskila/py_evalexpr
A Python extension module written in Rust that provides bindings to the evalexpr crate, enabling quick and safe expression evaluation in Python.
https://github.com/b-kiiskila/py_evalexpr
evalexpr expression-evaluation logical-expressions mathematical-expressions maturin pyo3 python python-bindings rust rust-extension
Last synced: 4 months ago
JSON representation
A Python extension module written in Rust that provides bindings to the evalexpr crate, enabling quick and safe expression evaluation in Python.
- Host: GitHub
- URL: https://github.com/b-kiiskila/py_evalexpr
- Owner: b-kiiskila
- License: mit
- Created: 2025-03-02T02:59:42.000Z (4 months ago)
- Default Branch: master
- Last Pushed: 2025-03-02T04:14:06.000Z (4 months ago)
- Last Synced: 2025-03-02T04:25:07.310Z (4 months ago)
- Topics: evalexpr, expression-evaluation, logical-expressions, mathematical-expressions, maturin, pyo3, python, python-bindings, rust, rust-extension
- Language: Python
- Homepage:
- Size: 48.8 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.MD
- License: LICENSE
Awesome Lists containing this project
README
# py_evalexpr
[](https://pypi.org/project/py-evalexpr/)
[](https://github.com/b-kiiskila/py_evalexpr/actions/workflows/maturin-ci.yml)
[](https://opensource.org/licenses/MIT)A Python extension module written in Rust that provides bindings to the [`evalexpr`](https://crates.io/crates/evalexpr) crate for expression evaluation.
## 🌟 Features
- 🧮 Evaluate mathematical and logical expressions from Python
- 🔒 Three evaluation contexts:
- **StatelessContext**: Simple expressions without variables
- **ImmutableContext**: Expressions with predefined variables
- **MutableContext**: Expressions that can update variables
- 📊 Type-specific evaluation methods for:
- Integers
- Floats
- Strings
- Booleans
- Tuples
- ⚡ High-performance expression evaluation
- 🚀 Built using Rust's `evalexpr` crate (version 12.0.2)
- 🐍 Python bindings via `PyO3`## ⚡ Performance Benchmarks
PyEvalExpr was benchmarked against several popular Python expression evaluation libraries:
| Test Case | py_evalexpr | sympy | asteval | simpleeval |
|------------|------------|--------|---------|------------|
| simple_arithmetic | 0.0047 ms | 0.2339 ms | 0.0116 ms | 0.0083 ms |
| complex_arithmetic | 0.0066 ms | 0.2329 ms | 0.0186 ms | 0.0118 ms |
| variables | 0.0046 ms | 0.1996 ms | 0.0126 ms | 0.0083 ms |
| math_functions | 0.0077 ms | 0.2403 ms | 0.0230 ms | 0.0117 ms |
| complex_expression | 0.0095 ms | 0.2268 ms | 0.0244 ms | 0.0141 ms |
| boolean_logic | 0.0059 ms | N/A | 0.0159 ms | 0.0103 ms |*Benchmarks performed on AMD Ryzen 9 7950X with 32GB RAM running Python 3.11 using 50,000 iterations per test. Lower is better.*
## 🔧 Prerequisites
- Python 3.11 or higher
- Rust toolchain (cargo, rustc)
- Compatible C compiler## 📦 Installation
```bash
pip install py-evalexpr
```## 💡 Usage Examples
### Quick Evaluation
```python
from py_evalexpr import evaluate, evaluate_int, evaluate_float# Basic arithmetic
result = evaluate("2 + 3 * 4") # Returns 14
result = evaluate("sqrt(16) + 2") # Returns 6.0# Type-specific evaluation
int_val = evaluate_int("42") # Returns 42 as int
float_val = evaluate_float("3.14159") # Returns 3.14159 as float
bool_val = evaluate_boolean("5 > 3") # Returns True
```### Context Usage
#### Stateless Context
```python
from py_evalexpr import StatelessContextcontext = StatelessContext()
result = context.evaluate("42").value # Integer: 42
result = context.evaluate("sin(0.5)").value # Uses built-in math functions
```#### Immutable Context
```python
from py_evalexpr import ImmutableContextcontext = ImmutableContext()
context.variables["x"] = 10
context.variables["y"] = 20result = context.evaluate("x + y").value # Returns 30
```#### Mutable Context
```python
from py_evalexpr import MutableContextcontext = MutableContext()
context.evaluate_empty("x = 10")
context.evaluate_empty("y = 20")
context.evaluate_empty("sum = x + y")
result = context.evaluate("sum * 2").value # Returns 60
```## 🛡️ Error Handling
```python
from py_evalexpr import evaluate
from py_evalexpr.exceptions import EvaluationErrortry:
result = evaluate("undefined_var + 5")
except EvaluationError as e:
print(f"Evaluation error: {e}")
```## 🤝 Contributing
Contributions are welcome:
- Open an issue to discuss proposed changes
- Submit pull requests
- Follow existing code style## 🙏 Acknowledgments
- [evalexpr](https://crates.io/crates/evalexpr) - Rust crate that powers this project
- [PyO3](https://pyo3.rs) - Python extensions framework
- [maturin](https://maturin.rs) - Python packaging tool
- [devbox](https://www.jetify.com/devbox) - Predictable development environments
- [uv](https://github.com/astral-sh/uv) - Python package installer---
Made in 🇨🇦🍁 by [Benjamin Kiiskila](https://github.com/b-kiiskila)