Skip to content

fix(ci): pin uv to the matrix interpreter; de-flake the webengine resize test - #7

Merged
jawjay merged 3 commits into
mainfrom
fix/ci-matrix-python
Aug 5, 2026
Merged

fix(ci): pin uv to the matrix interpreter; de-flake the webengine resize test#7
jawjay merged 3 commits into
mainfrom
fix/ci-matrix-python

Conversation

@jawjay

@jawjay jawjay commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Fixes the two pre-existing CI failures that predate #6 (every recent main push was red the same way):

  1. 3.12/3.13 jobs never ran tests. uv sync was pinned to the matrix interpreter but the bare uv run pytest re-resolved against .python-version (3.11), discarded the synced venv, and rebuilt a bare one without dev deps — error: Failed to spawn: pytest. Job-level UV_PYTHON: ${{ matrix.python }} now pins every uv invocation, and pytest runs with --no-sync against exactly the venv the sync step prepared.
  2. test_plotly_backend_nudges_after_a_qt_resize flaked at 2 s. A cold runner spends seconds spinning up QtWebEngine on the GUI thread before the resize debounce can even be processed. The test now settles briefly after show() and waits up to 10 s (matching the suite's existing 8 s _settle budget for slow CI).

This PR's checks are the validation: all three matrix jobs should now actually run the suite and pass.

🤖 Generated with Claude Code

jawjay added 3 commits August 5, 2026 13:19
…ize test

The test job synced with --python ${{ matrix.python }} but ran pytest with a
bare 'uv run', which re-resolved against .python-version (3.11) and rebuilt a
bare venv without dev deps — 'Failed to spawn: pytest' on 3.12/3.13. UV_PYTHON
now pins every uv invocation to the matrix interpreter and pytest runs with
--no-sync against the venv the sync step prepared.

test_plotly_backend_nudges_after_a_qt_resize flaked on CI at 2 s: a cold
runner spends seconds spinning up QtWebEngine on the GUI thread before the
resize debounce can be processed. Settle after show; wait up to 10 s.
A throttled trailing RangeEvent rides a QTimer that outlives its
subscription — it can deliver after the render is disposed (CI caught it:
DisposedError raised inside the Qt event loop from _propagate). The
controller now no-ops on a disposed handle and drops panes that die
underneath propagation, alongside the existing KeyError drop.
Whether the debounced plotly.resize lands in _command_queue or goes straight
over the bridge depends on when Chromium's handshake completes — a race that
flaked on CI both ways (queue never populated once the bridge was ready).
Record send() calls instead; the wiring under test is resize → debounce →
send, regardless of which path carries it.
@jawjay
jawjay merged commit 85902f5 into main Aug 5, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant