mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-22 09:33:29 +08:00
Add docstrings for cache signature hardening helpers
This commit is contained in:
parent
1af99b2e81
commit
1451001f64
@ -47,13 +47,14 @@ class CacheKeySet(ABC):
|
|||||||
return self.subcache_keys.get(node_id, None)
|
return self.subcache_keys.get(node_id, None)
|
||||||
|
|
||||||
class Unhashable:
|
class Unhashable:
|
||||||
|
"""Hashable sentinel for values that cannot be represented safely in cache keys."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Create a hashable sentinel value for unhashable prompt inputs."""
|
"""Initialize a sentinel that stays hashable while never comparing equal."""
|
||||||
self.value = float("NaN")
|
self.value = float("NaN")
|
||||||
|
|
||||||
|
|
||||||
def _sanitized_sort_key(obj, depth=0, max_depth=32):
|
def _sanitized_sort_key(obj, depth=0, max_depth=32):
|
||||||
"""Build a deterministic sort key from sanitized built-in container content."""
|
"""Return a deterministic ordering key for sanitized built-in container content."""
|
||||||
if depth >= max_depth:
|
if depth >= max_depth:
|
||||||
return ("MAX_DEPTH",)
|
return ("MAX_DEPTH",)
|
||||||
|
|
||||||
@ -85,7 +86,10 @@ def _sanitized_sort_key(obj, depth=0, max_depth=32):
|
|||||||
|
|
||||||
|
|
||||||
def _sanitize_signature_input(obj, depth=0, max_depth=32):
|
def _sanitize_signature_input(obj, depth=0, max_depth=32):
|
||||||
"""Sanitize prompt-signature inputs without recursing into opaque runtime objects."""
|
"""Normalize signature inputs to safe built-in containers.
|
||||||
|
|
||||||
|
Preserves built-in container type and replaces opaque runtime values with Unhashable().
|
||||||
|
"""
|
||||||
if depth >= max_depth:
|
if depth >= max_depth:
|
||||||
return Unhashable()
|
return Unhashable()
|
||||||
|
|
||||||
@ -123,7 +127,10 @@ def _sanitize_signature_input(obj, depth=0, max_depth=32):
|
|||||||
return Unhashable()
|
return Unhashable()
|
||||||
|
|
||||||
def to_hashable(obj, depth=0, max_depth=32, seen=None):
|
def to_hashable(obj, depth=0, max_depth=32, seen=None):
|
||||||
"""Convert prompt-safe built-in values into a stable hashable representation."""
|
"""Convert sanitized prompt inputs into a stable hashable representation.
|
||||||
|
|
||||||
|
Preserves built-in container type and stops safely on cycles or excessive depth.
|
||||||
|
"""
|
||||||
if depth >= max_depth:
|
if depth >= max_depth:
|
||||||
return Unhashable()
|
return Unhashable()
|
||||||
|
|
||||||
@ -182,6 +189,7 @@ class CacheKeySetID(CacheKeySet):
|
|||||||
self.subcache_keys[node_id] = (node_id, node["class_type"])
|
self.subcache_keys[node_id] = (node_id, node["class_type"])
|
||||||
|
|
||||||
class CacheKeySetInputSignature(CacheKeySet):
|
class CacheKeySetInputSignature(CacheKeySet):
|
||||||
|
"""Cache-key strategy that hashes a node's immediate inputs plus ancestor references."""
|
||||||
def __init__(self, dynprompt, node_ids, is_changed_cache):
|
def __init__(self, dynprompt, node_ids, is_changed_cache):
|
||||||
super().__init__(dynprompt, node_ids, is_changed_cache)
|
super().__init__(dynprompt, node_ids, is_changed_cache)
|
||||||
self.dynprompt = dynprompt
|
self.dynprompt = dynprompt
|
||||||
@ -201,6 +209,7 @@ class CacheKeySetInputSignature(CacheKeySet):
|
|||||||
self.subcache_keys[node_id] = (node_id, node["class_type"])
|
self.subcache_keys[node_id] = (node_id, node["class_type"])
|
||||||
|
|
||||||
async def get_node_signature(self, dynprompt, node_id):
|
async def get_node_signature(self, dynprompt, node_id):
|
||||||
|
"""Build the full cache signature for a node and its ordered ancestors."""
|
||||||
signature = []
|
signature = []
|
||||||
ancestors, order_mapping = self.get_ordered_ancestry(dynprompt, node_id)
|
ancestors, order_mapping = self.get_ordered_ancestry(dynprompt, node_id)
|
||||||
signature.append(await self.get_immediate_node_signature(dynprompt, node_id, order_mapping))
|
signature.append(await self.get_immediate_node_signature(dynprompt, node_id, order_mapping))
|
||||||
@ -209,7 +218,10 @@ class CacheKeySetInputSignature(CacheKeySet):
|
|||||||
return to_hashable(signature)
|
return to_hashable(signature)
|
||||||
|
|
||||||
async def get_immediate_node_signature(self, dynprompt, node_id, ancestor_order_mapping):
|
async def get_immediate_node_signature(self, dynprompt, node_id, ancestor_order_mapping):
|
||||||
"""Build the cache-signature fragment for a node's immediate inputs."""
|
"""Build the cache-signature fragment for a node's immediate inputs.
|
||||||
|
|
||||||
|
Link inputs are reduced to ancestor references, while raw values are sanitized first.
|
||||||
|
"""
|
||||||
if not dynprompt.has_node(node_id):
|
if not dynprompt.has_node(node_id):
|
||||||
# This node doesn't exist -- we can't cache it.
|
# This node doesn't exist -- we can't cache it.
|
||||||
return [float("NaN")]
|
return [float("NaN")]
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
def is_link(obj):
|
def is_link(obj):
|
||||||
"""Return True if obj is a plain prompt link of the form [node_id, output_index]."""
|
"""Return whether obj is a plain prompt link of the form [node_id, output_index]."""
|
||||||
# Prompt links produced by the frontend / GraphBuilder are plain Python
|
# Prompt links produced by the frontend / GraphBuilder are plain Python
|
||||||
# lists in the form [node_id, output_index]. Some custom-node paths can
|
# lists in the form [node_id, output_index]. Some custom-node paths can
|
||||||
# inject foreign runtime objects into prompt inputs during on-prompt graph
|
# inject foreign runtime objects into prompt inputs during on-prompt graph
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user