Skip to content

Commit 1c8b48a

Browse files
committed
Close #188: skip cleanup when inside an ExtendedTask
1 parent ea041c5 commit 1c8b48a

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to shinywidgets will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [UNRELEASED] - 2025-04-04
9+
10+
* Constructing a widget inside of a `shiny.reactive.ExtendedTask()` no longer errors out. (#188)
11+
812
## [0.5.1] - 2025-01-30
913

1014
* Fixes 'AttributeError: object has no attribute "_repr_mimebundle_"'. (#184)

shinywidgets/_shinywidgets.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,14 @@ def on_close():
168168
if id in WIDGET_INSTANCE_MAP:
169169
del WIDGET_INSTANCE_MAP[id]
170170

171-
ctx.on_invalidate(on_close)
171+
# This could be running in a shiny.reactive.ExtendedTask, in which case,
172+
# the context is a DenialContext. As a result, on_invalidate() will throw
173+
# (since reading/invalidating reactive sources isn't allowed in this context).
174+
# For now, we just don't clean up the widget in this case.
175+
# TODO: this line can likely be removed once we start closing iff we're in a
176+
# output context (see TODO comment above)
177+
if "DenialContext" != ctx.__class__.__name__:
178+
ctx.on_invalidate(on_close)
172179

173180
# Keep track of what session this widget belongs to (so we can close it when the
174181
# session ends)
@@ -208,6 +215,7 @@ def on_close():
208215
# Reactivity
209216
# --------------------------------------
210217

218+
211219
def reactive_read(widget: Widget, names: Union[str, Sequence[str]]) -> Any:
212220
"""
213221
Reactively read a widget trait
@@ -273,6 +281,7 @@ def _():
273281

274282
return w
275283

284+
276285
# Previous versions of ipywidgets (< 8.0.5) had
277286
# `Widget.comm = Instance('ipykernel.comm.Comm')`
278287
# which meant we'd get a runtime error when setting `Widget.comm = ShinyComm()`.
@@ -300,6 +309,7 @@ def is_traitlet_instance(x: object) -> "TypeGuard[Instance[Any]]":
300309
return False
301310
return isinstance(x, Instance)
302311

312+
303313
# It doesn't, at the moment, seem feasible to establish a comm with statically rendered widgets,
304314
# and partially for this reason, it may not be sensible to provide an input-like API for them.
305315

0 commit comments

Comments
 (0)