From be3d1d9d5ba7e17080f0db09155bdeb0be9abdd3 Mon Sep 17 00:00:00 2001 From: dante01yoon Date: Sat, 28 Feb 2026 21:16:23 +0900 Subject: [PATCH] refactor: replace jsonata with simpleeval for math evaluation jsonata PyPI package has critical issues: no Python 3.12/3.13 wheels, no ARM/Apple Silicon wheels, abandoned (last commit 2023), C extension. Replace with simpleeval (pure Python, 3.4M downloads/month, MIT, AST-based security). Add math module functions (sqrt, ceil, floor, log, sin, cos, tan) and variadic sum() supporting both sum(values) and sum(a, b, c). Pin version to >=1.0,<2.0. Co-Authored-By: Claude Opus 4.6 --- comfy_extras/nodes_math.py | 38 +++++++++++++++++++++++++++++++++----- requirements.txt | 2 +- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/comfy_extras/nodes_math.py b/comfy_extras/nodes_math.py index dfbb476fe..525d7d6eb 100644 --- a/comfy_extras/nodes_math.py +++ b/comfy_extras/nodes_math.py @@ -1,24 +1,52 @@ -"""Math expression node using JSONata for evaluation. +"""Math expression node using simpleeval for safe evaluation. -Provides a ComfyMathExpression node that evaluates JSONata expressions +Provides a ComfyMathExpression node that evaluates math expressions against dynamically-grown numeric inputs. """ from __future__ import annotations -import jsonata as jsonata_lib +import math + +from simpleeval import simple_eval from typing_extensions import override from comfy_api.latest import ComfyExtension, io +def _variadic_sum(*args): + """Support both sum(values) and sum(a, b, c).""" + if len(args) == 1 and hasattr(args[0], "__iter__"): + return sum(args[0]) + return sum(args) + + +MATH_FUNCTIONS = { + "sum": _variadic_sum, + "min": min, + "max": max, + "abs": abs, + "round": round, + "pow": pow, + "sqrt": math.sqrt, + "ceil": math.ceil, + "floor": math.floor, + "log": math.log, + "log2": math.log2, + "log10": math.log10, + "sin": math.sin, + "cos": math.cos, + "tan": math.tan, +} + + def _positional_alias(index: int) -> str: """Convert 0-based index to single letter: 0->a, 1->b, ..., 25->z.""" return chr(ord("a") + index) class MathExpressionNode(io.ComfyNode): - """Evaluates a JSONata expression against dynamically-grown inputs.""" + """Evaluates a math expression against dynamically-grown inputs.""" @classmethod def define_schema(cls) -> io.Schema: @@ -55,7 +83,7 @@ class MathExpressionNode(io.ComfyNode): context: dict = dict(values) context["values"] = list(values.values()) - result = jsonata_lib.Jsonata(expression).evaluate(context) + result = simple_eval(expression, names=context, functions=MATH_FUNCTIONS) if isinstance(result, bool) or not isinstance(result, (int, float)): raise ValueError( f"Math Expression '{expression}' must evaluate to a numeric result, " diff --git a/requirements.txt b/requirements.txt index 3676a678c..fed8c85a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,7 +24,7 @@ av>=14.2.0 comfy-kitchen>=0.2.7 comfy-aimdo>=0.2.2 requests -jsonata +simpleeval>=1.0,<2.0 #non essential dependencies: kornia>=0.7.1