Library for generating python-expressions
Project description
UnEval
UnEval is a microlibrary for generating python-expressions, which can be converted to runnable pythoncode.
Some use cases of this library are:
- Manipulation of the python-abstract syntax tree.
- Writing domain specific languages.
- Code generation.
I have the intention to build something on top of this later that converts python expressions to linear programming constraints.
Usage
Firstly, the building blocks can be used to generate expressions. Secondly, these expressions can be converted.
Building blocks
Factory | AST-class | Example |
---|---|---|
quote |
ast.Name |
quote('a') or quote.a (shortcut) |
if_ |
ast.IfExpr |
if_(quote.x >= 0, quote.x, -quote.x) |
for_ |
ast.GenExpr |
for_(quote.x ** 2, (quote.x, quote.range(5))) |
lambda_ |
ast.Lambda |
lambda_([quote.x], quote.x * quote.x) |
and_ , or_ |
ast.BoolOp |
and_(quote.x >= 10, quote.x <= 15) |
not_ , in_ |
ast.Not(), ast.In() |
not_(in_(quote.x, {1, 2, 3})) |
Converters
Converter | Target | Remark |
---|---|---|
str |
String | Convert to readable python |
to_expression |
Expression | Parse existing string |
to_ast |
AST-node | Generates AST-node |
to_code |
Code-object | Compiles the expression |
Examples
# Create variables
x, y = quote.x, quote.y # Shortcut for quote("x"), quote("y")
# Manipulate
z = x*x + y*y
d = z.abs() + x.pow(3) - y.sin(x)
# Convert
print(z) # x * x + y * y
print(ast.dump(to_ast(z))) # BinOp(left=BinOp(left=Name(id='x', ctx=Load()), op=Mult(), right=Name(id='x', ctx=Load())), op=Add(), right=BinOp(left=Name(id='y', ctx=Load()), op=Mult(), right=Name(id='y', ctx=Load())))
print(eval(to_code(z), {"x": 3, "y": 4})) # 25
These ideas can be used to create alternative syntax for lambda-functions:
from uneval import Expression, to_code, lambda_, quote
x = quote.x
def f_x(expr: Expression):
"""Create a lambda with parameter x."""
return eval(to_code(lambda_([x], expr)))
square = f_x(x * x) # Same as lambda x: x * x
print(square(5)) # => 25
You can also use it with pandas in combination with eval and query:
from uneval import quote as q
# No syntax highlighting.
df.eval("bmi = mass / height**2")
# With syntax highlighting
df.eval(f"bmi = {q.mass / q.height**2}")
Similar work
Libraries that implement something similar:
- Macropy has quasiquote.
- Polars - Writing
col.x
creates something like thisExpression
-object. - SymPy - Symbolic manipulation, but its representation is different from Python.
- pulp - Can build objectives and constraints for solving linear programming problems.
- sqlalchemy - Generates properties based on a schema.
- latexify - Converts python to SQL.
Other:
- Fixing lambda - A blog post about alternative lambda syntaxes.
- Mini-lambda - Packages to "fix" lambda.
- Meta - A few utils to work on AST's.
- python macros use cases - Stack-overflow discussion.
Useful references:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file uneval-0.0.2-py3-none-any.whl
.
File metadata
- Download URL: uneval-0.0.2-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.7.1 importlib_metadata/4.11.3 pkginfo/1.8.3 requests/2.28.1 requests-toolbelt/0.9.1 tqdm/4.64.1 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f2e5ce348a9995b10b263db3ccfddecb14a2d117902c37e841e0625ca29d618f |
|
MD5 | 4aa4120acacc85ed8cea36567c68105f |
|
BLAKE2b-256 | 21497f031b8b640ddbed35d2b12092f711aa15b5bc7a33441e15b3bdd740fdb9 |