fix: provider errors say 'failed while' once; import guard covers class/for/match bodies; diffusion picker lists .gguf again so a saved pick gets the install message; stale-module wording true for broken modules (attacker round 17)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-10-15 22:58:01 +03:00
co-authored by Claude Sonnet 5.5
parent 5c2588a9b2
commit 6e5035671a
4 changed files with 17 additions and 8 deletions
+2 -1
View File
@@ -54,7 +54,8 @@ class Registry:
answer = fn(*args, **kwargs)
except Exception as exc: # noqa: BLE001
from . import log
log.failed(f"{capability} provider {_spec.id}", exc) # skipped, but never silently
log.once(f"provider:{capability}:{_spec.id}:{exc}", log.WARNING, f"{capability} provider {_spec.id}",
f"failed while answering -- {type(exc).__name__}: {exc}") # skipped, never silently, said once
continue
if answer is not None:
return answer
+11 -3
View File
@@ -70,11 +70,17 @@ def _import_nodes(body):
for node in body:
if isinstance(node, (ast.Import, ast.ImportFrom)):
yield node
elif isinstance(node, (ast.Try, ast.If, ast.With)):
elif isinstance(node, ast.ClassDef): # a class body runs at import; its methods do not
yield from _import_nodes(node.body)
elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.Lambda)):
continue
else:
for part in ("body", "orelse", "finalbody"):
yield from _import_nodes(getattr(node, part, []))
yield from _import_nodes(getattr(node, part, None) or [])
for handler in getattr(node, "handlers", []):
yield from _import_nodes(handler.body)
for case in getattr(node, "cases", []):
yield from _import_nodes(case.body)
def _other_module_imports(path: Path, mods=None, root: Path = MODULES):
@@ -93,7 +99,7 @@ def _other_module_imports(path: Path, mods=None, root: Path = MODULES):
else:
mod = (node.module or "").split(".") if node.module else []
if node.level == 0:
targets = [tuple(mod[1:3])] if mod[:1] == ["modules"] else []
targets = ([tuple(mod[1:3])] if len(mod) >= 3 else [(mod[1], n) for n in names]) if mod[:1] == ["modules"] and len(mod) >= 2 else []
elif node.level >= 3:
targets = [tuple(mod[:2])] if len(mod) >= 2 else [(mod[0], n) for n in names] if mod else []
elif node.level == 2:
@@ -128,6 +134,8 @@ def test_the_guard_sees_every_way_to_import_another_module_at_load(tmp_path):
"from ..b import x": True, "from ...loaders.c import x": True, "from .. import b": True,
"from ...loaders import c": True, "import modules.sampling.b": True, "from modules.sampling.b import x": True,
"try:\n from ..b import x\nexcept ImportError:\n x = None": True, "if True:\n from ..b import x": True,
"from modules.sampling import b": True, "class K:\n from ..b import x": True,
"for i in []:\n from ..b import x": True, "match 1:\n case 1:\n from ..b import x": True,
"from . import helper": False, "from ..._core import log": False, "from ..prompt_taste import x": False,
"def f():\n from ..b import x": False,
}
+2 -2
View File
@@ -27,8 +27,8 @@ def _model_file_choices():
an existing pipeline's saved choice keeps its position in the list and
nothing a user already picked moves.
"""
ggufs = gguf_support.gguf_names("diffusion_models") if gguf_support.backend() else [] # no pack and no gguf package: nothing could load it
return list(folder_paths.get_filename_list("diffusion_models")) + ggufs
return list(folder_paths.get_filename_list("diffusion_models")) + \
gguf_support.gguf_names("diffusion_models") # listed even with no backend: a saved pick must stay valid so the loader can say what to install
+2 -2
View File
@@ -174,7 +174,7 @@ class FunPackModifierSettings(io.ComfyNode):
# Saved settings outlive modules (removed, renamed, or one that failed to load). Refusing the run for a
# name nobody can act on would break every project that ever used it, so it is skipped -- out loud.
log.once(f"stale_module:{module_id}", log.WARNING, "FunPack Modifier Settings",
f"saved settings for {module_id!r} ignored: no module with that id is installed")
f"saved settings for {module_id!r} ignored: no module with that id is loaded")
continue
clean, said = schema_mod.check_values(spec, values, keep_bad=guards_off)
checked[module_id] = clean
@@ -277,7 +277,7 @@ class FunPackLoadModifiers(io.ComfyNode):
for module_id in (settings or {}):
if module_id not in known and module_id not in control_mod.RESERVED:
log.once(f"stale_module:{module_id}", log.WARNING, "FunPack Load Modifiers",
f"saved settings for {module_id!r} ignored: no module with that id is installed")
f"saved settings for {module_id!r} ignored: no module with that id is loaded")
for spec in ordered:
values, said = schema_mod.check_values(
spec, (settings or {}).get(spec.id), keep_bad=full_control)