From 0fb1e239a903e93ef626a8c20589b38f46e39dff Mon Sep 17 00:00:00 2001 From: rgthree Date: Tue, 9 Sep 2025 20:31:18 -0400 Subject: [PATCH] Power Puter: Add while loops, break, continue (and pass). Cleanup extraneous print debug. --- py/power_puter.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++- py/pyproject.py | 2 -- pyproject.toml | 2 +- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/py/power_puter.py b/py/power_puter.py index 370170b..1e517f8 100644 --- a/py/power_puter.py +++ b/py/power_puter.py @@ -26,6 +26,20 @@ from .log import log_node_error, log_node_warn, log_node_info from .power_lora_loader import RgthreePowerLoraLoader +class LoopBreak(Exception): + """A special error type that is caught in a loop for correct breaking behavior.""" + + def __init__(self): + super().__init__('Cannot use "break" outside of a loop.') + + +class LoopContinue(Exception): + """A special error type that is caught in a loop for correct continue behavior.""" + + def __init__(self): + super().__init__('Cannot use "continue" outside of a loop.') + + @dataclasses.dataclass(frozen=True) # Note, kw_only=True is only python 3.10+ class Function(): """Function data. @@ -526,8 +540,31 @@ class _Puter: for i, elt in enumerate(stmt.target.elts): ctx[elt.id] = item[i] bodies = stmt.body if isinstance(stmt.body, list) else [stmt.body] + breaked = False for body in bodies: - value = self._eval_statement(body, ctx=ctx) + # Catch any breaks or continues and handle inside the loop normally. + try: + value = self._eval_statement(body, ctx=ctx) + except (LoopBreak, LoopContinue) as e: + breaked = isinstance(e, LoopBreak) + break + if breaked: + break + return None + + if isinstance(stmt, ast.While): + while self._eval_statement(stmt.test, ctx=ctx): + bodies = stmt.body if isinstance(stmt.body, list) else [stmt.body] + breaked = False + for body in bodies: + # Catch any breaks or continues and handle inside the loop normally. + try: + value = self._eval_statement(body, ctx=ctx) + except (LoopBreak, LoopContinue) as e: + breaked = isinstance(e, LoopBreak) + break + if breaked: + break return None if isinstance(stmt, ast.ListComp): @@ -699,4 +736,15 @@ class _Puter: ctx['__returned__'] = value return value + # Raise an error for break or continue, which should be caught and handled inside of loops, + # otherwise the error will be raised (which is desired when used outside of a loop). + if isinstance(stmt, ast.Break): + raise LoopBreak() + if isinstance(stmt, ast.Continue): + raise LoopContinue() + + # Literally nothing. + if isinstance(stmt, ast.Pass): + return None + raise TypeError(stmt) diff --git a/py/pyproject.py b/py/pyproject.py index 7622911..26eab34 100644 --- a/py/pyproject.py +++ b/py/pyproject.py @@ -63,10 +63,8 @@ async def get_logo_svg(): } async with session.get(LOGO_URL, headers=headers) as resp: LOGO_SVG = await resp.text() - LOGO_SVG = '' LOGO_SVG = re.sub(r'(id="bg".*fill=)"[^\"]+"', r'\1"{bg}"', LOGO_SVG) LOGO_SVG = re.sub(r'(id="fg".*fill=)"[^\"]+"', r'\1"{fg}"', LOGO_SVG) except Exception: LOGO_SVG = '' - print(LOGO_SVG) return LOGO_SVG diff --git a/pyproject.toml b/pyproject.toml index b1697a0..a1495d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "rgthree-comfy" description = "Making ComfyUI more comfortable." -version = "1.0.2509062212" +version = "1.0.2509092031" license = { file = "LICENSE" } dependencies = []