Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,11 @@
"title": "DataScience.latestExtension",
"category": "Python"
},
{
"command": "python.datascience.showDataViewer",
"title": "%python.command.python.datascience.showDataViewer.title%",
"category": "Python"
},
{
"command": "python.analysis.restartLanguageServer",
"title": "%python.command.python.analysis.restartLanguageServer.title%",
Expand Down Expand Up @@ -1655,6 +1660,13 @@
"when": "view == python_tests && viewItem == suite && !busyTests",
"group": "inline@0"
}
],
"debug/variables/context": [
{
"command": "python.datascience.showDataViewer",
"group": "1_view",
"when": "debugProtocolVariableMenuContext == 'viewableInDataViewer'"
}
]
},
"breakpoints": [
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"Datascience.currentlySelectedJupyterInterpreterForPlaceholder": "current: {0}",
"python.command.python.analysis.clearCache.title": "Clear Module Analysis Cache",
"python.command.python.analysis.restartLanguageServer.title": "Restart Language Server",
"python.command.python.datascience.showDataViewer.title": "View Value in Data Viewer",
"python.snippet.launch.standard.label": "Python: Current File",
"python.snippet.launch.module.label": "Python: Module",
"python.snippet.launch.module.default": "enter-your-module-name",
Expand Down
46 changes: 27 additions & 19 deletions src/client/datascience/jupyter/debuggerVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
INotebook
} from '../types';

const DataViewableTypes: Set<string> = new Set<string>(['DataFrame', 'list', 'dict', 'ndarray', 'Series']);
const DataViewableTypes: Set<string> = new Set<string>(['DataFrame', 'list', 'dict', 'ndarray', 'Series', 'Tensor']);
const KnownExcludedVariables = new Set<string>(['In', 'Out', 'exit', 'quit']);

@injectable()
Expand Down Expand Up @@ -274,24 +274,32 @@ export class DebuggerVariables implements IConditionalJupyterVariables, DebugAda
? this.configService.getSettings().datascience.variableExplorerExclude?.split(';')
: [];

const allowedVariables = variablesResponse.body.variables.filter((v) => {
if (!v.name || !v.type || !v.value) {
return false;
}
if (exclusionList && exclusionList.includes(v.type)) {
return false;
}
if (v.name.startsWith('_')) {
return false;
}
if (KnownExcludedVariables.has(v.name)) {
return false;
}
if (v.type === 'NoneType') {
return false;
}
return true;
});
const allowedVariables = variablesResponse.body.variables
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to get in touch with Debugger team about this.
Its something they might find useful or be aware of (the fact that we're adding this).
Personally I'd prefer if all of this was done in debugpy and we just hooked into some message or the like (e.g. we could use capabilities or other flags & use custom messages)
@int19h @karthiknadig /cc

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be hard to make it quite as flexible as client-side filtering. If we hardcode the filters, debugpy would have to be touched every time this logic needs revising. And if we don't hardcode them, then the protocol would need to be expressive enough to express all those conditions, which would also make the implementation expensive.

I think client-side filtering is the better option here, unless there are important perf reasons to exclude some variables.

Copy link
Copy Markdown
Author

@joyceerhl joyceerhl Oct 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in the interest of clarity (even though I think the conclusion is the same), we're not asking for filtering logic in debugpy. What we're after is debugpy setting the __vscodeVariableMenuContext property on DebugProtocol.Variables before they are sent over to VS Code, several lines down from this spot: https://github.com/microsoft/vscode-python/pull/14269/files#diff-d8fc76e8c5b19f7c5df2b4282409e727R297-R300

As background for anyone unfamiliar with why we need this, the reason we need this property is so that we can make use of the new contribution point for the variable context menu introduced in the August release. VS Code uses the hidden __vscodeVariableMenuContext property to set a per-variable debugProtocolVariableMenuContext key with the same contents (details). Extensions can then use the debugProtocolVariableMenuContext key in when clauses that specify whether a given context menu item with an associated command should be displayed for a given variable.

.filter((v) => {
if (!v.name || !v.type || !v.value) {
return false;
}
if (exclusionList && exclusionList.includes(v.type)) {
return false;
}
if (v.name.startsWith('_')) {
return false;
}
if (KnownExcludedVariables.has(v.name)) {
return false;
}
if (v.type === 'NoneType') {
return false;
}
return true;
})
.map((v) => {
if (v.type && DataViewableTypes.has(v.type)) {
// tslint:disable-next-line: no-any
(v as any).__vscodeVariableMenuContext = 'viewableInDataViewer';
}
return v;
});

this.lastKnownVariables = allowedVariables.map((v) => {
return {
Expand Down