parsimathious
parsimathious is a simple mathematical expression parser implemented with parsimonious. It supports basic arithmetic operations, parentheses, unary functions, constants, variables, and complex numbers.
Installation
You can install parsimathious using pip:
pip install parsimathious
Usage
Import the ExpressionParser and create an instance:
from parsimathious import ExpressionParser
parser = ExpressionParser()
Then you can parse and evaluate expressions:
result = parser("sin(pi / 2) + 1")
print(result) # Output: 2.0
Supported functions and constants
On top of basic arithmetic operations, parsimathious supports the following unary functions and constants by default:
| Name | Description |
|---|---|
sin |
Sine |
cos |
Cosine |
tan |
Tangent |
log |
Natural logarithm (base e) |
sqrt |
Square root |
exp |
Exponential (e^x) |
log10 |
Logarithm base 10 |
abs |
Absolute value |
floor |
Floor (round down) |
ceil |
Ceiling (round up) |
round |
Round to nearest integer |
sinh |
Hyperbolic sine |
cosh |
Hyperbolic cosine |
tanh |
Hyperbolic tangent |
asin |
Arc sine |
acos |
Arc cosine |
atan |
Arc tangent |
asinh |
Inverse hyperbolic sine |
acosh |
Inverse hyperbolic cosine |
atanh |
Inverse hyperbolic tangent |
sec |
Secant |
csc |
Cosecant |
cot |
Cotangent |
These dispatch on the type of their argument: complex arguments are evaluated with
cmath, everything else with
math. A real argument therefore returns a
plain float and keeps math's domain errors, while the complex branch is reached only
through a complex value:
parser("sin(1)") # 0.8414709848078965, a float
parser("sin(i)") # 1.1752011936438014j
parser("sqrt(-1)") # raises ValueError: math domain error
parser("sqrt(-1 + 0i)") # 1j
The default table is exported as DEFAULT_UNARY_FUNCTIONS, so you can build on it rather
than reaching for math directly, which would lose complex support for that entry.
Constants
| Name | Value | Description |
|---|---|---|
pi |
math.pi | The mathematical constant π |
e |
math.e | The mathematical constant e |
i |
1j | The imaginary unit |
Custom Unary Functions
It's also possible to support custom unary functions by passing a dictionary of function names to their implementations when creating the ExpressionParser:
import math
from parsimathious import ExpressionParser, UnaryFunctionMap
custom_functions: UnaryFunctionMap = {
"log2": math.log2, # Logarithm base 2
"cube": lambda x: x ** 3, # Cube function
}
parser = ExpressionParser(unary_functions=custom_functions)
result = parser("log2(8) + cube(3)")
print(result) # Output: 30.0
As with constants, this replaces the default functions rather than extending them. Spread
DEFAULT_UNARY_FUNCTIONS if you want to keep them:
from parsimathious import DEFAULT_UNARY_FUNCTIONS
parser = ExpressionParser(
unary_functions={**DEFAULT_UNARY_FUNCTIONS, "log2": math.log2},
)
Functions you supply are called exactly as given — they are never wrapped or dispatched.
Custom Constants
Custom constants can be passed via a dictionary of names to values when creating the ExpressionParser. This replaces the default constants (pi, e) rather than extending them, so include them again if you still need them:
import math
from parsimathious import ExpressionParser, ConstantMap
custom_constants: ConstantMap = {
"pi": math.pi,
"tau": 2 * math.pi,
}
parser = ExpressionParser(constants=custom_constants)
result = parser("tau / pi")
print(result) # Output: 2.0
Constant names cannot overlap with variable names (see below), and i is reserved for the imaginary unit and cannot be used as a constant name.
Variables
Unlike constants, variables don't have a fixed value: their names are declared when creating the ExpressionParser, and their values are supplied at evaluation time, by passing a dictionary of names to values to the parser call (or to eval_ast):
from parsimathious import ExpressionParser
parser = ExpressionParser(variable_names=["x", "y"])
result = parser("x + y * 2", variables={"x": 1.0, "y": 3.0})
print(result) # Output: 7.0
Each call only uses the variable values passed to it; if an expression references a declared variable but no value is provided for it, a ValueError is raised. As with constants, i is reserved for the imaginary unit and cannot be used as a variable name, and variable names cannot overlap with constant names.
NumPy arrays
Variable values are not restricted to scalars. Arithmetic works over numpy arrays out of the box, because operators dispatch through numpy itself:
import numpy as np
from parsimathious import ExpressionParser
parser = ExpressionParser(variable_names=["x"])
parser("2 * x + 1", variables={"x": np.array([0.0, 1.0, 2.0])}) # array([1., 3., 5.])
The default unary functions, however, are scalar-only and reject arrays. Use
ExpressionParser.with_numpy to get a parser whose functions are backed by numpy:
parser = ExpressionParser.with_numpy(variable_names=["x"])
x = np.linspace(0, np.pi, 5)
parser("exp(-x) * sin(x)", variables={"x": x}) # elementwise, returns an array
Function names are identical either way, so expressions need no changes. NumPy is an optional dependency:
pip install parsimathious[numpy]
To combine numpy functions with your own, build the map explicitly with
numpy_unary_functions() — with_numpy takes no unary_functions argument, since passing one
would replace the numpy table and make the constructor a no-op:
from parsimathious import numpy_unary_functions
parser = ExpressionParser(
unary_functions={**numpy_unary_functions(), "cube": lambda x: x ** 3},
variable_names=["x"],
)
Note that the numpy-backed table carries numpy's semantics throughout: sqrt(-1) returns nan
with a warning rather than raising, and results are numpy scalars rather than plain floats.
Metadata
Release files for parsimathious 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| parsimathious-0.3.0.tar.gz | 8.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| parsimathious-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.6 kB
Release files / parsimathious-0.3.0.tar.gz
| Download URL | parsimathious-0.3.0.tar.gz |
|---|---|
| Size | 8.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8f56a0b27456190dde05a7406bc0a7724e93ff8694fd7b5bebbbc556a966166b
|
|
BLAKE2b-256 checksum How to use checksums |
ca33264f71c1479f3c10e4e5ae4668c8d93b8c5e592188e9a8c6c3cce6dd5ac5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.
Transparency logRelease files / parsimathious-0.3.0-py3-none-any.whl
| Download URL | parsimathious-0.3.0-py3-none-any.whl |
|---|---|
| Size | 10.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a71c5ca3d4414bb4bb044c7edc42e31d3b122d35e98b0c8f3af9ddf1069a7067
|
|
BLAKE2b-256 checksum How to use checksums |
a7377952c208f101d0cbd3ea233ce9cb30ffa3bcccdb825534cd495b3b503ff5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.
Transparency log