From 4ae217499cef5951cd4556fe86f0543d7d61d72b Mon Sep 17 00:00:00 2001 From: Austin Dickey Date: Wed, 19 Feb 2025 12:54:12 -0600 Subject: [PATCH] wip --- .../python_files/posit/positron/variables.py | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/extensions/positron-python/python_files/posit/positron/variables.py b/extensions/positron-python/python_files/posit/positron/variables.py index 4672a58e8f2..d56a953fe8e 100644 --- a/extensions/positron-python/python_files/posit/positron/variables.py +++ b/extensions/positron-python/python_files/posit/positron/variables.py @@ -196,11 +196,8 @@ def _send_update( variables = self._get_filtered_vars(unevaluated) filtered_unevaluated = _summarize_children(variables, MAX_ITEMS) - # Filter out hidden removed variables and encode access keys - hidden = self._get_user_ns_hidden() - filtered_removed = [ - encode_access_key(name) for name in sorted(removed) if name not in hidden - ] + # We don't have to filter out hidden removed variables, but make sure to encode access keys + filtered_removed = [encode_access_key(name) for name in sorted(removed)] if filtered_assigned or filtered_unevaluated or filtered_removed: msg = UpdateParams( @@ -275,7 +272,6 @@ def snapshot_user_ns(self) -> None: or contain many large mutable objects. """ ns = self._get_user_ns() - hidden = self._get_user_ns_hidden() # Variables which are immutable and thus can be compared by # reference @@ -298,7 +294,7 @@ def snapshot_user_ns(self) -> None: start = time.time() for key, value in ns.items(): - if key in hidden: + if self._is_hidden(key, value): continue inspector = get_inspector(value) @@ -349,7 +345,6 @@ def _compare_user_ns( return assigned, unevaluated, removed after = self._get_user_ns() - hidden = self._get_user_ns_hidden() snapshot = self._snapshot @@ -373,7 +368,7 @@ def _check_ns_subset(ns_subset, evaluated, are_different_func): for key, value in ns_subset.items(): try: - if key in hidden: + if self._is_hidden(key, value): continue if key not in after: @@ -403,7 +398,7 @@ def _check_ns_subset(ns_subset, evaluated, are_different_func): ) for key, value in after.items(): - if key in hidden: + if self._is_hidden(key, value): continue if key not in all_snapshot_keys: @@ -417,8 +412,17 @@ def _check_ns_subset(ns_subset, evaluated, are_different_func): def _get_user_ns(self) -> dict[str, Any]: return self.kernel.shell.user_ns or {} - def _get_user_ns_hidden(self) -> dict[str, Any]: - return self.kernel.shell.user_ns_hidden or {} + def _is_hidden(self, name: str, value: Any) -> bool: + """Is this variable a hidden kernel variable?. + + Most of the time the answer is just whether it's in the kernel-hidden user namespace. But + the _ symbol is commonly overridden by users/packages. So we don't want to hide it if its + value is different from the value in the hidden namespace. + """ + hidden = self.kernel.shell.user_ns_hidden or {} + if name == "_": + return name in hidden and value is hidden[name] + return name in hidden # -- Private Methods -- @@ -431,12 +435,14 @@ def _get_filtered_vars(self, variables: Mapping[str, Any] | None = None) -> dict A filtered dict of the variables, excluding hidden variables. If variables is None, the current user namespace in the environment is used. """ - hidden = self._get_user_ns_hidden() - if variables is None: variables = self._get_user_ns() + # This path only runs during initialization so we don't care about the values of the + # hidden variables + hidden = self.kernel.shell.user_ns_hidden or {} + return {key: value for key, value in variables.items() if key not in hidden} - return {key: value for key, value in variables.items() if key not in hidden} + return {key: value for key, value in variables.items() if not self._is_hidden(key, value)} def _find_var(self, path: Iterable[str]) -> tuple[bool, Any]: """