2929import urwid
3030import inspect
3131import warnings
32+ import weakref
3233
3334from abc import ABC , abstractmethod
3435from collections .abc import Callable , Sized
@@ -170,11 +171,14 @@ def length(cls, mapping):
170171# {{{ data
171172
172173class FrameVarInfo :
173- def __init__ (self ):
174+ def __init__ (self , global_watch_iinfo ):
174175 self .id_path_to_iinfo = {}
175176 self .watches = []
177+ self .global_watch_iinfo = global_watch_iinfo
176178
177179 def get_inspect_info (self , id_path , read_only ):
180+ if id_path in self .global_watch_iinfo :
181+ return self .global_watch_iinfo [id_path ]
178182 if read_only :
179183 return self .id_path_to_iinfo .get (
180184 id_path , InspectInfo ())
@@ -206,6 +210,9 @@ def __init__(self, expression="", scope="local", method="expression"):
206210 self .method = method
207211 self ._value = self .NOT_EVALUATED
208212
213+ def id_path (self ):
214+ return str (id (self ))
215+
209216 def eval (self , frame_globals , frame_locals ):
210217 if (self .method == "expression"
211218 or self ._value is self .NOT_EVALUATED ):
@@ -778,8 +785,9 @@ def make_var_view(global_watches, frame_var_info, frame_globals, frame_locals):
778785 for watch_expr in chain (global_watches , frame_var_info .watches ):
779786 value = watch_expr .eval (frame_globals , frame_locals )
780787 label = watch_expr .label (value , frame_globals , frame_locals )
788+ id_path = watch_expr .id_path ()
781789 WatchValueWalker (frame_var_info , watch_widget_list , watch_expr ) \
782- .walk_value (None , label , value )
790+ .walk_value (None , label , value , id_path )
783791
784792 if "__return__" in vars :
785793 ret_walker .walk_value (None , "Return" , frame_locals ["__return__" ],
@@ -808,14 +816,18 @@ def __init__(self):
808816 self .frame_var_info = {}
809817 self .global_watches = []
810818
819+ # In order to have the global watch expression presented the same way in
820+ # all frames, we need persistent storage for global InspectInfo.
821+ self .global_watch_iinfo = {}
822+
811823 def get_frame_var_info (self , read_only , ssid = None ):
812824 if ssid is None :
813825 # self.debugger set by subclass
814826 ssid = self .debugger .get_stack_situation_id () # noqa: E501 # pylint: disable=no-member
815827 if read_only :
816- return self .frame_var_info .get (ssid , FrameVarInfo ())
828+ return self .frame_var_info .get (ssid , FrameVarInfo (self . global_watch_iinfo ))
817829 else :
818- return self .frame_var_info .setdefault (ssid , FrameVarInfo ())
830+ return self .frame_var_info .setdefault (ssid , FrameVarInfo (self . global_watch_iinfo ))
819831
820832 def add_watch (self , watch_expr : WatchExpression , fvi = None ):
821833 if watch_expr .scope == "local" :
@@ -824,6 +836,7 @@ def add_watch(self, watch_expr: WatchExpression, fvi=None):
824836 fvi .watches .append (watch_expr )
825837 elif watch_expr .scope == "global" :
826838 self .global_watches .append (watch_expr )
839+ self .global_watch_iinfo [watch_expr .id_path ()] = InspectInfo ()
827840
828841 def delete_watch (self , watch_expr : WatchExpression , fvi = None ):
829842 if fvi is None :
@@ -836,6 +849,7 @@ def delete_watch(self, watch_expr: WatchExpression, fvi=None):
836849 pass
837850 try :
838851 self .global_watches .remove (watch_expr )
852+ self .global_watch_iinfo .pop (watch_expr .id_path ())
839853 except ValueError :
840854 pass
841855
0 commit comments