From bff714dda0361874fefa64cd259103644cf59397 Mon Sep 17 00:00:00 2001 From: xmarre Date: Mon, 16 Mar 2026 10:13:04 +0100 Subject: [PATCH] Fix non-link input cache signature --- comfy_execution/caching.py | 19 ++++++++++--------- tests-unit/execution_test/caching_test.py | 21 ++++++++++++++++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/comfy_execution/caching.py b/comfy_execution/caching.py index 0a1bd188c..4cf2c3516 100644 --- a/comfy_execution/caching.py +++ b/comfy_execution/caching.py @@ -68,19 +68,20 @@ _FAILED_SIGNATURE = object() def _shallow_is_changed_signature(value): - """Sanitize execution-time `is_changed` values without deep recursion.""" + """Sanitize execution-time `is_changed` values with a small fail-closed budget.""" value_type = type(value) if value_type in _PRIMITIVE_SIGNATURE_TYPES: return value + + canonical = to_hashable(value, max_nodes=64) + if type(canonical) is Unhashable: + return canonical + 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) - return Unhashable() + 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-unit/execution_test/caching_test.py b/tests-unit/execution_test/caching_test.py index 943f72586..6effca064 100644 --- a/tests-unit/execution_test/caching_test.py +++ b/tests-unit/execution_test/caching_test.py @@ -353,11 +353,26 @@ def test_shallow_is_changed_signature_accepts_primitive_lists(caching_module): assert sanitized == ("is_changed_list", (1, "two", None, True)) -def test_shallow_is_changed_signature_fails_closed_on_nested_containers(caching_module): - """Nested containers from `is_changed` should be rejected immediately.""" +def test_shallow_is_changed_signature_accepts_structured_builtin_fingerprint_lists(caching_module): + """Structured built-in `is_changed` fingerprints should remain representable.""" caching, _ = caching_module - sanitized = caching._shallow_is_changed_signature([1, ["nested"]]) + sanitized = caching._shallow_is_changed_signature([("seed", 42), {"cfg": 8}]) + + assert sanitized == ( + "is_changed_list", + ( + ("tuple", ("seed", 42)), + ("dict", (("cfg", 8),)), + ), + ) + + +def test_shallow_is_changed_signature_fails_closed_for_opaque_payload(caching_module): + """Opaque `is_changed` payloads should still fail closed.""" + caching, _ = caching_module + + sanitized = caching._shallow_is_changed_signature([_OpaqueValue()]) assert isinstance(sanitized, caching.Unhashable)