Tests no longer look like node tables to ComfyUI-Manager
Manager reads every .py file of a plugin, tests too, and listed ten names from two test files as AMB's nodes, the only match for Power Lora Loader among them, so a workflow missing it could offer AMB in place of rgthree. The tables are written so its scanner passes them by, and a new test uses the scanner's own patterns to keep any file from looking like one again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e6a9c3be93
commit
6d1776d856
@@ -0,0 +1,37 @@
|
||||
"""ComfyUI-Manager reads every .py file of a plugin, tests too, and lists whatever looks like a node
|
||||
table as that plugin's nodes. AMB has none (AD-024), so no file may look like one: a table in a test once
|
||||
made Manager offer AMB to people who missed Power Lora Loader, in place of rgthree."""
|
||||
import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
PLUGIN = Path(__file__).resolve().parents[1]
|
||||
|
||||
# As ComfyUI-Manager's scanner.py (scan_in_file) has them.
|
||||
TABLE = re.compile(r"_CLASS_MAPPINGS\s*(?::\s*\w+\s*)?=\s*(?:\\\s*)?{([^}]*)}", re.MULTILINE | re.DOTALL)
|
||||
OTHERS = (r'^[^=]*_CLASS_MAPPINGS\["(.*?)"\]', r"^[^=]*_CLASS_MAPPINGS\['(.*?)'\]",
|
||||
r'@register_node\("(.+)",\s*\".+"\)', r'"(\w+)"\s*:\s*{"class":\s*\w+\s*')
|
||||
|
||||
|
||||
def claims(code):
|
||||
"""What the scanner would take for nodes in `code`: the tables with something in them, and the other forms."""
|
||||
found = [table.strip() for table in TABLE.findall(code) if table.strip()]
|
||||
return found + [name for pattern in OTHERS for name in re.findall(pattern, code)]
|
||||
|
||||
|
||||
class ManagerScanTests(unittest.TestCase):
|
||||
def test_the_check_sees_a_table(self):
|
||||
name = "NODE_CLASS_" + "MAPPINGS" # in two, or this file would be the one to look like a table
|
||||
self.assertTrue(claims(name + ' = {"Some Node": object}'))
|
||||
self.assertFalse(claims(name + " = {}"))
|
||||
|
||||
def test_no_file_looks_like_a_node_table(self):
|
||||
for path in PLUGIN.rglob("*.py"):
|
||||
parts = path.relative_to(PLUGIN).parts
|
||||
if "__pycache__" in parts or any(part.startswith(".") for part in parts):
|
||||
continue # the scanner leaves these out too
|
||||
self.assertEqual(claims(path.read_text(encoding="utf-8", errors="ignore")), [], path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+12
-11
@@ -65,18 +65,19 @@ class UsageTests(unittest.TestCase):
|
||||
{"type": "loras", "root": 0, "rel": "never.safetensors", "size": 9},
|
||||
{"type": "vae", "root": 0, "rel": "hashed.safetensors", "size": 1},
|
||||
]
|
||||
registered = { # by this name, not as the keyword's value: tests/test_manager_scan.py says why
|
||||
"KSampler": node("nodes", ["MODEL"], ["LATENT"]),
|
||||
"Power Lora Loader (rgthree)": node("custom_nodes.rgthree-comfy", ["MODEL"], ["MODEL"]),
|
||||
"easy loraStack": node("custom_nodes.ComfyUI-Easy-Use"),
|
||||
"easy seed": node("custom_nodes.ComfyUI-Easy-Use.py.nodes"),
|
||||
"Unused Thing": node("custom_nodes.forgotten-pack"),
|
||||
"DetailerForEach": node("custom_nodes.ComfyUI-Impact-Pack", ["IMAGE", "BBOX_DETECTOR"], ["IMAGE"]),
|
||||
"UltralyticsDetectorProvider": node("custom_nodes.comfyui-impact-subpack", [], ["BBOX_DETECTOR"]),
|
||||
"Genie Speak": node("custom_nodes.Genie-TTS", ["STRING"], ["AUDIO"]),
|
||||
"Manager Thing": node("custom_nodes.ComfyUI-Manager"),
|
||||
}
|
||||
nodes = types.SimpleNamespace(
|
||||
NODE_CLASS_MAPPINGS={
|
||||
"KSampler": node("nodes", ["MODEL"], ["LATENT"]),
|
||||
"Power Lora Loader (rgthree)": node("custom_nodes.rgthree-comfy", ["MODEL"], ["MODEL"]),
|
||||
"easy loraStack": node("custom_nodes.ComfyUI-Easy-Use"),
|
||||
"easy seed": node("custom_nodes.ComfyUI-Easy-Use.py.nodes"),
|
||||
"Unused Thing": node("custom_nodes.forgotten-pack"),
|
||||
"DetailerForEach": node("custom_nodes.ComfyUI-Impact-Pack", ["IMAGE", "BBOX_DETECTOR"], ["IMAGE"]),
|
||||
"UltralyticsDetectorProvider": node("custom_nodes.comfyui-impact-subpack", [], ["BBOX_DETECTOR"]),
|
||||
"Genie Speak": node("custom_nodes.Genie-TTS", ["STRING"], ["AUDIO"]),
|
||||
"Manager Thing": node("custom_nodes.ComfyUI-Manager"),
|
||||
},
|
||||
NODE_CLASS_MAPPINGS=registered,
|
||||
LOADED_MODULE_DIRS={name: str(custom / name) for name in packs},
|
||||
EXTENSION_WEB_DIRS={"rgthree-comfy": str(custom / "rgthree-comfy" / "js"), "page-only": str(custom / "page-only" / "web")},
|
||||
)
|
||||
|
||||
@@ -11,7 +11,8 @@ PLUGIN = Path(__file__).resolve().parents[1]
|
||||
sys.path[:0] = [str(PLUGIN), str(PLUGIN.parents[1])]
|
||||
from api import tts_version, version_manager as vm
|
||||
|
||||
NODES = 'NODE_CLASS_MAPPINGS = {"AnomalousTTS_CharacterSpeech": object}\n'
|
||||
MAPPINGS = 'NODE_CLASS_' + 'MAPPINGS' # in two: tests/test_manager_scan.py says why
|
||||
NODES = MAPPINGS + ' = {"AnomalousTTS_CharacterSpeech": object}\n'
|
||||
|
||||
|
||||
def git(cwd, *args):
|
||||
@@ -51,7 +52,7 @@ class TtsVersionTests(unittest.TestCase):
|
||||
def test_only_the_official_clone_is_found(self):
|
||||
self.assertIsNone(tts_version.find_checkout())
|
||||
self.clone('A_fork', 'https://github.com/someone/Anomalous_TTS.git')
|
||||
self.clone('Other_pack', 'https://github.com/DemonGatanjieu/Anomalous_TTS', nodes='NODE_CLASS_MAPPINGS = {}\n')
|
||||
self.clone('Other_pack', 'https://github.com/DemonGatanjieu/Anomalous_TTS', nodes=MAPPINGS + ' = {}\n')
|
||||
(self.nodes / 'Plain_copy').mkdir()
|
||||
Path(self.nodes / 'Plain_copy' / 'nodes.py').write_text(NODES, encoding='utf-8') # no git: Manager's zip, a copy
|
||||
self.assertIsNone(tts_version.find_checkout())
|
||||
|
||||
Reference in New Issue
Block a user