From 71d2a61b4577b0c2b9759015c8b5fd5bc1ab4979 Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Tue, 18 Aug 2026 21:49:10 -0400 Subject: [PATCH 1/2] Draw a frame in test_examples_run
Claude's draft test_examples_run() ran an example's __main__ block and stopped there. Under the offscreen canvas that only constructs the canvas and registers a draw function, so nothing is drawn and the draw function -- the bulk of most examples -- was never executed. Draw one frame for every example that exposes a canvas. Drawing is not enough on its own: rendercanvas calls the draw function inside its log_exception() context, so an exception there is logged to the "rendercanvas" logger and swallowed, and a frame still comes out. Assert that nothing was logged there. This makes the imgui examples fail against imgui_bundle 1.92.900, which is the bug reported in https://github.com/pygfx/wgpu-py/issues/829 and is fixed in the next commit. Resume this Claude session: ``` cd /home/mark/git/wgpu-py claude --resume 590dd7bc-312c-419e-ad3d-2c69d00943cd ```
--- examples/tests/test_examples.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/examples/tests/test_examples.py b/examples/tests/test_examples.py index 2cffb502..4fdc0f79 100644 --- a/examples/tests/test_examples.py +++ b/examples/tests/test_examples.py @@ -4,6 +4,7 @@ import os import importlib +import logging import runpy import sys from unittest.mock import patch @@ -177,11 +178,24 @@ def update_diffs(module, is_similar, img, stored_img, *, atol): @pytest.mark.parametrize("module", examples_to_run) -def test_examples_run(module, force_offscreen): +def test_examples_run(module, force_offscreen, caplog): """Run every example marked to see if they can run without error.""" - # use runpy so the module is not actually imported (and can be gc'd) - # but also to be able to run the code in the __main__ block - runpy.run_module(f"examples.{module}", run_name="__main__") + with caplog.at_level(logging.ERROR, logger="rendercanvas"): + # use runpy so the module is not actually imported (and can be gc'd) + # but also to be able to run the code in the __main__ block + module_globals = runpy.run_module(f"examples.{module}", run_name="__main__") + + # The main block only sets up the canvas and hands it a draw function; + # the offscreen canvas does not draw until asked. So ask, otherwise the + # draw function (the bulk of most examples) is never executed. + canvas = module_globals.get("canvas") + if canvas is not None: + canvas.draw() + + # rendercanvas calls the draw function inside a log_exception() context, so + # errors in it do not propagate; they only show up in the log. + errors = [r for r in caplog.records if r.name == "rendercanvas"] + assert not errors, caplog.text if __name__ == "__main__": From 461e941ddaa3bc057fc917d2e5b8d0539f847f8b Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Tue, 18 Aug 2026 21:49:10 -0400 Subject: [PATCH 2/2] Use len(draw_data.cmd_lists) in imgui backend
Claude's draft `ImDrawData.cmd_lists_count` was a legacy alias, documented in the imgui_bundle stubs as `== CmdLists.Size`, and imgui_bundle removed it in 1.92.900. Every `ImguiWgpuBackend.render()` call raises AttributeError against that release. Fixes #829. `len(draw_data.cmd_lists)` is exactly what the removed attribute equalled, and works across the whole supported `imgui-bundle>=1.92.0,<2` range: verified against 1.92.0, 1.92.3, 1.92.4, 1.92.5, 1.92.600, 1.92.601, 1.92.700, 1.92.801 and 1.92.900. No shim or version check is needed, and the pin does not need narrowing. The test from the previous commit fails without this change and passes with it. Resume this Claude session: ``` cd /home/mark/git/wgpu-py claude --resume 590dd7bc-312c-419e-ad3d-2c69d00943cd ```
--- CHANGELOG.md | 4 ++++ wgpu/utils/imgui/imgui_backend.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a458f3a2..3cb4bbc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,10 @@ Possible sections in each release: Downstream code should capture that error and skip the frame, optionally invoking some sort of sleep to save energy. See https://github.com/pygfx/wgpu-py/pull/820 for context. +### Fixed: +* The imgui backend no longer uses ``ImDrawData.cmd_lists_count``, which was removed in imgui-bundle 1.92.900. + See https://github.com/pygfx/wgpu-py/issues/829. + ## [v0.31.1] - 23-06-2026 diff --git a/wgpu/utils/imgui/imgui_backend.py b/wgpu/utils/imgui/imgui_backend.py index 2b87ded1..73a8bd5a 100644 --- a/wgpu/utils/imgui/imgui_backend.py +++ b/wgpu/utils/imgui/imgui_backend.py @@ -445,7 +445,7 @@ def render( fb_width = int(display_width * draw_data.framebuffer_scale.x) fb_height = int(display_height * draw_data.framebuffer_scale.y) - if fb_width <= 0 or fb_height <= 0 or draw_data.cmd_lists_count == 0: + if fb_width <= 0 or fb_height <= 0 or len(draw_data.cmd_lists) == 0: return if draw_data.textures is not None: