mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-16 22:58:19 +08:00
Fix nondeterministic set signing
This commit is contained in:
parent
77bc7bdd6b
commit
fadd79ad48
@ -155,13 +155,14 @@ def _sanitize_signature_input(obj, depth=0, max_depth=_MAX_SIGNATURE_DEPTH, acti
|
|||||||
try:
|
try:
|
||||||
if obj_type is dict:
|
if obj_type is dict:
|
||||||
try:
|
try:
|
||||||
|
items = list(obj.items())
|
||||||
sort_memo = {}
|
sort_memo = {}
|
||||||
sanitized_items = [
|
sanitized_items = [
|
||||||
(
|
(
|
||||||
_sanitize_signature_input(key, depth + 1, max_depth, active, memo, budget),
|
_sanitize_signature_input(key, depth + 1, max_depth, active, memo, budget),
|
||||||
_sanitize_signature_input(value, depth + 1, max_depth, active, memo, budget),
|
_sanitize_signature_input(value, depth + 1, max_depth, active, memo, budget),
|
||||||
)
|
)
|
||||||
for key, value in obj.items()
|
for key, value in items
|
||||||
]
|
]
|
||||||
ordered_items = [
|
ordered_items = [
|
||||||
(
|
(
|
||||||
@ -187,22 +188,26 @@ def _sanitize_signature_input(obj, depth=0, max_depth=_MAX_SIGNATURE_DEPTH, acti
|
|||||||
result = Unhashable()
|
result = Unhashable()
|
||||||
elif obj_type is list:
|
elif obj_type is list:
|
||||||
try:
|
try:
|
||||||
result = [_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in obj]
|
items = list(obj)
|
||||||
|
result = [_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in items]
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
result = Unhashable()
|
result = Unhashable()
|
||||||
elif obj_type is tuple:
|
elif obj_type is tuple:
|
||||||
try:
|
try:
|
||||||
result = tuple(_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in obj)
|
items = list(obj)
|
||||||
|
result = tuple(_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in items)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
result = Unhashable()
|
result = Unhashable()
|
||||||
elif obj_type is set:
|
elif obj_type is set:
|
||||||
try:
|
try:
|
||||||
result = {_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in obj}
|
items = list(obj)
|
||||||
|
result = {_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in items}
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
result = Unhashable()
|
result = Unhashable()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
result = frozenset(_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in obj)
|
items = list(obj)
|
||||||
|
result = frozenset(_sanitize_signature_input(item, depth + 1, max_depth, active, memo, budget) for item in items)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
result = Unhashable()
|
result = Unhashable()
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -105,6 +105,48 @@ def test_sanitize_signature_input_handles_shared_builtin_substructures(caching_m
|
|||||||
assert sanitized[0][1]["value"] == 2
|
assert sanitized[0][1]["value"] == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanitize_signature_input_snapshots_list_before_recursing(caching_module, monkeypatch):
|
||||||
|
"""List sanitization should read a point-in-time snapshot before recursive descent."""
|
||||||
|
caching, _ = caching_module
|
||||||
|
original = caching._sanitize_signature_input
|
||||||
|
marker = object()
|
||||||
|
values = [marker, 2]
|
||||||
|
|
||||||
|
def mutating_sanitize(obj, *args, **kwargs):
|
||||||
|
"""Mutate the live list during recursion to verify snapshot-based traversal."""
|
||||||
|
if obj is marker:
|
||||||
|
values[1] = 3
|
||||||
|
return original(obj, *args, **kwargs)
|
||||||
|
|
||||||
|
monkeypatch.setattr(caching, "_sanitize_signature_input", mutating_sanitize)
|
||||||
|
|
||||||
|
sanitized = original(values)
|
||||||
|
|
||||||
|
assert isinstance(sanitized, list)
|
||||||
|
assert sanitized[1] == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanitize_signature_input_snapshots_dict_before_recursing(caching_module, monkeypatch):
|
||||||
|
"""Dict sanitization should read a point-in-time snapshot before recursive descent."""
|
||||||
|
caching, _ = caching_module
|
||||||
|
original = caching._sanitize_signature_input
|
||||||
|
marker = object()
|
||||||
|
values = {"first": marker, "second": 2}
|
||||||
|
|
||||||
|
def mutating_sanitize(obj, *args, **kwargs):
|
||||||
|
"""Mutate the live dict during recursion to verify snapshot-based traversal."""
|
||||||
|
if obj is marker:
|
||||||
|
values["second"] = 3
|
||||||
|
return original(obj, *args, **kwargs)
|
||||||
|
|
||||||
|
monkeypatch.setattr(caching, "_sanitize_signature_input", mutating_sanitize)
|
||||||
|
|
||||||
|
sanitized = original(values)
|
||||||
|
|
||||||
|
assert isinstance(sanitized, dict)
|
||||||
|
assert sanitized["second"] == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"container_factory",
|
"container_factory",
|
||||||
[
|
[
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user