Remove redundant stack copies after execution

The input stack is already copied when remember_stack is off, and the
removed line is a no-op when it is on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mcDandy
2026-10-18 12:55:08 +02:00
co-authored by Claude Opus 5.5
parent 70dee22a89
commit 1b225753cd
7 changed files with 25 additions and 12 deletions
-1
View File
@@ -167,6 +167,5 @@ class AudioMathNode(io.ComfyNode):
res_list.append({"waveform": result_chunk, "sample_rate": sample_rate})
return (res_list, stack)
else:
stack = stack if remember_stack else copy.deepcopy(stack)
return ([{"waveform": result, "sample_rate": sample_rate}], stack)
-1
View File
@@ -251,5 +251,4 @@ class ConditioningMathNode(io.ComfyNode):
base[0] = (rtensor, new_dict)
res_list = [base]
stack = stack if remember_stack else copy.deepcopy(stack)
return (move_to_device(res_list, original_device),stack)
-2
View File
@@ -159,8 +159,6 @@ class ImageMathNode(io.ComfyNode):
res_list = []
for result_chunk in res:
res_list.append(result_chunk)
stack = stack if remember_stack else copy.deepcopy(stack)
return (res_list, stack)
else:
stack = stack if remember_stack else copy.deepcopy(stack)
return ([result], stack)
-4
View File
@@ -242,7 +242,6 @@ class LatentMathNode(io.ComfyNode):
if getattr(result_t, "is_nested", False):
rl = result_latent.copy()
rl["samples"] = result_t
stack = stack if remember_stack else copy.deepcopy(stack)
return (move_to_device([rl], original_device), stack)
# If the visitor produced a list/tuple, emit each element as a separate latent.
@@ -252,7 +251,6 @@ class LatentMathNode(io.ComfyNode):
rl = result_latent.copy()
rl["samples"] = comp
results.append(rl)
stack = stack if remember_stack else copy.deepcopy(stack)
return (move_to_device(results, original_device), stack)
if batching > 0:
@@ -262,9 +260,7 @@ class LatentMathNode(io.ComfyNode):
rl = result_latent.copy()
rl["samples"] = result_tensor
results.append(rl)
stack = stack if remember_stack else copy.deepcopy(stack)
return (move_to_device(results, original_device), stack)
rl = result_latent.copy()
rl["samples"] = result_t
stack = stack if remember_stack else copy.deepcopy(stack)
return (move_to_device([rl], original_device), stack)
-2
View File
@@ -140,8 +140,6 @@ class MaskMathNode(io.ComfyNode):
res_list = []
for result_chunk in res:
res_list.append(result_chunk)
stack = stack if remember_stack else copy.deepcopy(stack)
return (res_list, stack)
else:
stack = stack if remember_stack else copy.deepcopy(stack)
return ([result], stack)
-2
View File
@@ -105,9 +105,7 @@ class StringMathNode(io.ComfyNode):
for start in range(0, len(s), n):
yield s[start:start+n]
stack = stack if remember_stack else copy.deepcopy(stack)
return (chunks(result,batching), stack)
else:
stack = stack if remember_stack else copy.deepcopy(stack)
return ([result], stack)
+25
View File
@@ -9,6 +9,9 @@ from PIL import ImageFont
from more_math.Parser.UnifiedMathVisitor import ChangeTrackingDict, MathDict, UnifiedMathVisitor
from more_math.helper_functions import checkLazyNew, parse_expr
from more_math.FloatMathNode import FloatMathNode
from more_math.ImageMathNode import ImageMathNode
from more_math.LatentMathNode import LatentMathNode
from more_math.MaskMathNode import MaskMathNode
def _visit(expression, variables):
@@ -284,6 +287,28 @@ def test_unconnected_stack_is_not_shared_between_runs():
assert stack == {0: [1.0]}
@pytest.mark.parametrize("node, value, extra", [
(ImageMathNode, torch.zeros(2, 4, 4, 3), {"use_compute_device": False}),
(MaskMathNode, torch.zeros(2, 4, 4), {}),
(LatentMathNode, {"samples": torch.zeros(2, 4, 4, 4)}, {"use_compute_device": False}),
])
@pytest.mark.parametrize("batching", [0, 1])
def test_stack_across_list_runs(node, value, extra, batching):
# ComfyUI runs the node once per list item and passes the same stack object every time
def run(stack, remember):
return node.execute(V={"V0": value}, F={}, Expression="stack_push(0, 1); V0", batching=batching, remember_stack=remember, stack=stack, **extra)[-1]
shared = {}
run(shared, True)
assert run(shared, True) == {0: [1.0, 1.0]}
fresh = {}
first, second = run(fresh, False), run(fresh, False)
assert fresh == {}
assert first == second == {0: [1.0]}
assert first is not second
def test_top_level_return_stops_script():
assert _visit("x = 1; return 5; x = 2; x", {}) == 5