Files
olivv-cs-ComfyUI-FunPack/tests/test_run_phase.py
T
digital-garbageandClaude Opus 5 7681c599a0 progress: say which scene and which pass is running; fix context_window_schedule
Three things, all about a run telling you what it is doing.

1. The second pass is now visible. ComfyUI's progress channel carries only
   (value, max), so a chain sampling some scenes twice was one anonymous bar.
   The sampler publishes a live label ("scene 2/3 · pass 2 of 2") through the
   new run_phase module; /api/progress hands it to the editor, which appends it
   to the readout, and pass 2 also announces itself on the console the moment it
   starts rather than only in the after-the-fact run report.

   run_phase keeps its state on `sys`, not in module globals: the writer reaches
   it package-relative and the reader imports FunPack modules top-level by name,
   so they can hold different module objects and the label would never arrive.

2. The progress bar total now counts both passes. It only ever counted the main
   schedule, so with a second pass on it overflowed during scene 1 and jumped
   backwards at scene 2, whose offset is a multiple of the per-scene stride.

3. context_windows was unusable. The knob offered "uniform_standard" etc.;
   core's names are the other way round ("standard_uniform"), so every schedule
   except "batched" raised ValueError out of the sampler and FAILED THE RENDER.
   Core's names are the choices now, the old spellings are aliased so saved
   projects keep working, and an unknown name is refused with a reason naming
   what core accepts instead of crashing.

   Same call had a second, quieter break: a keyword core's handler doesn't take
   (latent_retain_index_list is absent on some builds, including this Mac's)
   raised TypeError, which was reported as "ComfyUI core too old" — silently
   switching off a feature core fully supports. Extras are dropped now, with a
   note naming the one knob that stops working.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 17:57:21 +03:00

53 lines
1.9 KiB
Python

"""run_phase — the live "what is the sampler doing" label behind the progress readout.
The one invariant that actually breaks in production: the WRITER (samplers.py) reaches this
module as a package-relative import and the READER (movie_editor's bridge) imports FunPack
modules top-level by name, so the two can hold different module objects. State in module
globals would be two separate copies and the label would never arrive. It lives on `sys`
for exactly that reason, and this pins it down.
"""
import importlib.util
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
import run_phase # noqa: E402
def _second_import():
"""A second, independent module object for the same file — what the other import path
produces at runtime."""
spec = importlib.util.spec_from_file_location("other_pkg.run_phase", ROOT / "run_phase.py")
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
def test_both_import_paths_see_the_same_label():
other = _second_import()
run_phase.set_phase("scene 2/3 · pass 2 of 2")
assert other.current()["label"] == "scene 2/3 · pass 2 of 2"
other.clear()
assert run_phase.current()["label"] == ""
def test_seq_only_ever_increases():
"""A poller uses it to tell "still the same phase" from "this phase came round again",
so it must never reset — not even when the label is cleared."""
before = run_phase.current()["seq"]
run_phase.set_phase("a")
run_phase.set_phase("a")
run_phase.clear()
assert run_phase.current()["seq"] == before + 3
def test_a_bad_label_never_raises():
"""This is a readout on the sampling path: it must not be able to fail a render."""
run_phase.set_phase(None)
assert run_phase.current()["label"] == ""
run_phase.set_phase(12)
assert run_phase.current()["label"] == "12"
run_phase.clear()