Switch variadic syntax to Variadic() wrapper type annotation

Agent-Logs-Url: https://github.com/ali1234/comfyui-job-iterator/sessions/c56c9e0b-f4b5-403d-889e-bd09244426b4

Co-authored-by: ali1234 <651970+ali1234@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-04 23:00:26 +00:00
committed by GitHub
co-authored by ali1234
parent c761d43b7e
commit 3b1cc65fd5
4 changed files with 47 additions and 24 deletions
+3 -3
View File
@@ -4,7 +4,7 @@ import textwrap
import code
from .registry import register_node
from .types import Any
from .types import Any, Variadic
class RestoreStdStreams(object):
@@ -40,7 +40,7 @@ class Quitter:
@register_node(category='debug', output=True, display_name='Interact')
def Interact(*inputs: Any) -> ():
def Interact(inputs: Variadic(Any)) -> ():
"""Opens an interactive REPL whenever the node is evaluated."""
if sys.__stdout__.isatty():
with RestoreStdStreams():
@@ -52,7 +52,7 @@ def Interact(*inputs: Any) -> ():
"""),
exitmsg="Resuming workflow...",
local={
'inputs': list(inputs),
'inputs': inputs,
'quit': Quitter(),
'exit': Quitter(),
}
+11 -18
View File
@@ -1,7 +1,7 @@
import inspect
from functools import wraps
from .types import ComfyWidgetType, Combo
from .types import ComfyWidgetType, Combo, Variadic
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
@@ -29,7 +29,7 @@ def get_nodes():
return {k: v.exec.__doc__ for k, v in NODE_CLASS_MAPPINGS.items()}
def register_node(category=None, version=0, display_name=None, output=False, variadic_max=8):
def register_node(category=None, version=0, display_name=None, output=False):
def decorator(f):
node_attrs = {}
node_attrs['OUTPUT_NODE'] = output
@@ -39,21 +39,15 @@ def register_node(category=None, version=0, display_name=None, output=False, var
node_attrs['RETURN_TYPES'] = tuple(x.type if isinstance(x, ComfyWidgetType) else x for x in sig.return_annotation)
variadic_params = set()
for k, v in sig.parameters.items():
t = v.annotation
opts = {}
req = 'required'
if v.kind == inspect.Parameter.VAR_POSITIONAL:
# Variadic *args parameter: emit numbered optional inputs.
variadic_params.add(k)
if isinstance(t, ComfyWidgetType):
opts = t.opts()
t = t.type
for i in range(variadic_max):
node_attrs['_INPUT_TYPES']['optional'][f'{k}_{i}'] = (t, opts)
if isinstance(t, Variadic):
# Variadic parameter: emit numbered optional input sockets.
for i in range(t.max):
node_attrs['_INPUT_TYPES']['optional'][f'{k}_{i}'] = (t.type, t.opts())
continue
if isinstance(t, ComfyWidgetType):
@@ -83,10 +77,9 @@ def register_node(category=None, version=0, display_name=None, output=False, var
@wraps(f)
def exec(**kwargs):
call_args = []
call_kwargs = {}
for param_name, param in sig.parameters.items():
if param.kind == inspect.Parameter.VAR_POSITIONAL:
if isinstance(param.annotation, Variadic):
# Collect all {param_name}_N kwargs, sorted by index.
prefix = param_name + '_'
numbered = {}
@@ -94,9 +87,9 @@ def register_node(category=None, version=0, display_name=None, output=False, var
if k.startswith(prefix) and k[len(prefix):].isdigit():
numbered[int(k[len(prefix):])] = kwargs[k]
values = [numbered[i] for i in sorted(numbered)]
if isinstance(param.annotation, ComfyWidgetType):
values = [param.annotation[v] for v in values]
call_args.extend(values)
if isinstance(param.annotation.inner, ComfyWidgetType):
values = [param.annotation.inner[v] for v in values]
call_kwargs[param_name] = values
else:
if param_name in kwargs:
v = kwargs[param_name]
@@ -104,7 +97,7 @@ def register_node(category=None, version=0, display_name=None, output=False, var
# Look up Combo value from mapping
v = param.annotation[v]
call_kwargs[param_name] = v
return f(*call_args, **call_kwargs)
return f(**call_kwargs)
node_attrs['exec'] = staticmethod(exec)
+2 -2
View File
@@ -53,8 +53,8 @@ def MappedJoin(sequence: Sequence(), sep: String() = ", ") -> (Sequence(), ):
return (list(t), )
@register_node(display_name="Make Sequence")
def MakeSequence(*inputs: Any) -> (Sequence(), ):
def MakeSequence(inputs: Variadic(Any)) -> (Sequence(), ):
"""Collects variadic inputs into a single Sequence."""
return (list(inputs), )
return (inputs, )
+31 -1
View File
@@ -79,4 +79,34 @@ class JobStep(ComfyWidgetType):
Any = type('AnyType', (str, ), {'__ne__': lambda self, value: False})("*")
__all__ = ['Int', 'Float', 'String', 'Bool', 'Color', 'Combo', 'Any', 'Sequence', 'Job', 'JobStep']
class Variadic:
"""Annotation wrapper for variadic (multi-socket) inputs in the node decorator.
Use as a parameter annotation to declare that a node accepts up to *max*
numbered optional input sockets all sharing the same type::
@register_node()
def MyNode(items: Variadic(Int())) -> (Sequence(),):
return (list(items),)
The decorated function receives *items* as a plain Python list containing
the values of whichever numbered sockets are connected.
"""
def __init__(self, inner, max=8):
self.inner = inner
self.max = max
@property
def type(self):
if isinstance(self.inner, ComfyWidgetType):
return self.inner.type
return self.inner
def opts(self):
if isinstance(self.inner, ComfyWidgetType):
return self.inner.opts()
return {}
__all__ = ['Int', 'Float', 'String', 'Bool', 'Color', 'Combo', 'Any', 'Sequence', 'Job', 'JobStep', 'Variadic']