mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-06-05 20:55:24 +00:00
Drop register_dynamic_input_func legacy-arity shim
register_dynamic_input_func is a private helper (underscore module, not in __all__, not re-exported). Its only callers are the three core setup_dynamic_input_funcs() registrations, all of which were updated together. No third party can be relying on the old 5-arg signature, so the inspect.signature shim and accompanying backward-compat tests are over-engineered. 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,36 +1369,7 @@ _DynamicInputFunc = Callable[
|
||||
]
|
||||
DYNAMIC_INPUT_LOOKUP: dict[str, _DynamicInputFunc] = {}
|
||||
def register_dynamic_input_func(io_type: str, func: _DynamicInputFunc):
|
||||
"""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
|
||||
DYNAMIC_INPUT_LOOKUP[io_type] = func
|
||||
|
||||
def get_dynamic_input_func(io_type: str) -> _DynamicInputFunc:
|
||||
return DYNAMIC_INPUT_LOOKUP[io_type]
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
"""Backward-compat tests for ``register_dynamic_input_func``.
|
||||
|
||||
When ``live_input_types`` was added as a sixth argument to the dynamic-input
|
||||
expansion callback, third-party custom nodes that registered against the
|
||||
original 5-argument signature would otherwise crash with ``TypeError`` the
|
||||
first time their input was expanded. ``register_dynamic_input_func`` wraps
|
||||
such legacy callables transparently.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from comfy_api.latest import _io
|
||||
|
||||
|
||||
def test_legacy_5arg_callback_is_wrapped_transparently():
|
||||
received = {}
|
||||
|
||||
def legacy(out_dict, live_inputs, value, input_type, curr_prefix):
|
||||
received["args"] = (out_dict, live_inputs, value, input_type, curr_prefix)
|
||||
|
||||
io_type = "TEST_LEGACY_5ARG_V3"
|
||||
try:
|
||||
_io.register_dynamic_input_func(io_type, legacy)
|
||||
fn = _io.get_dynamic_input_func(io_type)
|
||||
|
||||
# Caller invokes with 6 arguments (current signature). The shim must
|
||||
# strip the trailing live_input_types argument before delegating.
|
||||
fn({"required": {}}, {"a": 1}, ("X", {}), "required", ["p"], {"a": "INT"})
|
||||
|
||||
assert received["args"] == (
|
||||
{"required": {}}, {"a": 1}, ("X", {}), "required", ["p"]
|
||||
)
|
||||
finally:
|
||||
_io.DYNAMIC_INPUT_LOOKUP.pop(io_type, None)
|
||||
|
||||
|
||||
def test_new_6arg_callback_passes_live_input_types_through():
|
||||
received = {}
|
||||
|
||||
def modern(out_dict, live_inputs, value, input_type, curr_prefix, live_input_types=None):
|
||||
received["live_input_types"] = live_input_types
|
||||
|
||||
io_type = "TEST_MODERN_6ARG_V3"
|
||||
try:
|
||||
_io.register_dynamic_input_func(io_type, modern)
|
||||
fn = _io.get_dynamic_input_func(io_type)
|
||||
fn({}, {}, ("X", {}), "required", None, {"foo": "IMAGE"})
|
||||
assert received["live_input_types"] == {"foo": "IMAGE"}
|
||||
finally:
|
||||
_io.DYNAMIC_INPUT_LOOKUP.pop(io_type, None)
|
||||
|
||||
|
||||
def test_callable_with_uninspectable_signature_assumed_modern():
|
||||
"""``functools.partial`` and C builtins may have no introspectable signature.
|
||||
|
||||
The shim must not blow up; falling back to the new signature is the safe
|
||||
choice (we get a clean TypeError if the callable really is too old, which
|
||||
is no worse than the pre-shim behavior).
|
||||
"""
|
||||
calls = []
|
||||
|
||||
class _CallableObj:
|
||||
# Lambdas / objects with __call__ are introspectable; partial with
|
||||
# opaque builtins are not. Simulate the latter by raising in __signature__.
|
||||
def __call__(self, *args, **kwargs):
|
||||
calls.append((args, kwargs))
|
||||
|
||||
@property
|
||||
def __signature__(self):
|
||||
raise ValueError("uninspectable")
|
||||
|
||||
io_type = "TEST_UNINSPECTABLE_V3"
|
||||
try:
|
||||
_io.register_dynamic_input_func(io_type, _CallableObj())
|
||||
fn = _io.get_dynamic_input_func(io_type)
|
||||
fn({}, {}, ("X", {}), "required", None, {"x": "INT"})
|
||||
assert calls and len(calls[0][0]) == 6
|
||||
finally:
|
||||
_io.DYNAMIC_INPUT_LOOKUP.pop(io_type, None)
|
||||
Reference in New Issue
Block a user