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 <noreply@anthropic.com>
This commit is contained in:
dante01yoon 2026-02-28 10:00:51 +09:00
parent d43390eedb
commit 2c0821bed7
3 changed files with 24 additions and 2 deletions

View File

@ -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]:

View File

@ -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]}
)

View File

@ -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