Repository navigation
Distinguish protected fields from bound methods in variablePresentation #2023
Description
Problem
When using variablePresentation to reduce noise in the debugger variables view, protected: "hide" currently hides both protected/private fields and protected/private bound methods.
For example:
class Service:
def __init__(self):
self._config = {"timeout": 10}
self._client = object()
self._state = "ready"
def _build_url(self):
return "https://example.com"
def _validate(self):
return True
service = Service()
breakpoint()With a launch configuration like:
{
"variablePresentation": {
"special": "hide",
"function": "hide",
"class": "group",
"protected": "hide"
}
}the debugger hides _config, _client, and _state, even though these are object state fields that are usually useful during debugging.
If protected is changed to inline or group, the fields become visible again, but protected bound methods such as _build_url and _validate are also shown, adding noise to the variables view.
Expected behavior
It would be useful if variablePresentation could distinguish protected/private data fields from protected/private bound methods.
For example, something like:
{
"variablePresentation": {
"special": "hide",
"function": "hide",
"class": "group",
"protected": "group",
"protectedFunction": "hide",
"protectedField": "inline"
}
}or another equivalent naming scheme.
The goal is to support this behavior:
- Hide
__dunder__special variables. - Hide function/method variables.
- Hide or group class-related variables.
- Keep protected/private instance fields visible.
- Hide protected/private bound methods.
Actual behavior
Currently, protected appears to be based primarily on the variable name pattern, such as _xxx, rather than distinguishing whether the value is a field or a bound method.
As a result:
self._config # useful field, should remain visible
self._client # useful field, should remain visible
self._build_url # bound method, often noise
self._validate # bound method, often noiseare all affected by the same protected presentation option.
Why this matters
In Python applications, many important object state fields are intentionally named with a leading underscore:
self._config
self._client
self._session
self._state
self._registryHiding all protected variables makes object instances difficult to inspect because the useful state disappears.
On the other hand, keeping protected variables visible often exposes many bound methods, which makes the variables panel noisy.
This is especially noticeable in editors that rely directly on debugpy / DAP variable presentation, such as VS Code or Zed, where the debugger variables panel can become much noisier than IDEs that implement additional Python-specific variable filtering.
Suggested solution
Add more granular variablePresentation options for protected variables, such as:
{
"variablePresentation": {
"protectedField": "inline",
"protectedFunction": "hide"
}
}or allow function: "hide" to reliably apply to bound methods even when they are also classified as protected.
A possible classification rule could be:
- If the name starts with
_and the value is callable / method-like, treat it as a protected function/method. - If the name starts with
_and the value is not callable, treat it as a protected field.
Alternative workaround
Currently the closest workaround is:
{
"variablePresentation": {
"special": "hide",
"function": "hide",
"class": "group",
"protected": "group"
}
}However, this still groups useful fields together with protected methods and does not provide a clean object-state view.
Another workaround is to use watch expressions such as:
vars(obj)
obj.__dict__but this does not solve the variables panel noise directly.
Environment
- debugpy version:
- Python version: 3.12
- Editor / client: Zed / VS Code / other
- OS: macos
Activity
rchiodo commentedon May 12, 2026
Converting to a discussion item for up votes