29
29
from ._cdn import SHINYWIDGETS_CDN_ONLY , SHINYWIDGETS_EXTENSION_WARNING
30
30
from ._comm import BufferType , OrphanedShinyComm , ShinyComm , ShinyCommManager
31
31
from ._dependencies import require_dependency
32
- from ._render_widget_base import has_current_context
32
+ from ._render_widget_base import WidgetRenderContext , has_current_context
33
33
from ._utils import package_dir
34
34
35
35
__all__ = (
@@ -60,8 +60,7 @@ def init_shiny_widget(w: Widget):
60
60
return
61
61
# Break out of any module-specific session. Otherwise, input.shinywidgets_comm_send
62
62
# will be some module-specific copy.
63
- while hasattr (session , "_parent" ):
64
- session = cast (Session , session ._parent ) # pyright: ignore
63
+ session = session .root_scope ()
65
64
66
65
# If this is the first time we've seen this session, initialize some things
67
66
if session not in SESSIONS :
@@ -148,12 +147,8 @@ def _open_shiny_comm():
148
147
149
148
_open_shiny_comm .destroy ()
150
149
151
- # If we're in a reactive context, close this widget when the context is invalidated
152
- # TODO: this should probably only be done in an output context, but I'm pretty sure
153
- # we don't have a decent way to determine that at the moment. In theory, doing this
154
- # in _any_ reactive context be problematic if you have an effect() that adds one
155
- # widget to another (i.e., a marker to a map) and want that marker to persist through
156
- # the next invalidation. The example provided in #174 is one such example.
150
+ # If the widget initialized in a reactive _output_ context, then cleanup the widget
151
+ # when the context gets invalidated.
157
152
if has_current_context ():
158
153
ctx = get_current_context ()
159
154
@@ -170,13 +165,7 @@ def on_close():
170
165
if id in WIDGET_INSTANCE_MAP :
171
166
del WIDGET_INSTANCE_MAP [id ]
172
167
173
- # This could be running in a shiny.reactive.ExtendedTask, in which case,
174
- # the context is a DenialContext. As a result, on_invalidate() will throw
175
- # (since reading/invalidating reactive sources isn't allowed in this context).
176
- # For now, we just don't clean up the widget in this case.
177
- # TODO: this line can likely be removed once we start closing iff we're in a
178
- # output context (see TODO comment above)
179
- if "DenialContext" != ctx .__class__ .__name__ :
168
+ if WidgetRenderContext .is_rendering_widget (session ):
180
169
ctx .on_invalidate (on_close )
181
170
182
171
# Keep track of what session this widget belongs to (so we can close it when the
0 commit comments