Skip to content

Commit fe67dc3

Browse files
authored
Merge pull request #5406 from Microsoft/rchiodo/release_update
Cherry-pick two more changes into release
2 parents 09e4050 + 73a6df2 commit fe67dc3

13 files changed

Lines changed: 122 additions & 54 deletions

File tree

news/2 Fixes/5278.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Filtered rows shows 'fetching' instead of No rows.

news/2 Fixes/5395.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Multi-dimensional arrays don't open in the data viewer.

package.nls.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
"python.command.python.datascience.undocells.title": "Undo last Python Interactive action",
5050
"python.command.python.datascience.redocells.title": "Redo last Python Interactive action",
5151
"python.command.python.datascience.removeallcells.title": "Delete all Python Interactive cells",
52-
"python.command.python.datascience.interruptkernel.title": "Interrupt iPython Kernel",
53-
"python.command.python.datascience.restartkernel.title": "Restart iPython Kernel",
52+
"python.command.python.datascience.interruptkernel.title": "Interrupt IPython Kernel",
53+
"python.command.python.datascience.restartkernel.title": "Restart IPython Kernel",
5454
"python.command.python.datascience.expandallcells.title": "Expand all Python Interactive cells",
5555
"python.command.python.datascience.collapseallcells.title": "Collapse all Python Interactive cells",
5656
"python.snippet.launch.standard.label": "Python: Current File",
@@ -100,7 +100,7 @@
100100
"Interpreters.LoadingInterpreters": "Loading Python Interpreters",
101101
"Common.doNotShowAgain": "Do not show again",
102102
"Interpreters.environmentPromptMessage": "We noticed a new virtual environment has been created. Do you want to select it for the workspace folder?",
103-
"DataScience.restartKernelMessage": "Do you want to restart the iPython kernel? All variables will be lost.",
103+
"DataScience.restartKernelMessage": "Do you want to restart the IPython kernel? All variables will be lost.",
104104
"DataScience.restartKernelMessageYes": "Restart",
105105
"DataScience.restartKernelMessageNo": "Cancel",
106106
"DataScience.restartingKernelFailed": "Kernel restart failed. Jupyter server is hung. Please reload VS Code.",
@@ -111,12 +111,12 @@
111111
"InteractiveShiftEnterBanner.bannerMessage": "Would you like to run code in the 'Python Interactive' window (an IPython console) for 'shift-enter'? Select 'No' to continue to run code in the Python Terminal. This can be changed later in settings.",
112112
"InteractiveShiftEnterBanner.bannerLabelYes": "Yes",
113113
"InteractiveShiftEnterBanner.bannerLabelNo": "No",
114-
"DataScience.restartingKernelStatus": "Restarting iPython Kernel",
114+
"DataScience.restartingKernelStatus": "Restarting IPython Kernel",
115115
"DataScience.executingCode": "Executing Cell",
116116
"DataScience.collapseAll": "Collapse all cell inputs",
117117
"DataScience.expandAll": "Expand all cell inputs",
118118
"DataScience.export": "Export as Jupyter Notebook",
119-
"DataScience.restartServer": "Restart iPython Kernel",
119+
"DataScience.restartServer": "Restart IPython Kernel",
120120
"DataScience.undo": "Undo",
121121
"DataScience.redo": "Redo",
122122
"DataScience.clearAll": "Remove All Cells",
@@ -161,13 +161,13 @@
161161
"diagnostics.yesUpdateLaunch": "Yes, update launch.json",
162162
"diagnostics.bannerLabelNo": "No, I will do it later",
163163
"diagnostics.invalidTestSettings": "Your settings needs to be updated to change the setting \"python.unitTest.\" to \"python.testing.\", otherwise testing Python code using the extension may not work. Would you like to automatically update your settings now?",
164-
"DataScience.interruptKernel": "Interrupt iPython Kernel",
164+
"DataScience.interruptKernel": "Interrupt IPython Kernel",
165165
"DataScience.exportingFormat": "Exporting {0}",
166166
"DataScience.exportCancel": "Cancel",
167167
"Common.canceled": "Canceled",
168168
"DataScience.importChangeDirectoryComment": "#%% Change working directory from the workspace root to the ipynb file location. Turn this addition off with the DataScience.changeDirOnImportExport setting",
169169
"DataScience.exportChangeDirectoryComment": "# Change directory to VSCode workspace root so that relative path loads work correctly. Turn this addition off with the DataScience.changeDirOnImportExport setting",
170-
"DataScience.interruptKernelStatus": "Interrupting iPython Kernel",
170+
"DataScience.interruptKernelStatus": "Interrupting IPython Kernel",
171171
"DataScience.restartKernelAfterInterruptMessage": "Interrupting the kernel timed out. Do you want to restart the kernel instead? All variables will be lost.",
172172
"DataScience.pythonInterruptFailedHeader": "Keyboard interrupt crashed the kernel. Kernel restarted.",
173173
"DataScience.sysInfoURILabel": "Jupyter Server URI: ",
@@ -226,7 +226,8 @@
226226
"DataScience.dataExplorerInvalidVariableFormat": "'{0}' is not an active variable.",
227227
"DataScience.jupyterGetVariablesExecutionError": "Failure during variable extraction:\r\n{0}",
228228
"DataScience.loadingMessage": "loading ...",
229-
"DataScience.noRowsInDataViewer": "Fetching data ...",
229+
"DataScience.fetchingDataViewer": "Fetching data ...",
230+
"DataScience.noRowsInDataViewer": "No rows match current filter",
230231
"DataScience.pandasTooOldForViewingFormat": "Python package 'pandas' is version {0}. Version 0.20 or greater is required for viewing data.",
231232
"DataScience.pandasRequiredForViewing": "Python package 'pandas' is required for viewing data.",
232233
"DataScience.valuesColumn": "values",

