## 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: ```python 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: ```json { "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: ```json { "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: ```python 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 noise ``` are 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: ```python self._config self._client self._session self._state self._registry ``` Hiding 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: ```json { "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: ```json { "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: ```python vars(obj) obj.__dict__ ``` but this does not solve the variables panel noise directly. ## Environment * debugpy version: <!-- fill in --> * Python version: 3.12 * Editor / client: Zed / VS Code / other * OS: macos