From c702cddf754a4fc0a61b046d7f80a730323b6811 Mon Sep 17 00:00:00 2001 From: xmarre Date: Wed, 18 Mar 2026 13:15:04 +0100 Subject: [PATCH] Fix shallow is_changed logic --- comfy_execution/caching.py | 20 ++++++++++---------- tests/execution/test_caching.py | 22 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/comfy_execution/caching.py b/comfy_execution/caching.py index 398036eb8..1a5615627 100644 --- a/comfy_execution/caching.py +++ b/comfy_execution/caching.py @@ -68,22 +68,22 @@ _FAILED_SIGNATURE = object() def _shallow_is_changed_signature(value): - """Reduce execution-time `is_changed` values without deep traversal.""" + """Reduce execution-time `is_changed` values through a fail-closed builtin canonicalizer.""" value_type = type(value) if value_type in _PRIMITIVE_SIGNATURE_TYPES: return value - if value_type is list or value_type is tuple: - try: - items = tuple(value) - except RuntimeError: - return Unhashable() - if all(type(item) in _PRIMITIVE_SIGNATURE_TYPES for item in items): - container_tag = "is_changed_list" if value_type is list else "is_changed_tuple" - return (container_tag, items) + if value_type not in _CONTAINER_SIGNATURE_TYPES: return Unhashable() - return Unhashable() + canonical = _signature_to_hashable(value, max_nodes=64) + if type(canonical) is Unhashable: + return canonical + if value_type is list or value_type is tuple: + container_tag = "is_changed_list" if value_type is list else "is_changed_tuple" + return (container_tag, canonical[1]) + + return canonical def _primitive_signature_sort_key(obj): diff --git a/tests/execution/test_caching.py b/tests/execution/test_caching.py index db6d95063..765ab0b91 100644 --- a/tests/execution/test_caching.py +++ b/tests/execution/test_caching.py @@ -39,7 +39,17 @@ def test_shallow_is_changed_signature_keeps_primitive_only_tuple_shallow(): ) -def test_shallow_is_changed_signature_fails_closed_for_nested_container(monkeypatch): +def test_shallow_is_changed_signature_keeps_structured_builtin_fingerprint_list(): + assert caching._shallow_is_changed_signature([("seed", 42), {"cfg": 8}]) == ( + "is_changed_list", + ( + ("tuple", ("seed", 42)), + ("dict", (("cfg", 8),)), + ), + ) + + +def test_shallow_is_changed_signature_does_not_use_to_hashable(monkeypatch): monkeypatch.setattr( caching, "to_hashable", @@ -48,9 +58,15 @@ def test_shallow_is_changed_signature_fails_closed_for_nested_container(monkeypa ), ) - signature = caching._shallow_is_changed_signature([1, [2, 3]]) + signature = caching._shallow_is_changed_signature([("seed", 42), {"cfg": 8}]) - assert isinstance(signature, caching.Unhashable) + assert signature == ( + "is_changed_list", + ( + ("tuple", ("seed", 42)), + ("dict", (("cfg", 8),)), + ), + ) def test_get_immediate_node_signature_canonicalizes_non_link_inputs(monkeypatch):