Skip to content

Commit 9610ee0

Browse files
Note ipywidgets cache monkeypatch work and in-app measurement caveat
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 822ec03 commit 9610ee0

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

notes.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,44 @@ Implemented and E2E-validated (playwright headless):
368368
version/cache-busting story before defaulting on. VueComponent (component_url) is the
369369
symmetric next step (httpVueLoader URL mode already exists in the JS).
370370

371+
## ipywidgets caches as a monkeypatch in exploration repo (2026-06-15)
372+
373+
Goal: ship the ipywidgets get_state caches without waiting on upstream. Confirmed our
374+
perf-widget-construction branch is a SUPERSET of Maarten's stalled PR #3602 (it has #3602's
375+
keys-cache + trait_to_json-cache, PLUS a static-default fast path, and deliberately OMITS the
376+
breaking comm-trait removal that blocked #3602 — so a monkeypatch is safe).
377+
378+
Built in a git worktree (exploration-wt-ipyw, branch perf/ipywidgets-cache-monkeypatch, commit
379+
9bf4b44b8, UNSIGNED — gpg couldn't prompt; local only, no PR):
380+
- leasing/src/shared/utils/ipywidgets_cache.py — default-on monkeypatch of Widget.get_state +
381+
per-class caches, with a per-class verify-on-first-use guard (falls back to stock per class on
382+
any byte mismatch).
383+
- leasing/tests/shared/test_ipywidgets_cache.py — 35-case offline byte-identical test (passes vs
384+
stock 8.1.8). Invariant: patched output == pre-install output, so meaningful in any venv.
385+
- wired install() into solara_app.py before install_perf_hooks (before any widget exists).
386+
387+
TWO REAL BUGS found only because reconfirmation was insisted on (first 'PASSED' was bogus —
388+
stock-vs-stock for disabled classes):
389+
1. Reentrancy: _verify_class constructs a probe -> __init__ -> open() -> get_state() re-entered
390+
verification for the same class -> class wrongly disabled (+ the RecursionError spew). Fixed
391+
with a _verifying sentinel.
392+
2. Two-instance compare: probes embedding layout/style sub-widgets have per-instance model ids
393+
that never match -> all core widgets disabled. Fixed by verifying on a single instance.
394+
395+
Delta reconfirmed (stock vs patched, identical-deps venv): widget create 1.33-1.45x; 200 v.Btn
396+
construction 24.5->18.7ms (1.31x); byte-identical across 14 widget types + add_traits; guard
397+
verifies all (none disabled).
398+
399+
IN-APP caveat (couldn't run real leasing app — needs secrets/DB): measured proxies only.
400+
- synthetic 1024-button solara render cycle: only ~3% faster (952->930ms min) because that bench
401+
is reacton-reconciler/comm-dominated; widget construction is a small fraction of it.
402+
- the leasing home page is get_state-DOMINATED (other agent profiled get_state at 41% of the
403+
cycle, cut 0.383->0.171s, render cycle -28% with the equivalent editable branch). The monkeypatch
404+
is byte-identical to that branch with the same microbench speedup, so the -28% should transfer.
405+
- DEFINITIVE in-app number needs the leasing agent: force-reinstall stock ipywidgets==8.1.8 in the
406+
leasing venv (it still has the editable branch, now redundant — and the monkeypatch would
407+
otherwise wrap the branch), run from the worktree, confirm with PROFILE=1.
408+
371409
## Stash (possible bugs / questionable behavior found along the way)
372410

373411
- pandas 3.0 re-render on equal DataFrame (see above) — env pin papering over it for now.

0 commit comments

Comments
 (0)