mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-07-27 08:16:44 +00:00
Separate ComfyNodeV3 into an internal base class and one that only has the functions defined that a developer cares about overriding, reference ComfyNodeInternal in execution.py/server.py instead of ComfyNodeV3 to make the code not bound to a particular version of v3 schema (once placed on api)
This commit is contained in:
parent
b99e3d1336
commit
ab98b65226
@ -1,6 +1,10 @@
|
|||||||
class ComfyNodeInternal:
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class ComfyNodeInternal(ABC):
|
||||||
"""Class that all V3-based APIs inherit from for ComfyNode.
|
"""Class that all V3-based APIs inherit from for ComfyNode.
|
||||||
|
|
||||||
This is intended to only be referenced within execution.py, as it has to handle all V3 APIs going forward."""
|
This is intended to only be referenced within execution.py, as it has to handle all V3 APIs going forward."""
|
||||||
...
|
@classmethod
|
||||||
|
@abstractmethod
|
||||||
|
def GET_NODE_INFO_V1(cls):
|
||||||
|
...
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
from typing import Callable, Optional
|
from typing import Callable, Optional
|
||||||
|
|
||||||
|
|
||||||
def first_real_override(cls: type, name: str, *, base: type) -> Optional[Callable]:
|
def first_real_override(cls: type, name: str, *, base: type=None) -> Optional[Callable]:
|
||||||
"""Return the *callable* override of `name` visible on `cls`, or None if every
|
"""Return the *callable* override of `name` visible on `cls`, or None if every
|
||||||
implementation up to (and including) `base` is the placeholder defined on `base`.
|
implementation up to (and including) `base` is the placeholder defined on `base`.
|
||||||
|
|
||||||
|
If base is not provided, it will assume cls has a GET_BASE_CLASS
|
||||||
"""
|
"""
|
||||||
|
if base is None:
|
||||||
|
if not hasattr(cls, "GET_BASE_CLASS"):
|
||||||
|
raise ValueError("base is required if cls does not have a GET_BASE_CLASS; is this a valid ComfyNode subclass?")
|
||||||
|
base = cls.GET_BASE_CLASS()
|
||||||
base_attr = getattr(base, name, None)
|
base_attr = getattr(base, name, None)
|
||||||
if base_attr is None:
|
if base_attr is None:
|
||||||
return None
|
return None
|
||||||
|
@ -6,11 +6,12 @@ from collections import Counter
|
|||||||
from dataclasses import asdict, dataclass
|
from dataclasses import asdict, dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Callable, Literal, TypedDict, TypeVar
|
from typing import Any, Callable, Literal, TypedDict, TypeVar
|
||||||
|
from comfy_api.v3.helpers import first_real_override
|
||||||
|
|
||||||
# used for type hinting
|
# used for type hinting
|
||||||
import torch
|
import torch
|
||||||
from spandrel import ImageModelDescriptor
|
from spandrel import ImageModelDescriptor
|
||||||
from typing_extensions import NotRequired
|
from typing_extensions import NotRequired, final
|
||||||
|
|
||||||
from comfy.clip_vision import ClipVisionModel
|
from comfy.clip_vision import ClipVisionModel
|
||||||
from comfy.clip_vision import Output as ClipVisionOutput_
|
from comfy.clip_vision import Output as ClipVisionOutput_
|
||||||
@ -1244,8 +1245,9 @@ def add_to_dict_v3(io: InputV3 | OutputV3, d: dict):
|
|||||||
d[io.id] = (io.get_io_type(), io.as_dict())
|
d[io.id] = (io.get_io_type(), io.as_dict())
|
||||||
|
|
||||||
|
|
||||||
class ComfyNodeV3(ComfyNodeInternal):
|
|
||||||
"""Common base class for all V3 nodes."""
|
class _ComfyNodeBaseInternal(ComfyNodeInternal):
|
||||||
|
"""Common base class for storing internal methods and properties; DO NOT USE for defining nodes."""
|
||||||
|
|
||||||
RELATIVE_PYTHON_MODULE = None
|
RELATIVE_PYTHON_MODULE = None
|
||||||
SCHEMA = None
|
SCHEMA = None
|
||||||
@ -1264,6 +1266,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
@classmethod
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def execute(cls, **kwargs) -> NodeOutput:
|
def execute(cls, **kwargs) -> NodeOutput:
|
||||||
|
"""Override this function with one that performs node's actions."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -1292,28 +1295,28 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
"""
|
"""
|
||||||
return [name for name in kwargs if kwargs[name] is None]
|
return [name for name in kwargs if kwargs[name] is None]
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GET_SERIALIZERS(cls) -> list[Serializer]:
|
|
||||||
return []
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GET_NODE_INFO_V3(cls) -> dict[str, Any]:
|
|
||||||
schema = cls.GET_SCHEMA()
|
|
||||||
info = schema.get_v3_info(cls)
|
|
||||||
return asdict(info)
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.local_state: NodeStateLocal = None
|
self.local_state: NodeStateLocal = None
|
||||||
self.local_resources: ResourcesLocal = None
|
self.local_resources: ResourcesLocal = None
|
||||||
self.__class__.VALIDATE_CLASS()
|
self.__class__.VALIDATE_CLASS()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def GET_SERIALIZERS(cls) -> list[Serializer]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def GET_BASE_CLASS(cls):
|
||||||
|
return _ComfyNodeBaseInternal
|
||||||
|
|
||||||
|
@final
|
||||||
@classmethod
|
@classmethod
|
||||||
def VALIDATE_CLASS(cls):
|
def VALIDATE_CLASS(cls):
|
||||||
if not callable(cls.define_schema):
|
if first_real_override(cls, "define_schema") is None:
|
||||||
raise Exception(f"No define_schema function was defined for node class {cls.__name__}.")
|
raise Exception(f"No define_schema function was defined for node class {cls.__name__}.")
|
||||||
if not callable(cls.execute):
|
if first_real_override(cls, "execute") is None:
|
||||||
raise Exception(f"No execute function was defined for node class {cls.__name__}.")
|
raise Exception(f"No execute function was defined for node class {cls.__name__}.")
|
||||||
|
|
||||||
|
@final
|
||||||
@classmethod
|
@classmethod
|
||||||
def EXECUTE_NORMALIZED(cls, *args, **kwargs) -> NodeOutput:
|
def EXECUTE_NORMALIZED(cls, *args, **kwargs) -> NodeOutput:
|
||||||
to_return = cls.execute(*args, **kwargs)
|
to_return = cls.execute(*args, **kwargs)
|
||||||
@ -1330,6 +1333,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
else:
|
else:
|
||||||
raise Exception(f"Invalid return type from node: {type(to_return)}")
|
raise Exception(f"Invalid return type from node: {type(to_return)}")
|
||||||
|
|
||||||
|
@final
|
||||||
@classmethod
|
@classmethod
|
||||||
def PREPARE_CLASS_CLONE(cls, hidden_inputs: dict) -> type[ComfyNodeV3]:
|
def PREPARE_CLASS_CLONE(cls, hidden_inputs: dict) -> type[ComfyNodeV3]:
|
||||||
"""Creates clone of real node class to prevent monkey-patching."""
|
"""Creates clone of real node class to prevent monkey-patching."""
|
||||||
@ -1339,10 +1343,24 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
type_clone.hidden = HiddenHolder.from_dict(hidden_inputs)
|
type_clone.hidden = HiddenHolder.from_dict(hidden_inputs)
|
||||||
return type_clone
|
return type_clone
|
||||||
|
|
||||||
|
@final
|
||||||
|
@classmethod
|
||||||
|
def GET_NODE_INFO_V3(cls) -> dict[str, Any]:
|
||||||
|
schema = cls.GET_SCHEMA()
|
||||||
|
info = schema.get_v3_info(cls)
|
||||||
|
return asdict(info)
|
||||||
#############################################
|
#############################################
|
||||||
# V1 Backwards Compatibility code
|
# V1 Backwards Compatibility code
|
||||||
#--------------------------------------------
|
#--------------------------------------------
|
||||||
|
@final
|
||||||
|
@classmethod
|
||||||
|
def GET_NODE_INFO_V1(cls) -> dict[str, Any]:
|
||||||
|
schema = cls.GET_SCHEMA()
|
||||||
|
info = schema.get_v1_info(cls)
|
||||||
|
return asdict(info)
|
||||||
|
|
||||||
_DESCRIPTION = None
|
_DESCRIPTION = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def DESCRIPTION(cls): # noqa
|
def DESCRIPTION(cls): # noqa
|
||||||
if cls._DESCRIPTION is None:
|
if cls._DESCRIPTION is None:
|
||||||
@ -1350,6 +1368,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._DESCRIPTION
|
return cls._DESCRIPTION
|
||||||
|
|
||||||
_CATEGORY = None
|
_CATEGORY = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def CATEGORY(cls): # noqa
|
def CATEGORY(cls): # noqa
|
||||||
if cls._CATEGORY is None:
|
if cls._CATEGORY is None:
|
||||||
@ -1357,6 +1376,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._CATEGORY
|
return cls._CATEGORY
|
||||||
|
|
||||||
_EXPERIMENTAL = None
|
_EXPERIMENTAL = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def EXPERIMENTAL(cls): # noqa
|
def EXPERIMENTAL(cls): # noqa
|
||||||
if cls._EXPERIMENTAL is None:
|
if cls._EXPERIMENTAL is None:
|
||||||
@ -1364,6 +1384,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._EXPERIMENTAL
|
return cls._EXPERIMENTAL
|
||||||
|
|
||||||
_DEPRECATED = None
|
_DEPRECATED = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def DEPRECATED(cls): # noqa
|
def DEPRECATED(cls): # noqa
|
||||||
if cls._DEPRECATED is None:
|
if cls._DEPRECATED is None:
|
||||||
@ -1371,6 +1392,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._DEPRECATED
|
return cls._DEPRECATED
|
||||||
|
|
||||||
_API_NODE = None
|
_API_NODE = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def API_NODE(cls): # noqa
|
def API_NODE(cls): # noqa
|
||||||
if cls._API_NODE is None:
|
if cls._API_NODE is None:
|
||||||
@ -1378,6 +1400,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._API_NODE
|
return cls._API_NODE
|
||||||
|
|
||||||
_OUTPUT_NODE = None
|
_OUTPUT_NODE = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def OUTPUT_NODE(cls): # noqa
|
def OUTPUT_NODE(cls): # noqa
|
||||||
if cls._OUTPUT_NODE is None:
|
if cls._OUTPUT_NODE is None:
|
||||||
@ -1385,6 +1408,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._OUTPUT_NODE
|
return cls._OUTPUT_NODE
|
||||||
|
|
||||||
_INPUT_IS_LIST = None
|
_INPUT_IS_LIST = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def INPUT_IS_LIST(cls): # noqa
|
def INPUT_IS_LIST(cls): # noqa
|
||||||
if cls._INPUT_IS_LIST is None:
|
if cls._INPUT_IS_LIST is None:
|
||||||
@ -1392,6 +1416,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._INPUT_IS_LIST
|
return cls._INPUT_IS_LIST
|
||||||
_OUTPUT_IS_LIST = None
|
_OUTPUT_IS_LIST = None
|
||||||
|
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def OUTPUT_IS_LIST(cls): # noqa
|
def OUTPUT_IS_LIST(cls): # noqa
|
||||||
if cls._OUTPUT_IS_LIST is None:
|
if cls._OUTPUT_IS_LIST is None:
|
||||||
@ -1399,6 +1424,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._OUTPUT_IS_LIST
|
return cls._OUTPUT_IS_LIST
|
||||||
|
|
||||||
_RETURN_TYPES = None
|
_RETURN_TYPES = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def RETURN_TYPES(cls): # noqa
|
def RETURN_TYPES(cls): # noqa
|
||||||
if cls._RETURN_TYPES is None:
|
if cls._RETURN_TYPES is None:
|
||||||
@ -1406,6 +1432,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._RETURN_TYPES
|
return cls._RETURN_TYPES
|
||||||
|
|
||||||
_RETURN_NAMES = None
|
_RETURN_NAMES = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def RETURN_NAMES(cls): # noqa
|
def RETURN_NAMES(cls): # noqa
|
||||||
if cls._RETURN_NAMES is None:
|
if cls._RETURN_NAMES is None:
|
||||||
@ -1413,6 +1440,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._RETURN_NAMES
|
return cls._RETURN_NAMES
|
||||||
|
|
||||||
_OUTPUT_TOOLTIPS = None
|
_OUTPUT_TOOLTIPS = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def OUTPUT_TOOLTIPS(cls): # noqa
|
def OUTPUT_TOOLTIPS(cls): # noqa
|
||||||
if cls._OUTPUT_TOOLTIPS is None:
|
if cls._OUTPUT_TOOLTIPS is None:
|
||||||
@ -1420,6 +1448,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return cls._OUTPUT_TOOLTIPS
|
return cls._OUTPUT_TOOLTIPS
|
||||||
|
|
||||||
_NOT_IDEMPOTENT = None
|
_NOT_IDEMPOTENT = None
|
||||||
|
@final
|
||||||
@classproperty
|
@classproperty
|
||||||
def NOT_IDEMPOTENT(cls): # noqa
|
def NOT_IDEMPOTENT(cls): # noqa
|
||||||
if cls._NOT_IDEMPOTENT is None:
|
if cls._NOT_IDEMPOTENT is None:
|
||||||
@ -1428,6 +1457,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
|
|
||||||
FUNCTION = "EXECUTE_NORMALIZED"
|
FUNCTION = "EXECUTE_NORMALIZED"
|
||||||
|
|
||||||
|
@final
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls, include_hidden=True, return_schema=False) -> dict[str, dict] | tuple[dict[str, dict], SchemaV3]:
|
def INPUT_TYPES(cls, include_hidden=True, return_schema=False) -> dict[str, dict] | tuple[dict[str, dict], SchemaV3]:
|
||||||
schema = cls.FINALIZE_SCHEMA()
|
schema = cls.FINALIZE_SCHEMA()
|
||||||
@ -1439,6 +1469,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
return input, schema
|
return input, schema
|
||||||
return input
|
return input
|
||||||
|
|
||||||
|
@final
|
||||||
@classmethod
|
@classmethod
|
||||||
def FINALIZE_SCHEMA(cls):
|
def FINALIZE_SCHEMA(cls):
|
||||||
"""Call define_schema and finalize it."""
|
"""Call define_schema and finalize it."""
|
||||||
@ -1446,6 +1477,7 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
schema.finalize()
|
schema.finalize()
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
@final
|
||||||
@classmethod
|
@classmethod
|
||||||
def GET_SCHEMA(cls) -> SchemaV3:
|
def GET_SCHEMA(cls) -> SchemaV3:
|
||||||
"""Validate node class, finalize schema, validate schema, and set expected class properties."""
|
"""Validate node class, finalize schema, validate schema, and set expected class properties."""
|
||||||
@ -1487,16 +1519,58 @@ class ComfyNodeV3(ComfyNodeInternal):
|
|||||||
cls._OUTPUT_TOOLTIPS = output_tooltips
|
cls._OUTPUT_TOOLTIPS = output_tooltips
|
||||||
cls.SCHEMA = schema
|
cls.SCHEMA = schema
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def GET_NODE_INFO_V1(cls) -> dict[str, Any]:
|
|
||||||
schema = cls.GET_SCHEMA()
|
|
||||||
info = schema.get_v1_info(cls)
|
|
||||||
return asdict(info)
|
|
||||||
#--------------------------------------------
|
#--------------------------------------------
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
|
|
||||||
|
class ComfyNodeV3(_ComfyNodeBaseInternal):
|
||||||
|
"""Common base class for all V3 nodes."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@abstractmethod
|
||||||
|
def define_schema(cls) -> SchemaV3:
|
||||||
|
"""Override this function with one that returns a SchemaV3 instance."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@abstractmethod
|
||||||
|
def execute(cls, **kwargs) -> NodeOutput:
|
||||||
|
"""Override this function with one that performs node's actions."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate_inputs(cls, **kwargs) -> bool:
|
||||||
|
"""Optionally, define this function to validate inputs; equivalent to V1's VALIDATE_INPUTS."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fingerprint_inputs(cls, **kwargs) -> Any:
|
||||||
|
"""Optionally, define this function to fingerprint inputs; equivalent to V1's IS_CHANGED."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def check_lazy_status(cls, **kwargs) -> list[str]:
|
||||||
|
"""Optionally, define this function to return a list of input names that should be evaluated.
|
||||||
|
|
||||||
|
This basic mixin impl. requires all inputs.
|
||||||
|
|
||||||
|
:kwargs: All node inputs will be included here. If the input is ``None``, it should be assumed that it has not yet been evaluated. \
|
||||||
|
When using ``INPUT_IS_LIST = True``, unevaluated will instead be ``(None,)``.
|
||||||
|
|
||||||
|
Params should match the nodes execution ``FUNCTION`` (self, and all inputs by name).
|
||||||
|
Will be executed repeatedly until it returns an empty list, or all requested items were already evaluated (and sent as params).
|
||||||
|
|
||||||
|
Comfy Docs: https://docs.comfy.org/custom-nodes/backend/lazy_evaluation#defining-check-lazy-status
|
||||||
|
"""
|
||||||
|
return [name for name in kwargs if kwargs[name] is None]
|
||||||
|
|
||||||
|
@final
|
||||||
|
@classmethod
|
||||||
|
def GET_BASE_CLASS(cls):
|
||||||
|
"""DO NOT override this class. Will break things in execution.py."""
|
||||||
|
return ComfyNodeV3
|
||||||
|
|
||||||
|
|
||||||
class NodeOutput:
|
class NodeOutput:
|
||||||
'''
|
'''
|
||||||
Standardized output of a node; can pass in any number of args and/or a UIOutput into 'ui' kwarg.
|
Standardized output of a node; can pass in any number of args and/or a UIOutput into 'ui' kwarg.
|
||||||
|
15
execution.py
15
execution.py
@ -28,6 +28,7 @@ from comfy_execution.graph import (
|
|||||||
)
|
)
|
||||||
from comfy_execution.graph_utils import GraphBuilder, is_link
|
from comfy_execution.graph_utils import GraphBuilder, is_link
|
||||||
from comfy_execution.validation import validate_node_input
|
from comfy_execution.validation import validate_node_input
|
||||||
|
from comfy_api.internal import ComfyNodeInternal
|
||||||
from comfy_api.v3 import io, helpers
|
from comfy_api.v3 import io, helpers
|
||||||
|
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ class IsChangedCache:
|
|||||||
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
|
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
|
||||||
has_is_changed = False
|
has_is_changed = False
|
||||||
is_changed_name = None
|
is_changed_name = None
|
||||||
if issubclass(class_def, io.ComfyNodeV3) and helpers.first_real_override(class_def, "fingerprint_inputs", base=io.ComfyNodeV3) is not None:
|
if issubclass(class_def, ComfyNodeInternal) and helpers.first_real_override(class_def, "fingerprint_inputs") is not None:
|
||||||
has_is_changed = True
|
has_is_changed = True
|
||||||
is_changed_name = "fingerprint_inputs"
|
is_changed_name = "fingerprint_inputs"
|
||||||
elif hasattr(class_def, "IS_CHANGED"):
|
elif hasattr(class_def, "IS_CHANGED"):
|
||||||
@ -127,7 +128,7 @@ class CacheSet:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def get_input_data(inputs, class_def, unique_id, outputs=None, dynprompt=None, extra_data={}):
|
def get_input_data(inputs, class_def, unique_id, outputs=None, dynprompt=None, extra_data={}):
|
||||||
is_v3 = issubclass(class_def, io.ComfyNodeV3)
|
is_v3 = issubclass(class_def, ComfyNodeInternal)
|
||||||
if is_v3:
|
if is_v3:
|
||||||
valid_inputs, schema = class_def.INPUT_TYPES(include_hidden=False, return_schema=True)
|
valid_inputs, schema = class_def.INPUT_TYPES(include_hidden=False, return_schema=True)
|
||||||
else:
|
else:
|
||||||
@ -224,7 +225,7 @@ def _map_node_over_list(obj, input_data_all, func, allow_interrupt=False, execut
|
|||||||
if pre_execute_cb is not None and index is not None:
|
if pre_execute_cb is not None and index is not None:
|
||||||
pre_execute_cb(index)
|
pre_execute_cb(index)
|
||||||
# V3
|
# V3
|
||||||
if isinstance(obj, io.ComfyNodeV3) or (io.is_class(obj) and issubclass(obj, io.ComfyNodeV3)):
|
if isinstance(obj, ComfyNodeInternal) or (io.is_class(obj) and issubclass(obj, ComfyNodeInternal)):
|
||||||
# if is just a class, then assign no resources or state, just create clone
|
# if is just a class, then assign no resources or state, just create clone
|
||||||
if io.is_class(obj):
|
if io.is_class(obj):
|
||||||
type_obj = obj
|
type_obj = obj
|
||||||
@ -411,8 +412,8 @@ def execute(server, dynprompt, caches, current_item, extra_data, executed, promp
|
|||||||
obj = class_def()
|
obj = class_def()
|
||||||
caches.objects.set(unique_id, obj)
|
caches.objects.set(unique_id, obj)
|
||||||
|
|
||||||
if issubclass(class_def, io.ComfyNodeV3):
|
if issubclass(class_def, ComfyNodeInternal):
|
||||||
lazy_status_present = helpers.first_real_override(class_def, "check_lazy_status", base=io.ComfyNodeV3) is not None
|
lazy_status_present = helpers.first_real_override(class_def, "check_lazy_status") is not None
|
||||||
else:
|
else:
|
||||||
lazy_status_present = getattr(obj, "check_lazy_status", None) is not None
|
lazy_status_present = getattr(obj, "check_lazy_status", None) is not None
|
||||||
if lazy_status_present:
|
if lazy_status_present:
|
||||||
@ -674,9 +675,9 @@ def validate_inputs(prompt, item, validated):
|
|||||||
|
|
||||||
validate_function_inputs = []
|
validate_function_inputs = []
|
||||||
validate_has_kwargs = False
|
validate_has_kwargs = False
|
||||||
if issubclass(obj_class, io.ComfyNodeV3):
|
if issubclass(obj_class, ComfyNodeInternal):
|
||||||
validate_function_name = "validate_inputs"
|
validate_function_name = "validate_inputs"
|
||||||
validate_function = helpers.first_real_override(obj_class, validate_function_name, base=io.ComfyNodeV3)
|
validate_function = helpers.first_real_override(obj_class, validate_function_name)
|
||||||
else:
|
else:
|
||||||
validate_function_name = "VALIDATE_INPUTS"
|
validate_function_name = "VALIDATE_INPUTS"
|
||||||
validate_function = getattr(obj_class, validate_function_name, None)
|
validate_function = getattr(obj_class, validate_function_name, None)
|
||||||
|
@ -29,7 +29,7 @@ import comfy.model_management
|
|||||||
import node_helpers
|
import node_helpers
|
||||||
from comfyui_version import __version__
|
from comfyui_version import __version__
|
||||||
from app.frontend_management import FrontendManager
|
from app.frontend_management import FrontendManager
|
||||||
from comfy_api.v3.io import ComfyNodeV3
|
from comfy_api.internal import ComfyNodeInternal
|
||||||
|
|
||||||
from app.user_manager import UserManager
|
from app.user_manager import UserManager
|
||||||
from app.model_manager import ModelFileManager
|
from app.model_manager import ModelFileManager
|
||||||
@ -555,7 +555,7 @@ class PromptServer():
|
|||||||
|
|
||||||
def node_info(node_class):
|
def node_info(node_class):
|
||||||
obj_class = nodes.NODE_CLASS_MAPPINGS[node_class]
|
obj_class = nodes.NODE_CLASS_MAPPINGS[node_class]
|
||||||
if issubclass(obj_class, ComfyNodeV3):
|
if issubclass(obj_class, ComfyNodeInternal):
|
||||||
return obj_class.GET_NODE_INFO_V1()
|
return obj_class.GET_NODE_INFO_V1()
|
||||||
info = {}
|
info = {}
|
||||||
info['input'] = obj_class.INPUT_TYPES()
|
info['input'] = obj_class.INPUT_TYPES()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user