pythonFiles/datascience/getJupyterVariableDataFrameInfo.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
_VSCODE_columnTypes = list(_VSCODE_evalResult.dtypes)
3636
_VSCODE_columnNames = list(_VSCODE_evalResult)
3737
elif _VSCODE_targetVariable['type'] == 'ndarray':
38-
_VSCODE_evalResult = _VSCODE_pd.Series(_VSCODE_evalResult)
39-
_VSCODE_evalResult = _VSCODE_pd.Series.to_frame(_VSCODE_evalResult)
38+
_VSCODE_evalResult = _VSCODE_pd.DataFrame(_VSCODE_evalResult)
4039
_VSCODE_columnTypes = list(_VSCODE_evalResult.dtypes)
4140
_VSCODE_columnNames = list(_VSCODE_evalResult)
4241
elif _VSCODE_targetVariable['type'] == 'DataFrame':

pythonFiles/datascience/getJupyterVariableDataFrameRows.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
_VSCODE_evalResult = _VSCODE_pd.Series(_VSCODE_evalResult)
2424
_VSCODE_df = _VSCODE_pd.Series.to_frame(_VSCODE_evalResult)
2525
elif _VSCODE_targetVariable['type'] == 'ndarray':
26-
_VSCODE_evalResult = _VSCODE_pd.Series(_VSCODE_evalResult)
27-
_VSCODE_df = _VSCODE_pd.Series.to_frame(_VSCODE_evalResult)
26+
_VSCODE_df = _VSCODE_pd.DataFrame(_VSCODE_evalResult)
2827
# If not a known type, then just let pandas handle it.
2928
elif not (hasattr(_VSCODE_df, 'iloc')):
3029
_VSCODE_df = _VSCODE_pd.DataFrame(_VSCODE_evalResult)

