Improved custom nodes compatibility

- Fixed and verifies compatibility with the following nodes:
   ComfyUI-Manager==3.0.1
   ComfyUI_LayerStyle==1.0.90
   ComfyUI-Easy-Use==1.3.4 (required fix)
   ComfyUI-KJNodes==1.1.7 (required mitigation)
   ComfyUI_Custom_Nodes_AlekPet==1.0.88
   LanPaint==1.4.1
   Comfyui-Simple-Json-Node==1.1.0
 - Add support to referencing files in packages.
This commit is contained in:
doctorpangloss 2025-10-23 16:28:10 -07:00
parent d707efe53c
commit 67f9d3e693
4 changed files with 21 additions and 7 deletions

View File

@ -151,6 +151,9 @@ class SupportedExtensions:
p: FolderNames = self.parent()
return len(list(p.supported_extensions(self.folder_name)))
def __or__(self, other):
self._append_any(other)
return self
__ior__ = _append_any
add = _append_any

View File

@ -104,7 +104,7 @@ class DownloadableFileList(ComboOptions, list[str]):
A list of downloadable files that can be validated differently than it will be serialized to JSON
"""
def __init__(self, existing_files: Iterable[str], downloadable_files: Iterable[Downloadable]):
def __init__(self, existing_files: Iterable[str], downloadable_files: Iterable[Downloadable]=tuple()):
super().__init__()
self._validation_view = set(existing_files)

View File

@ -52,6 +52,7 @@ class _PromptServerStub:
# todo: these need to be added to a real prompt server if the loading order is behaving in a complex way
self.on_prompt_handlers.append(handler)
def _vanilla_load_importing_execute_prestartup_script(node_paths: Iterable[str]) -> None:
def execute_script(script_path):
module_name = splitext(script_path)[0]
@ -62,7 +63,7 @@ def _vanilla_load_importing_execute_prestartup_script(node_paths: Iterable[str])
spec.loader.exec_module(module)
return True
except Exception as e:
logger.error(f"Failed to execute startup-script: {script_path} / {e}")
logger.error(f"Failed to execute startup-script: {script_path}", exc_info=e)
return False
node_prestartup_times = []
@ -129,7 +130,10 @@ def _vanilla_load_importing_execute_prestartup_script(node_paths: Iterable[str])
@contextmanager
def _exec_mitigations(module: types.ModuleType, module_path: str) -> Generator[ExportedNodes, Any, None]:
if module.__name__.lower() == "comfyui-manager":
if module.__name__.lower() in (
"comfyui-manager",
"comfyui_ryanonyheinside",
):
from ..cmd import folder_paths
old_file = folder_paths.__file__
@ -148,6 +152,7 @@ def _exec_mitigations(module: types.ModuleType, module_path: str) -> Generator[E
# todo: unfortunately, we shouldn't restore the patches here, they will have to be applied forever.
# concurrent.futures.ThreadPoolExecutor = _ThreadPoolExecutor
# threading.Thread.start = original_thread_start
logger.info(f"Exec mitigations were applied for {module.__name__}, due to using the folder_paths.__file__ symbol and manipulating EXTENSION_WEB_DIRS")
else:
yield ExportedNodes()

View File

@ -105,10 +105,16 @@ def test_load_font_with_upath(pkg_fs):
# UPath will use the registered fsspec filesystem for "pkg"
font_path = UPath("pkg://comfy.fonts/Tiny5-Regular.ttf")
# ImageFont.truetype can take a file-like object.
# UPath.open() provides one using the underlying fsspec filesystem.
with font_path.open("rb") as f:
font = ImageFont.truetype(f, 10)
# Try to load the font by passing the UPath object directly.
# This is not expected to work for non-local paths unless the consuming
# library (Pillow) has specific support for fsspec/upath.
try:
font = ImageFont.truetype(font_path, 10)
except (TypeError, AttributeError):
# If passing the path directly fails, fall back to opening the file
# and passing the file-like object, which is the standard way.
with font_path.open("rb") as f:
font = ImageFont.truetype(f, 10)
assert font is not None
assert isinstance(font, ImageFont.FreeTypeFont)