diff --git a/py/any_switch.py b/py/any_switch.py index 9ba437a..99713fa 100644 --- a/py/any_switch.py +++ b/py/any_switch.py @@ -1,7 +1,6 @@ from .context_utils import is_context_empty from .constants import get_category, get_name -from .utils import any_type -from .utils import ContainsAnyDict +from .utils import FlexibleOptionalInputType, any_type def is_none(value): @@ -22,7 +21,7 @@ class RgthreeAnySwitch: def INPUT_TYPES(cls): # pylint: disable = invalid-name, missing-function-docstring return { "required": {}, - "optional": ContainsAnyDict(), + "optional": FlexibleOptionalInputType(any_type), } RETURN_TYPES = (any_type,) diff --git a/py/context_merge.py b/py/context_merge.py index 529f6e7..02d0afe 100644 --- a/py/context_merge.py +++ b/py/context_merge.py @@ -2,7 +2,7 @@ from .constants import get_category, get_name from .context_utils import (ORIG_CTX_RETURN_TYPES, ORIG_CTX_RETURN_NAMES, merge_new_context, get_orig_context_return_tuple, is_context_empty) -from .utils import ContainsAnyDict +from .utils import FlexibleOptionalInputType class RgthreeContextMerge: @@ -15,7 +15,7 @@ class RgthreeContextMerge: def INPUT_TYPES(cls): # pylint: disable = invalid-name, missing-function-docstring return { "required": {}, - "optional": ContainsAnyDict(), + "optional": FlexibleOptionalInputType("RGTHREE_CONTEXT"), } RETURN_TYPES = ORIG_CTX_RETURN_TYPES diff --git a/py/context_switch.py b/py/context_switch.py index e046560..67e02e1 100644 --- a/py/context_switch.py +++ b/py/context_switch.py @@ -2,7 +2,7 @@ from .constants import get_category, get_name from .context_utils import (ORIG_CTX_RETURN_TYPES, ORIG_CTX_RETURN_NAMES, is_context_empty, get_orig_context_return_tuple) -from .utils import ContainsAnyDict +from .utils import FlexibleOptionalInputType class RgthreeContextSwitch: @@ -15,7 +15,7 @@ class RgthreeContextSwitch: def INPUT_TYPES(cls): # pylint: disable = invalid-name, missing-function-docstring return { "required": {}, - "optional": ContainsAnyDict(), + "optional": FlexibleOptionalInputType("RGTHREE_CONTEXT"), } RETURN_TYPES = ORIG_CTX_RETURN_TYPES diff --git a/py/power_lora_loader.py b/py/power_lora_loader.py index 01e9fec..9a03f28 100644 --- a/py/power_lora_loader.py +++ b/py/power_lora_loader.py @@ -1,7 +1,7 @@ from nodes import LoraLoader from .constants import get_category, get_name from .power_prompt_utils import get_lora_by_filename -from .utils import ContainsAnyDict +from .utils import FlexibleOptionalInputType, any_type class RgthreePowerLoraLoader: @@ -18,7 +18,7 @@ class RgthreePowerLoraLoader: "clip": ("CLIP",), }, # Since we will pass any number of loras in from the UI, this needs to always allow an - "optional": ContainsAnyDict(), + "optional": FlexibleOptionalInputType(any_type), "hidden": {}, } diff --git a/py/utils.py b/py/utils.py index 273cae5..a2438c3 100644 --- a/py/utils.py +++ b/py/utils.py @@ -9,9 +9,26 @@ class AnyType(str): def __ne__(self, __value: object) -> bool: return False +class FlexibleOptionalInputType(dict): + """A special class to make flexible nodes that pass data to our python handlers. -class ContainsAnyDict(dict): - """A special class that always returns true for contains check ('prop' in my_dict).""" + Enables both flexible/dynamic input types (like for Any Switch) or a dynamic number of inputs + (like for Any Switch, Context Switch, Context Merge, Power Lora Loader, etc). + + Note, for ComfyUI, all that's needed is the `__contains__` override below, which tells ComfyUI + that our node will handle the input, regardless of what it is. + + However, with https://github.com/comfyanonymous/ComfyUI/pull/2666 a large change would occur + requiring more details on the input itself. There, we need to return a list/tuple where the first + item is the type. This can be a real type, or use the AnyType for additional flexibility. + + This should be forwards compatible unless more changes occur in the PR. + """ + def __init__(self, type): + self.type = type + + def __getitem__(self, key): + return (self.type, ) def __contains__(self, key): return True