pythonFiles/tests/ipython/test_variables.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ def test_dataframe_info(capsys):
4949
ls = list([10, 20, 30, 40])
5050
df = pd.DataFrame(ls)
5151
se = pd.Series(ls)
52-
np = np.array(ls)
52+
np1 = np.array(ls)
53+
np2 = np.array([[1, 2, 3], [4, 5, 6]])
5354
obj = {}
5455
''')
5556
vars = get_variables(capsys)
5657
df = get_variable_value(vars, 'df', capsys)
5758
se = get_variable_value(vars, 'se', capsys)
58-
np = get_variable_value(vars, 'np', capsys)
59+
np = get_variable_value(vars, 'np1', capsys)
60+
np2 = get_variable_value(vars, 'np2', capsys)
5961
ls = get_variable_value(vars, 'ls', capsys)
6062
obj = get_variable_value(vars, 'obj', capsys)
6163
assert df
@@ -65,8 +67,9 @@ def test_dataframe_info(capsys):
6567
assert obj
6668
verify_dataframe_info(vars, 'df', capsys, True)
6769
verify_dataframe_info(vars, 'se', capsys, True)
68-
verify_dataframe_info(vars, 'np', capsys, True)
70+
verify_dataframe_info(vars, 'np1', capsys, True)
6971
verify_dataframe_info(vars, 'ls', capsys, True)
72+
verify_dataframe_info(vars, 'np2', capsys, True)
7073
verify_dataframe_info(vars, 'obj', capsys, False)
7174

7275
def verify_dataframe_info(vars, name, capsys, hasInfo):
@@ -96,6 +99,27 @@ def test_dataframe_rows(capsys):
9699
rows = get_data_frame_rows(info, 100, 200, capsys)
97100
assert rows
98101
assert rows['data'][0]['+h2'] == 'Fy3 W[pMT['
102+
get_ipython().run_cell('''
103+
import pandas as pd
104+
import numpy as np
105+
ls = list([10, 20, 30, 40])
106+
df = pd.DataFrame(ls)
107+
se = pd.Series(ls)
108+
np1 = np.array(ls)
109+
np2 = np.array([[1, 2, 3], [4, 5, 6]])
110+
obj = {}
111+
''')
112+
vars = get_variables(capsys)
113+
np2 = get_variable_value(vars, 'np2', capsys)
114+
assert np2
115+
info = get_data_frame_info(vars, 'np2', capsys)
116+
assert 'rowCount' in info
117+
assert info['rowCount'] == 2
118+
rows = get_data_frame_rows(info, 0, 2, capsys)
119+
assert rows
120+
assert rows['data'][0]
121+
122+
99123

100124

101125

src/client/common/utils/localize.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ export namespace DataScience {
160160
export const pythonInteractiveCreateFailed = localize('DataScience.pythonInteractiveCreateFailed', 'Failure to create a \'Python Interactive\' window. Try reinstalling the Python extension.');
161161
export const jupyterGetVariablesExecutionError = localize('DataScience.jupyterGetVariablesExecutionError', 'Failure during variable extraction: \r\n{0}');
162162
export const loadingMessage = localize('DataScience.loadingMessage', 'loading ...');
163-
export const noRowsInDataViewer = localize('DataScience.noRowsInDataViewer', 'Fetching data ...');
163+
export const fetchingDataViewer = localize('DataScience.fetchingDataViewer', 'Fetching data ...');
164+
export const noRowsInDataViewer = localize('DataScience.noRowsInDataViewer', 'No rows match current filter');
164165
export const pandasTooOldForViewingFormat = localize('DataScience.pandasTooOldForViewingFormat', 'Python package \'pandas\' is version {0}. Version 0.20 or greater is required for viewing data.');
165166
export const pandasRequiredForViewing = localize('DataScience.pandasRequiredForViewing', 'Python package \'pandas\' is required for viewing data.');
166167
export const valuesColumn = localize('DataScience.valuesColumn', 'values');

src/client/datascience/editor-integration/decorator.ts

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,16 @@ import { generateCellRanges } from '../cellFactory';
1313
@injectable()
1414
export class Decorator implements IExtensionActivationService, IDisposable {
1515

16-
private activeCellType: vscode.TextEditorDecorationType;
17-
private cellSeparatorType: vscode.TextEditorDecorationType;
16+
private activeCellTop: vscode.TextEditorDecorationType | undefined;
17+
private activeCellBottom: vscode.TextEditorDecorationType | undefined;
18+
private cellSeparatorType: vscode.TextEditorDecorationType | undefined;
1819
private timer: NodeJS.Timer | undefined;
1920

2021
constructor(@inject(IDocumentManager) private documentManager: IDocumentManager,
2122
@inject(IDisposableRegistry) disposables: IDisposableRegistry,
2223
@inject(IConfigurationService) private configuration: IConfigurationService)
2324
{
24-
this.activeCellType = this.documentManager.createTextEditorDecorationType({
25-
backgroundColor: new vscode.ThemeColor('peekViewEditor.background'),
26-
isWholeLine: true
27-
});
28-
this.cellSeparatorType = this.documentManager.createTextEditorDecorationType({
29-
borderColor: new vscode.ThemeColor('peekViewEditor.background'),
30-
borderWidth: '1px 0px 0px 0px',
31-
borderStyle: 'solid',
32-
isWholeLine: true
33-
});
25+
this.computeDecorations();
3426
disposables.push(this);
3527
disposables.push(this.configuration.getSettings().onDidChange(this.settingsChanged, this));
3628
disposables.push(this.documentManager.onDidChangeActiveTextEditor(this.changedEditor, this));
@@ -80,22 +72,48 @@ export class Decorator implements IExtensionActivationService, IDisposable {
8072
this.timer = setTimeout(() => this.update(editor), 100);
8173
}
8274

75+
private computeDecorations() {
76+
this.activeCellTop = this.documentManager.createTextEditorDecorationType({
77+
borderColor: new vscode.ThemeColor('peekView.border'),
78+
borderWidth: '2px 0px 0px 0px',
79+
borderStyle: 'solid',
80+
isWholeLine: true
81+
});
82+
this.activeCellBottom = this.documentManager.createTextEditorDecorationType({
83+
borderColor: new vscode.ThemeColor('peekView.border'),
84+
borderWidth: '0px 0px 1px 0px',
85+
borderStyle: 'solid',
86+
isWholeLine: true
87+
});
88+
this.cellSeparatorType = this.documentManager.createTextEditorDecorationType({
89+
borderColor: new vscode.ThemeColor('editor.lineHighlightBorder'),
90+
borderWidth: '1px 0px 0px 0px',
91+
borderStyle: 'solid',
92+
isWholeLine: true
93+
});
94+
}
95+
8396
private update(editor: vscode.TextEditor | undefined) {
84-
if (editor && editor.document && editor.document.languageId === PYTHON_LANGUAGE) {
97+
if (editor && editor.document && editor.document.languageId === PYTHON_LANGUAGE &&
98+
this.activeCellTop && this.cellSeparatorType && this.activeCellBottom) {
8599
const settings = this.configuration.getSettings().datascience;
86100
if (settings.decorateCells && settings.enabled) {
87101
// Find all of the cells
88102
const cells = generateCellRanges(editor.document, this.configuration.getSettings().datascience);
89103

90104
// Find the range for our active cell.
91-
const activeRanges = cells.map(c => c.range).filter(r => r.contains(editor.selection.anchor));
92-
editor.setDecorations(this.activeCellType, activeRanges);
105+
const currentRange = cells.map(c => c.range).filter(r => r.contains(editor.selection.anchor));
106+
const rangeTop = currentRange.length > 0 ? [new vscode.Range(currentRange[0].start, currentRange[0].start)] : [];
107+
const rangeBottom = currentRange.length > 0 ? [new vscode.Range(currentRange[0].end, currentRange[0].end)] : [];
108+
editor.setDecorations(this.activeCellTop, rangeTop);
109+
editor.setDecorations(this.activeCellBottom, rangeBottom);
93110

94111
// Find the start range for the rest
95112
const startRanges = cells.map(c => new vscode.Range(c.range.start, c.range.start));
96113
editor.setDecorations(this.cellSeparatorType, startRanges);
97114
} else {
98-
editor.setDecorations(this.activeCellType, []);
115+
editor.setDecorations(this.activeCellTop, []);
116+
editor.setDecorations(this.activeCellBottom, []);
99117
editor.setDecorations(this.cellSeparatorType, []);
100118
}
101119
}
Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +0,0 @@
1-
.progress-bar {
2-
margin:2px;
3-
text-align: center;
4-
}
5-
6-
.progress-container {
7-
padding: 20px;
8-
text-align:center;
9-
}

src/datascience-ui/data-explorer/emptyRowsView.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,14 @@ import * as React from 'react';
77
import { getLocString } from '../react-common/locReactSide';
88

99
export interface IEmptyRowsProps {
10-
total: number;
11-
current: number;
1210
}
1311

14-
export const EmptyRowsView = (props: IEmptyRowsProps) => {
15-
const percent = props.current / props.total * 100;
16-
const percentText = `${Math.round(percent)}%`;
17-
const style: React.CSSProperties = {
18-
width: percentText
19-
};
20-
const message = getLocString('DataScience.noRowsInDataViewer', 'Fetching data ...');
12+
export const EmptyRows = (_props: IEmptyRowsProps) => {
13+
const message = getLocString('DataScience.noRowsInDataViewer', 'No rows match current filter');
2114

2215
return (
23-
<div className='progress-container'>
16+
<div className='container'>
2417
{message}
25-
<div className='progress-bar' style={style}>{percentText}</div>
2618
</div>
2719
);
2820
};

0 commit comments

Comments
 (0)