From 08fe3951145e19661b05f39dc15210dcbcaa143b Mon Sep 17 00:00:00 2001 From: rgthree Date: Sat, 24 May 2025 15:34:01 -0400 Subject: [PATCH] Power Puter: Better cache handling for connected nodes; Add print method. --- py/power_puter.py | 54 +++++++++++++++++++++++++++++++---------------- pyproject.toml | 2 +- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/py/power_puter.py b/py/power_puter.py index bd4eeb6..d091547 100644 --- a/py/power_puter.py +++ b/py/power_puter.py @@ -12,6 +12,7 @@ import json import random import dataclasses import re +import time from typing import Any, Callable import operator as op @@ -59,14 +60,10 @@ _FUNCTIONS = { Function(name="input_node", call='_get_input_node', args=(0, 1)), Function(name="dir", call=dir, args=(1, 1)), Function(name="type", call=type, args=(1, 1)), + Function(name="print", call=print, args=(0, None)), ] } -# A list of function names (from above) that could change without us knowing (globally available in -# the prompt, no from an input). This allows us to always mark the node as changed since we cannot -# tell. -_GLOBAL_FUNCTION_NAMES = ['node', 'nodes'] - # Special functions by class type (called from the Attrs.) _SPECIAL_FUNCTIONS = { RgthreePowerLoraLoader.NAME: { @@ -76,6 +73,16 @@ _SPECIAL_FUNCTIONS = { } } +# Series of regex checks for usage of a non-deterministic function. Using these is fine, but means +# the output can't be cached because it's either random, or is associated with another node that is +# not connected to ours (like looking up a node in the prompt). Using these means downstream nodes +# would always be run; that is fine for something like a final JSON output, but less so for a prompt +# text. +_NON_DETERMINISTIC_FUNCTION_CHECKS = [ + r'(? list[Any]: """Get a list of the nodes that match the node_id, or all the nodes in the prompt.""" - log_node_warn( - _NODE_NAME, - "There was a breaking change to `nodes()` in Power Puter. The return is now a list of nodes," - " rather than a dict. Update any Power Puter code." - ) nodes = self._prompt_nodes.copy() if not node_id: return nodes @@ -235,6 +252,7 @@ class _Puter: return [n for n in self._prompt_nodes if n['id'] == connected_node_id][0] except (TypeError, IndexError, KeyError): log_node_warn(_NODE_NAME, f'No input node found for "{input_name}". ') + return None def _eval_statement(self, stmt: ast.stmt, ctx: dict, prev_stmt: ast.stmt | None = None): """Evaluates an ast.stmt.""" diff --git a/pyproject.toml b/pyproject.toml index 1246271..45a334c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "rgthree-comfy" description = "Making ComfyUI more comfortable." -version = "1.0.2505222249" +version = "1.0.2505241534" license = { file = "LICENSE" } dependencies = []