Skip to content

Commit 3d73773

Browse files
committed
ignore jupyter magic commands
1 parent cdcdb51 commit 3d73773

2 files changed

Lines changed: 52 additions & 28 deletions

File tree

src/client/common/constants.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,16 @@ export namespace Text {
5858
export namespace Delays {
5959
// Max time to wait before aborting the generation of code lenses for unit tests
6060
export const MaxUnitTestCodeLensDelay = 5000;
61+
}
62+
63+
export namespace LinterErrors {
64+
export namespace pylint {
65+
export const InvalidSyntax = 'E0001';
66+
}
67+
export namespace prospector {
68+
export const InvalidSyntax = 'F999';
69+
}
70+
export namespace flake8 {
71+
export const InvalidSyntax = 'E999';
72+
}
6173
}

src/client/providers/lintProvider.ts

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import * as pydocstyle from './../linters/pydocstyle';
1111
import * as settings from '../common/configSettings';
1212
import * as telemetryHelper from '../common/telemetry';
1313
import * as telemetryContracts from '../common/telemetryContracts';
14-
14+
import {LinterErrors} from '../common/constants'
1515
const lintSeverityToVSSeverity = new Map<linter.LintMessageSeverity, vscode.DiagnosticSeverity>();
1616
lintSeverityToVSSeverity.set(linter.LintMessageSeverity.Error, vscode.DiagnosticSeverity.Error)
1717
lintSeverityToVSSeverity.set(linter.LintMessageSeverity.Hint, vscode.DiagnosticSeverity.Hint)
@@ -37,6 +37,9 @@ function createDiagnostics(message: linter.ILintMessage, txtDocumentLines: strin
3737
return diagnostic;
3838
}
3939

40+
interface DocumentHasJupyterCodeCells {
41+
(doc: vscode.TextDocument, token: vscode.CancellationToken): Promise<Boolean>;
42+
}
4043
export class LintProvider extends vscode.Disposable {
4144
private settings: settings.IPythonSettings;
4245
private diagnosticCollection: vscode.DiagnosticCollection;
@@ -45,7 +48,8 @@ export class LintProvider extends vscode.Disposable {
4548
private outputChannel: vscode.OutputChannel;
4649
private context: vscode.ExtensionContext;
4750

48-
public constructor(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel, private workspaceRootPath: string) {
51+
public constructor(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel,
52+
private workspaceRootPath: string, private documentHasJupyterCodeCells: DocumentHasJupyterCodeCells) {
4953
super(() => { });
5054
this.outputChannel = outputChannel;
5155
this.context = context;
@@ -68,13 +72,13 @@ export class LintProvider extends vscode.Disposable {
6872
if (e.languageId !== 'python' || !this.settings.linting.enabled || !this.settings.linting.lintOnSave) {
6973
return;
7074
}
71-
this.lintDocument(e.uri, e.getText().split(/\r?\n/g), 100);
75+
this.lintDocument(e, e.uri, e.getText().split(/\r?\n/g), 100);
7276
});
7377
this.context.subscriptions.push(disposable);
7478
}
7579

7680
private lastTimeout: number;
77-
private lintDocument(documentUri: vscode.Uri, documentLines: string[], delay: number): void {
81+
private lintDocument(document: vscode.TextDocument, documentUri: vscode.Uri, documentLines: string[], delay: number): void {
7882
// Since this is a hack, lets wait for 2 seconds before linting
7983
// Give user to continue typing before we waste CPU time
8084
if (this.lastTimeout) {
@@ -83,11 +87,11 @@ export class LintProvider extends vscode.Disposable {
8387
}
8488

8589
this.lastTimeout = setTimeout(() => {
86-
this.onLintDocument(documentUri, documentLines);
90+
this.onLintDocument(document, documentUri, documentLines);
8791
}, delay);
8892
}
8993

90-
private onLintDocument(documentUri: vscode.Uri, documentLines: string[]): void {
94+
private onLintDocument(document: vscode.TextDocument, documentUri: vscode.Uri, documentLines: string[]): void {
9195
if (this.pendingLintings.has(documentUri.fsPath)) {
9296
this.pendingLintings.get(documentUri.fsPath).cancel();
9397
this.pendingLintings.delete(documentUri.fsPath);
@@ -113,29 +117,37 @@ export class LintProvider extends vscode.Disposable {
113117
return results;
114118
});
115119
});
120+
this.documentHasJupyterCodeCells(document, cancelToken.token).then(hasJupyterCodeCells => {
121+
// linters will resolve asynchronously - keep a track of all
122+
// diagnostics reported as them come in
123+
let diagnostics: vscode.Diagnostic[] = [];
124+
125+
promises.forEach(p => {
126+
p.then(msgs => {
127+
if (cancelToken.token.isCancellationRequested) {
128+
return;
129+
}
130+
131+
// Build the message and suffix the message with the name of the linter used
132+
msgs.forEach(d => {
133+
// ignore magic commands from jupyter
134+
if (hasJupyterCodeCells && documentLines[d.line - 1].trim().startsWith('%') &&
135+
(d.code === LinterErrors.pylint.InvalidSyntax ||
136+
d.code === LinterErrors.prospector.InvalidSyntax ||
137+
d.code === LinterErrors.flake8.InvalidSyntax)) {
138+
return;
139+
}
140+
diagnostics.push(createDiagnostics(d, documentLines));
141+
});
142+
143+
// Limit the number of messages to the max value
144+
diagnostics = diagnostics.filter((value, index) => index <= this.settings.linting.maxNumberOfProblems);
145+
146+
// set all diagnostics found in this pass, as this method always clears existing diagnostics.
147+
this.diagnosticCollection.set(documentUri, diagnostics)
116148

117-
// linters will resolve asynchronously - keep a track of all
118-
// diagnostics reported as them come in
119-
let diagnostics: vscode.Diagnostic[] = [];
120-
121-
promises.forEach(p => {
122-
p.then(msgs => {
123-
if (cancelToken.token.isCancellationRequested) {
124-
return;
125-
}
126-
127-
// Build the message and suffix the message with the name of the linter used
128-
msgs.forEach(d => {
129-
diagnostics.push(createDiagnostics(d, documentLines));
130149
});
131-
132-
// Limit the number of messages to the max value
133-
diagnostics = diagnostics.filter((value, index) => index <= this.settings.linting.maxNumberOfProblems);
134-
135-
// set all diagnostics found in this pass, as this method always clears existing diagnostics.
136-
this.diagnosticCollection.set(documentUri, diagnostics)
137-
138-
})
139-
})
150+
});
151+
});
140152
}
141153
}

0 commit comments

Comments
 (0)