mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-08 02:22:12 -03:00
refactor(nodes): resolve dynamic inputs without inspect.stack()
The Prompt and Lora Stack Combiner nodes expose unbounded dynamic input
slots (trigger_wordsN / lora_stackN). They resolved them by having
INPUT_TYPES() return a custom lookup object, but only when the caller was
ComfyUI's get_input_info() -- detected with inspect.stack(). That frame
inspection is what the registry security scan reports as
python_anti_debugging under the obfuscated-code admin tag.
Make the lookup a dict subclass instead, so INPUT_TYPES() can always
return it:
* /object_info (server.py) json.dumps INPUT_TYPES() directly, and a
dict subclass serializes its stored entries -- byte-identical to the
plain dict that was returned before.
* input_order (list(value.keys())), validate_inputs'
set(class_inputs["optional"]) and every other iteration still see only
the static slots.
* get_input_info() (graph.py) keeps resolving dynamic names through the
overridden __contains__/__getitem__, which no longer depends on who
the caller is.
The one behaviour change is in execution.py:get_input_data -- a dynamic
input passed as a constant rather than a link now reaches the node
instead of being silently dropped. These inputs are declared forceInput,
so the frontend only offers links; where it can happen the new behaviour
is the intended one.
Verified against ComfyUI's own consumer code: json.dumps output, keys(),
set(optional) and get_input_info() lookups all match the old behaviour,
and the two nodes no longer cross-resolve each other's slots.
3657 passed, 7 skipped.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any, cast
|
||||
|
||||
from py.nodes.prompt import PromptLM
|
||||
@@ -63,6 +64,29 @@ def test_text_lm_input_types_expose_input_only_seed():
|
||||
assert "wildcard generation" in cast(Any, seed_options)["tooltip"]
|
||||
|
||||
|
||||
def test_prompt_lm_input_types_resolve_dynamic_trigger_words_slots():
|
||||
optional = PromptLM.INPUT_TYPES()["optional"]
|
||||
|
||||
assert "trigger_words1" in optional
|
||||
assert optional["trigger_words1"][0] == "STRING"
|
||||
|
||||
assert "trigger_words4" in optional
|
||||
trigger_type, trigger_options = optional["trigger_words4"]
|
||||
assert trigger_type == "STRING"
|
||||
assert cast(Any, trigger_options)["forceInput"] is True
|
||||
|
||||
# Dynamic slots resolve on demand without becoming real entries.
|
||||
assert "trigger_words4" not in dict(optional)
|
||||
|
||||
|
||||
def test_prompt_lm_input_types_serialize_only_static_slots():
|
||||
"""ComfyUI's /object_info route json.dumps INPUT_TYPES() directly."""
|
||||
payload = json.loads(json.dumps(PromptLM.INPUT_TYPES()))
|
||||
|
||||
assert set(payload["optional"]) == {"seed", "trigger_words1"}
|
||||
assert payload["optional"]["trigger_words1"][0] == "STRING"
|
||||
|
||||
|
||||
def test_text_lm_is_changed_forces_rerun_without_seed_when_text_is_dynamic():
|
||||
result = TextLM.IS_CHANGED("__flower__", seed=None)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user