@@ -154,39 +154,52 @@ def _get_scope_key(self):
154154 raise NotImplementedError
155155
156156 def subscribe (self , listener : Callable [[T ], None ], scope : Optional [ContextManager ] = None ):
157+ if scope is not None :
158+ warnings .warn ("scope argument should not be used, it was only for internal use" )
159+ del scope
157160 scope_id = self ._get_scope_key ()
158- self .listeners [scope_id ].add ((listener , scope ))
161+ rc = reacton .core .get_render_context (required = False )
162+ kernel = solara .server .kernel_context .get_current_context () if solara .server .kernel_context .has_current_context () else nullcontext ()
163+ context = Context (rc , kernel )
164+
165+ self .listeners [scope_id ].add ((listener , context ))
159166
160167 def cleanup ():
161- self .listeners [scope_id ].remove ((listener , scope ))
168+ self .listeners [scope_id ].remove ((listener , context ))
162169
163170 return cleanup
164171
165172 def subscribe_change (self , listener : Callable [[T , T ], None ], scope : Optional [ContextManager ] = None ):
173+ if scope is not None :
174+ warnings .warn ("scope argument should not be used, it was only for internal use" )
175+ del scope
166176 scope_id = self ._get_scope_key ()
167- self .listeners2 [scope_id ].add ((listener , scope ))
177+ rc = reacton .core .get_render_context (required = False )
178+ kernel = solara .server .kernel_context .get_current_context () if solara .server .kernel_context .has_current_context () else nullcontext ()
179+ context = Context (rc , kernel )
180+ self .listeners2 [scope_id ].add ((listener , context ))
168181
169182 def cleanup ():
170- self .listeners2 [scope_id ].remove ((listener , scope ))
183+ self .listeners2 [scope_id ].remove ((listener , context ))
171184
172185 return cleanup
173186
174187 def fire (self , new : T , old : T ):
175188 logger .info ("value change from %s to %s, will fire events" , old , new )
176189 scope_id = self ._get_scope_key ()
177- scopes = set ()
178- for listener , scope in self .listeners [scope_id ].copy ():
179- scopes .add (scope )
180- for listener2 , scope in self .listeners2 [scope_id ].copy ():
181- scopes .add (scope )
182- if scopes :
183- for scope in scopes :
184- with scope or nullcontext ():
185- for listener , scope_listener in self .listeners [scope_id ].copy ():
186- if scope == scope_listener :
190+ contexts = set ()
191+ for listener , context in self .listeners [scope_id ].copy ():
192+ contexts .add (context )
193+ for listener2 , context in self .listeners2 [scope_id ].copy ():
194+ contexts .add (context )
195+ if contexts :
196+ for context in contexts :
197+ with context or nullcontext ():
198+ for listener , context_listener in self .listeners [scope_id ].copy ():
199+ if context == context_listener :
187200 listener (new )
188- for listener2 , scope_listener in self .listeners2 [scope_id ].copy ():
189- if scope == scope_listener :
201+ for listener2 , context_listener in self .listeners2 [scope_id ].copy ():
202+ if context == context_listener :
190203 listener2 (new , old )
191204
192205 def update (self , _f = None , ** kwargs ):
@@ -847,7 +860,7 @@ class AutoSubscribeContextManagerBase:
847860 def __init__ (self ):
848861 self .subscribed = {}
849862
850- def update_subscribers (self , change_handler , scope = None ):
863+ def update_subscribers (self , change_handler ):
851864 assert self .reactive_used is not None
852865 reactive_used = self .reactive_used
853866 # remove subfields for which we already listen to it's root reactive value
@@ -863,7 +876,7 @@ def update_subscribers(self, change_handler, scope=None):
863876
864877 for reactive in added :
865878 if reactive not in self .subscribed :
866- unsubscribe = reactive .subscribe_change (change_handler , scope = scope )
879+ unsubscribe = reactive .subscribe_change (change_handler )
867880 self .subscribed [reactive ] = unsubscribe
868881 for reactive in removed :
869882 unsubscribe = self .subscribed [reactive ]
@@ -892,12 +905,16 @@ def __init__(self, render_context, kernel_context):
892905 self .kernel_context = kernel_context
893906
894907 def __enter__ (self ):
895- self .render_context .__enter__ ()
908+ if self .render_context is not None :
909+ self .render_context .__enter__ ()
896910 self .kernel_context .__enter__ ()
897911
898912 def __exit__ (self , exc_type , exc_val , exc_tb ):
899- # this will trigger a render
900- res1 = self .render_context .__exit__ (exc_type , exc_val , exc_tb )
913+ if self .render_context is not None :
914+ # this will trigger a render
915+ res1 = self .render_context .__exit__ (exc_type , exc_val , exc_tb )
916+ else :
917+ res1 = None
901918 # pop the current context from the stack
902919 res2 = self .kernel_context .__exit__ (exc_type , exc_val , exc_tb )
903920 return res1 or res2
@@ -929,9 +946,7 @@ def force_update(new_value, old_value):
929946 super ().__enter__ ()
930947
931948 def update_subscribers ():
932- rc = reacton .core .get_render_context (required = True )
933- kernel = solara .server .kernel_context .get_current_context () if solara .server .kernel_context .has_current_context () else nullcontext ()
934- self .update_subscribers (force_update , scope = Context (rc , kernel ))
949+ self .update_subscribers (force_update )
935950
936951 solara .use_effect (update_subscribers , None )
937952
0 commit comments