Skip to content

Plot.cleanup() severs other plots' subscribers on shared streams: owner filter defeated by _WeakSubscriber.__bool__ #6988

Description

@SimonHeybrock

Description

DimensionedPlot.cleanup is documented and written to remove only the stream subscribers owned by the plot being cleaned (get_method_owner(subscriber) not in plots). Since subscribers became _WeakSubscriber wrappers (the weak-subscriber work around #6875), that owner filter is dead code: the wrapper's __bool__ returns False for any param-method subscriber — which every plot-refresh subscriber is — so the leading subscriber and (...) in the filter short-circuits and cleanup removes every weakly-wrapped plot-refresh subscriber on the touched streams, including those of other live plots. A surviving view of the same object silently stops updating.

Complete, minimal, self-contained example

import holoviews as hv
hv.extension('bokeh')

pipe = hv.streams.Pipe(data=[1, 2, 3])
dmap = hv.DynamicMap(lambda data: hv.Curve(data), streams=[pipe])
r = hv.renderer('bokeh')
plot1 = r.get_plot(dmap)
plot2 = r.get_plot(dmap)
print(len(pipe.subscribers))  # 2

plot1.cleanup()
print(len(pipe.subscribers))  # 0  <- plot2's subscriber removed as well

pipe.send([8, 9])
print(len(plot2.current_frame.dimension_values(0)))  # unchanged: plot2 is dead

Versions: holoviews 1.23.1 (behavior unchanged on current main), bokeh 3.9.2, Python 3.12.

If treating weak param-method subscribers as always-reapable is intentional, the docstring and owner filter are misleading and the sharing hazard above deserves a note; if not, _WeakSubscriber could expose its referent so the owner check works again. Can submit a PR once maintainers indicate which reading is intended.

Context: hit while working around holoviz/panel#8710, where explicit plot.cleanup() is the app-side fix (scipp/esslivedata#1224) — its correctness currently relies on cleaning up before the surviving plot renders.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions