Skip to content

Commit

Permalink
Persist InspectInfo for global watches
Browse files Browse the repository at this point in the history
  • Loading branch information
mvanderkamp committed Jul 30, 2022
1 parent eb4a822 commit d9dca1e
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions pudb/var_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import urwid
import inspect
import warnings
import weakref

from abc import ABC, abstractmethod
from collections.abc import Callable, Sized
Expand Down Expand Up @@ -170,11 +171,14 @@ def length(cls, mapping):
# {{{ data

class FrameVarInfo:
def __init__(self):
def __init__(self, global_watch_iinfo):
self.id_path_to_iinfo = {}
self.watches = []
self.global_watch_iinfo = global_watch_iinfo

def get_inspect_info(self, id_path, read_only):
if id_path in self.global_watch_iinfo:
return self.global_watch_iinfo[id_path]
if read_only:
return self.id_path_to_iinfo.get(
id_path, InspectInfo())
Expand Down Expand Up @@ -206,6 +210,9 @@ def __init__(self, expression="", scope="local", method="expression"):
self.method = method
self._value = self.NOT_EVALUATED

def id_path(self):
return str(id(self))

def eval(self, frame_globals, frame_locals):
if (self.method == "expression"
or self._value is self.NOT_EVALUATED):
Expand Down Expand Up @@ -778,8 +785,9 @@ def make_var_view(global_watches, frame_var_info, frame_globals, frame_locals):
for watch_expr in chain(global_watches, frame_var_info.watches):
value = watch_expr.eval(frame_globals, frame_locals)
label = watch_expr.label(value, frame_globals, frame_locals)
id_path = watch_expr.id_path()
WatchValueWalker(frame_var_info, watch_widget_list, watch_expr) \
.walk_value(None, label, value)
.walk_value(None, label, value, id_path)

if "__return__" in vars:
ret_walker.walk_value(None, "Return", frame_locals["__return__"],
Expand Down Expand Up @@ -808,14 +816,18 @@ def __init__(self):
self.frame_var_info = {}
self.global_watches = []

# In order to have the global watch expression presented the same way in
# all frames, we need persistent storage for global InspectInfo.
self.global_watch_iinfo = {}

def get_frame_var_info(self, read_only, ssid=None):
if ssid is None:
# self.debugger set by subclass
ssid = self.debugger.get_stack_situation_id() # noqa: E501 # pylint: disable=no-member
if read_only:
return self.frame_var_info.get(ssid, FrameVarInfo())
return self.frame_var_info.get(ssid, FrameVarInfo(self.global_watch_iinfo))
else:
return self.frame_var_info.setdefault(ssid, FrameVarInfo())
return self.frame_var_info.setdefault(ssid, FrameVarInfo(self.global_watch_iinfo))

def add_watch(self, watch_expr: WatchExpression, fvi=None):
if watch_expr.scope == "local":
Expand All @@ -824,6 +836,7 @@ def add_watch(self, watch_expr: WatchExpression, fvi=None):
fvi.watches.append(watch_expr)
elif watch_expr.scope == "global":
self.global_watches.append(watch_expr)
self.global_watch_iinfo[watch_expr.id_path()] = InspectInfo()

def delete_watch(self, watch_expr: WatchExpression, fvi=None):
if fvi is None:
Expand All @@ -836,6 +849,7 @@ def delete_watch(self, watch_expr: WatchExpression, fvi=None):
pass
try:
self.global_watches.remove(watch_expr)
self.global_watch_iinfo.pop(watch_expr.id_path())
except ValueError:
pass

Expand Down

0 comments on commit d9dca1e

Please sign in to comment.