diff --git a/comfy_api/latest/_io.py b/comfy_api/latest/_io.py index 257f07c42..f6a617c7d 100644 --- a/comfy_api/latest/_io.py +++ b/comfy_api/latest/_io.py @@ -387,10 +387,6 @@ class Combo(ComfyTypeIO): super().__init__(id, display_name, tooltip, is_output_list) self.options = options if options is not None else [] - @property - def io_type(self): - return self.options - @comfytype(io_type="COMBO") class MultiCombo(ComfyTypeI): '''Multiselect Combo input (dropdown for selecting potentially more than one value).''' diff --git a/comfy_execution/graph.py b/comfy_execution/graph.py index 0d811e354..d262201d9 100644 --- a/comfy_execution/graph.py +++ b/comfy_execution/graph.py @@ -6,6 +6,7 @@ import asyncio import inspect from comfy_execution.graph_utils import is_link, ExecutionBlocker from comfy.comfy_types.node_typing import ComfyNodeABC, InputTypeDict, InputTypeOptions +from comfy_api.latest import IO # NOTE: ExecutionBlocker code got moved to graph_utils.py to prevent torch being imported too soon during unit tests ExecutionBlocker = ExecutionBlocker @@ -97,6 +98,10 @@ def get_input_info( extra_info = input_info[1] else: extra_info = {} + # if input_type is a list, it is a Combo defined in outdated format; convert it + if isinstance(input_type, list): + extra_info["options"] = input_type + input_type = IO.Combo.io_type return input_type, input_category, extra_info class TopologicalSort: diff --git a/comfy_execution/validation.py b/comfy_execution/validation.py index 24c0b4ed7..a5e9675da 100644 --- a/comfy_execution/validation.py +++ b/comfy_execution/validation.py @@ -29,6 +29,11 @@ def validate_node_input( if received_type == IO.MatchType.io_type or input_type == IO.MatchType.io_type: return True + # This accounts for some custom nodes that output lists of options as the type; + # if we ever want to break them on purpose, this can be removed + if isinstance(received_type, list) and input_type == IO.Combo.io_type: + return True + # Not equal, and not strings if not isinstance(received_type, str) or not isinstance(input_type, str): return False diff --git a/comfy_extras/nodes_logic.py b/comfy_extras/nodes_logic.py index 95a6ba788..8dde4eb1e 100644 --- a/comfy_extras/nodes_logic.py +++ b/comfy_extras/nodes_logic.py @@ -141,6 +141,28 @@ class AutogrowPrefixTestNode(io.ComfyNode): combined = ",".join([str(x) for x in vals]) return io.NodeOutput(combined) +class ComboOutputTestNode(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="ComboOptionTestNode", + display_name="ComboOptionTest", + category="logic", + inputs=[io.Combo.Input("combo", options=["option1", "option2", "option3"]), + io.Combo.Input("combo2", options=["option4", "option5", "option6"])], + outputs=[io.Combo.Output(), io.Combo.Output()], + ) + + @classmethod + def validate_inputs(cls, combo: io.Combo.Type) -> bool: + if combo not in ["option1", "option2", "option3"]: + return "Invalid combo: {}".format(combo) + return True + + @classmethod + def execute(cls, combo: io.Combo.Type, combo2: io.Combo.Type) -> io.NodeOutput: + return io.NodeOutput(combo, combo2) + class LogicExtension(ComfyExtension): @override async def get_node_list(self) -> list[type[io.ComfyNode]]: @@ -149,6 +171,7 @@ class LogicExtension(ComfyExtension): # DCTestNode, # AutogrowNamesTestNode, # AutogrowPrefixTestNode, + ComboOutputTestNode, ] async def comfy_entrypoint() -> LogicExtension: