mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-25 02:20:18 +08:00
TypeResolver: address code review (link parsing + slot_idx guard + back-compat shim)
* Add _parse_link helper validating both node_id (str) and slot_idx (int, rejecting bool) so malformed API JSON (e.g. ['n1', '0']) degrades to AnyType instead of crashing with TypeError. * Add slot_idx type guards in resolve_output_type and is_output_list. * Extract _get_class_def_for_node helper to dedupe node/class lookup across resolve_output_type, is_output_list, get_declared_slot_io_type. * register_dynamic_input_func now detects 5-argument legacy callables via inspect.signature and silently wraps them; preserves backward compatibility for any custom node that registered its own dynamic input expansion against the pre-live_input_types signature. * Tests: malformed link (str slot idx, wrong arity), bad slot type directly to resolve_output_type, non-string class_type. Tests for the legacy 5-arg shim and the modern 6-arg passthrough, including callables with uninspectable signatures. Amp-Thread-ID: https://ampcode.com/threads/T-019e8568-f382-743d-a97f-0de3ff29d501 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -1369,7 +1369,36 @@ _DynamicInputFunc = Callable[
|
||||
]
|
||||
DYNAMIC_INPUT_LOOKUP: dict[str, _DynamicInputFunc] = {}
|
||||
def register_dynamic_input_func(io_type: str, func: _DynamicInputFunc):
|
||||
DYNAMIC_INPUT_LOOKUP[io_type] = func
|
||||
"""Register a dynamic-input expansion callback.
|
||||
|
||||
Accepts both the current 6-argument form and the legacy 5-argument form
|
||||
(without ``live_input_types``). Legacy callables are silently wrapped so
|
||||
custom nodes that registered against the older signature continue to work.
|
||||
"""
|
||||
try:
|
||||
sig = inspect.signature(func)
|
||||
param_count = sum(
|
||||
1 for p in sig.parameters.values()
|
||||
if p.kind in (inspect.Parameter.POSITIONAL_ONLY,
|
||||
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||
inspect.Parameter.VAR_POSITIONAL)
|
||||
)
|
||||
# 5 = legacy signature (no live_input_types). If the callable has
|
||||
# *args we can't be certain, so treat it as new-style.
|
||||
has_varargs = any(p.kind is inspect.Parameter.VAR_POSITIONAL for p in sig.parameters.values())
|
||||
is_legacy = (param_count == 5 and not has_varargs)
|
||||
except (TypeError, ValueError):
|
||||
# Builtins / C-implemented callables without introspectable signatures
|
||||
# are assumed to be new-style.
|
||||
is_legacy = False
|
||||
|
||||
if is_legacy:
|
||||
_legacy = func
|
||||
def _adapter(out_dict, live_inputs, value, input_type, curr_prefix, live_input_types=None):
|
||||
_legacy(out_dict, live_inputs, value, input_type, curr_prefix)
|
||||
DYNAMIC_INPUT_LOOKUP[io_type] = _adapter
|
||||
else:
|
||||
DYNAMIC_INPUT_LOOKUP[io_type] = func
|
||||
|
||||
def get_dynamic_input_func(io_type: str) -> _DynamicInputFunc:
|
||||
return DYNAMIC_INPUT_LOOKUP[io_type]
|
||||
|
||||
Reference in New Issue
Block a user