From 2c0821bed75a63ff1c7bf780243a56f757485ab5 Mon Sep 17 00:00:00 2001 From: dante01yoon Date: Sat, 28 Feb 2026 10:00:51 +0900 Subject: [PATCH] fix: address CodeRabbit review feedback - Harden EagerEval.validate with type checks and strip() for empty strings - Add _positional_alias for spreadsheet-style names beyond z (aa, ab...) - Validate JSONata result is numeric before returning - Add jsonata to requirements.txt Co-Authored-By: Claude Opus 4.6 --- comfy_api/latest/_io.py | 6 +++++- comfy_extras/nodes_math.py | 19 ++++++++++++++++++- requirements.txt | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/comfy_api/latest/_io.py b/comfy_api/latest/_io.py index a88db1e83..ac44885cf 100644 --- a/comfy_api/latest/_io.py +++ b/comfy_api/latest/_io.py @@ -1431,7 +1431,11 @@ class EagerEval: def validate(self) -> None: if self.engine != "jsonata": raise ValueError(f"Unsupported EagerEval.engine '{self.engine}'. Only 'jsonata' is supported.") - if not self.expr and not self.expr_widget: + if self.expr is not None and (not isinstance(self.expr, str) or not self.expr.strip()): + raise ValueError("EagerEval.expr must be a non-empty string when provided.") + if self.expr_widget is not None and (not isinstance(self.expr_widget, str) or not self.expr_widget.strip()): + raise ValueError("EagerEval.expr_widget must be a non-empty string when provided.") + if self.expr is None and self.expr_widget is None: raise ValueError("EagerEval requires either 'expr' or 'expr_widget'.") def as_dict(self) -> dict[str, Any]: diff --git a/comfy_extras/nodes_math.py b/comfy_extras/nodes_math.py index 7d20a57bd..999f71024 100644 --- a/comfy_extras/nodes_math.py +++ b/comfy_extras/nodes_math.py @@ -13,6 +13,19 @@ from typing_extensions import override from comfy_api.latest import ComfyExtension, io +def _positional_alias(index: int) -> str: + """Convert 0-based index to spreadsheet-style column name: a..z, aa..az, ba...""" + s = "" + n = index + while True: + n, rem = divmod(n, 26) + s = chr(ord("a") + rem) + s + if n == 0: + break + n -= 1 + return s + + class MathExpressionNode(io.ComfyNode): """Evaluates a JSONata expression against dynamically-grown inputs.""" @@ -53,11 +66,15 @@ class MathExpressionNode(io.ComfyNode): ) -> io.NodeOutput: context: dict = {} for i, (key, val) in enumerate(values.items()): - context[chr(ord("a") + i)] = val # positional: a, b, c, ... + context[_positional_alias(i)] = val # positional: a, b, c, ... aa, ab, ... context[key] = val # also by input name: value0, value1, ... context["values"] = list(values.values()) # for $sum(values) etc. result = jsonata_lib.Jsonata(expression).evaluate(context) + if isinstance(result, bool) or not isinstance(result, (int, float)): + raise ValueError( + f"Math Expression must evaluate to a numeric result, got {type(result).__name__}." + ) return io.NodeOutput( result, ui={"result": [result], "context": [context]} ) diff --git a/requirements.txt b/requirements.txt index b5b292980..3676a678c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,6 +24,7 @@ av>=14.2.0 comfy-kitchen>=0.2.7 comfy-aimdo>=0.2.2 requests +jsonata #non essential dependencies: kornia>=0.7.1