Skip to content

Commit 05e5f74

Browse files
committed
widgets: fix bug when changing buffers, which would make other buffers get "messed up/deleted"
1 parent 536a0e8 commit 05e5f74

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

src/packages/frontend/jupyter/widgets/manager2.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ export class WidgetManager {
6363
}
6464

6565
private initAllModels = async () => {
66+
// TODO: this can do a lot that makes no sense
67+
// due to lack of garbage collection and any link to what is actually
68+
// in the notebook.
69+
/*
70+
With this disabled, this breaks for RTC or close/open:
71+
72+
from ipywidgets import VBox, jsdlink, IntSlider
73+
s1 = IntSlider(max=200, value=100); s2 = IntSlider(value=40)
74+
jsdlink((s1, 'value'), (s2, 'max'))
75+
VBox([s1, s2])
76+
*/
77+
// log("initAllModels: temporarily disabled"); return;
78+
6679
if (this.ipywidgets_state.get_state() == "init") {
6780
await once(this.ipywidgets_state, "ready");
6881
}
@@ -268,7 +281,7 @@ export class WidgetManager {
268281
const change: { [key: string]: any } = {};
269282
for (let i = 0; i < buffer_paths.length; i++) {
270283
const key = buffer_paths[i][0];
271-
setInObject(state, buffer_paths[i], buffers[i]);
284+
setInObject(state, buffer_paths[i], new DataView(buffers[i]));
272285
change[key] = state[key];
273286
}
274287
if (len(change) > 0) {
@@ -632,7 +645,7 @@ class Environment implements WidgetEnvironment {
632645
if (buffers.length > 0) {
633646
for (let i = 0; i < buffer_paths.length; i++) {
634647
const buffer = buffers[i];
635-
setInObject(state, buffer_paths[i], buffer);
648+
setInObject(state, buffer_paths[i], new DataView(buffer));
636649
}
637650
}
638651

src/packages/sync/editor/generic/ipywidgets-state.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,25 @@ export class IpywidgetsState extends EventEmitter {
375375
dbg("value -- after", { merged: data });
376376
defaultMerge = "none";
377377
} else if (type == "buffers") {
378-
// we keep around the buffers that were
379-
// already set, but overwrite
380-
// when they change.
381-
defaultMerge = "shallow";
378+
// it's critical to not throw away existing buffers when
379+
// new ones come or current ones change. With shallow merge,
380+
// the existing ones go away, which is very broken, e.g.,
381+
// see this with this example:
382+
/*
383+
import bqplot.pyplot as plt
384+
import numpy as np
385+
x, y = np.random.rand(2, 10)
386+
fig = plt.figure(animation_duration=3000)
387+
scat = plt.scatter(x=x, y=y)
388+
fig
389+
---
390+
scat.x, scat.y = np.random.rand(2, 50)
391+
392+
# now close and open it, and it breaks with shallow merge,
393+
# since the second cell caused the opacity buffer to be
394+
# deleted, which breaks everything.
395+
*/
396+
defaultMerge = "deep";
382397
} else if (type == "message") {
383398
defaultMerge = "none";
384399
} else {

0 commit comments

Comments
 (0)