Skip to content

Commit 18be595

Browse files
author
Mikhail Arkhipov
authored
Improves linting behavior per #722 (#792)
* Basic tokenizer * Fixed property names * Tests, round I * Tests, round II * tokenizer test * Remove temorary change * Fix merge issue * Merge conflict * Merge conflict * Completion test * Fix last line * Fix javascript math * Make test await for results * Add license headers * Rename definitions to types * License headers * Fix typo in completion details (typo) * Fix hover test * Russian translations * Update to better translation * Fix typo * #70 How to get all parameter info when filling in a function param list * Fix #70 How to get all parameter info when filling in a function param list * Clean up * Clean imports * CR feedback * Trim whitespace for test stability * More tests * Better handle no-parameters documentation * Better handle ellipsis and Python3 * #385 Auto-Indentation doesn't work after comment * #141 Auto indentation broken when return keyword involved * Undo changes * #627 Docstrings for builtin methods are not parsed correctly * reStructuredText converter * Fix: period is not an operator * Minor fixes * Restructure * Tests * Tests * Code heuristics * Baselines * HTML handling * Lists * State machine * Baselines * Squash * no message * Whitespace difference * Update Jedi to 0.11.1 * Enable Travis * Test fixes * Undo change * Jedi 0.11 with parser * Undo changes * Undo changes * Test fixes * Re-lint when interpreter changes * Re-lint on linter config change * Run linting command * Encapsulate jupiter * Handle promise * More tests * Tests * Use service * Linter provider tests * Move methods to documents manager
1 parent 5a1452e commit 18be595

21 files changed

+570
-279
lines changed

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@
231231
"command": "python.enableLinting",
232232
"title": "%python.command.python.enableLinting.title%",
233233
"category": "Python"
234+
},
235+
{
236+
"command": "python.runLinting",
237+
"title": "%python.command.python.runLinting.title%",
238+
"category": "Python"
234239
}
235240
],
236241
"menus": {
@@ -1836,4 +1841,4 @@
18361841
"publisherDisplayName": "Microsoft",
18371842
"publisherId": "998b010b-e2af-44a5-a6cd-0b5fd3b9b6f8"
18381843
}
1839-
}
1844+
}

package.nls.json

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,29 @@
2626
"python.command.python.goToPythonObject.title": "Go to Python Object",
2727
"python.command.python.setLinter.title": "Select Linter",
2828
"python.command.python.enableLinting.title": "Enable Linting",
29-
"python.snippet.launch.standard.label": "Python",
30-
"python.snippet.launch.standard.description": "Debug a Python program with standard output",
31-
"python.snippet.launch.pyspark.label": "Python: PySpark",
32-
"python.snippet.launch.pyspark.description": "Debug PySpark",
33-
"python.snippet.launch.module.label": "Python: Module",
34-
"python.snippet.launch.module.description": "Debug a Python Module",
35-
"python.snippet.launch.terminal.label": "Python: Terminal (integrated)",
36-
"python.snippet.launch.terminal.description": "Debug a Python program with Integrated Terminal/Console",
37-
"python.snippet.launch.externalTerminal.label": "Python: Terminal (external)",
38-
"python.snippet.launch.externalTerminal.description": "Debug a Python program with External Terminal/Console",
39-
"python.snippet.launch.django.label": "Python: Django",
40-
"python.snippet.launch.django.description": "Debug a Django Application",
41-
"python.snippet.launch.flask.label": "Python: Flask (0.11.x or later)",
42-
"python.snippet.launch.flask.description": "Debug a Flask Application",
43-
"python.snippet.launch.flaskOld.label": "Python: Flask (0.10.x or earlier)",
44-
"python.snippet.launch.flaskOld.description": "Debug an older styled Flask Application",
45-
"python.snippet.launch.pyramid.label": "Python: Pyramid Application",
46-
"python.snippet.launch.pyramid.description": "Debug a Pyramid Application",
47-
"python.snippet.launch.watson.label": "Python: Watson Application",
48-
"python.snippet.launch.watson.description": "Debug a Watson Application",
49-
"python.snippet.launch.attach.label": "Python: Attach",
50-
"python.snippet.launch.attach.description": "Attach the debugger for remote debugging",
51-
"python.snippet.launch.scrapy.label": "Python: Scrapy",
52-
"python.snippet.launch.scrapy.description": "Scrapy with Integrated Terminal/Console"
53-
}
29+
"python.command.python.runLinting.title": "Run Linting",
30+
"python.snippet.launch.standard.label": "Python",
31+
"python.snippet.launch.standard.description": "Debug a Python program with standard output",
32+
"python.snippet.launch.pyspark.label": "Python: PySpark",
33+
"python.snippet.launch.pyspark.description": "Debug PySpark",
34+
"python.snippet.launch.module.label": "Python: Module",
35+
"python.snippet.launch.module.description": "Debug a Python Module",
36+
"python.snippet.launch.terminal.label": "Python: Terminal (integrated)",
37+
"python.snippet.launch.terminal.description": "Debug a Python program with Integrated Terminal/Console",
38+
"python.snippet.launch.externalTerminal.label": "Python: Terminal (external)",
39+
"python.snippet.launch.externalTerminal.description": "Debug a Python program with External Terminal/Console",
40+
"python.snippet.launch.django.label": "Python: Django",
41+
"python.snippet.launch.django.description": "Debug a Django Application",
42+
"python.snippet.launch.flask.label": "Python: Flask (0.11.x or later)",
43+
"python.snippet.launch.flask.description": "Debug a Flask Application",
44+
"python.snippet.launch.flaskOld.label": "Python: Flask (0.10.x or earlier)",
45+
"python.snippet.launch.flaskOld.description": "Debug an older styled Flask Application",
46+
"python.snippet.launch.pyramid.label": "Python: Pyramid Application",
47+
"python.snippet.launch.pyramid.description": "Debug a Pyramid Application",
48+
"python.snippet.launch.watson.label": "Python: Watson Application",
49+
"python.snippet.launch.watson.description": "Debug a Watson Application",
50+
"python.snippet.launch.attach.label": "Python: Attach",
51+
"python.snippet.launch.attach.description": "Attach the debugger for remote debugging",
52+
"python.snippet.launch.scrapy.label": "Python: Scrapy",
53+
"python.snippet.launch.scrapy.description": "Scrapy with Integrated Terminal/Console"
54+
}

package.nls.ru.json

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,29 @@
2525
"python.command.python.goToPythonObject.title": "Перейти к объекту Python",
2626
"python.command.python.setLinter.title": "Выбрать анализатор кода",
2727
"python.command.python.enableLinting.title": "Включить анализатор кода",
28-
"python.snippet.launch.standard.label": "Python",
29-
"python.snippet.launch.standard.description": "Отладить программу Python со стандартным выводом",
30-
"python.snippet.launch.pyspark.label": "Python: PySpark",
31-
"python.snippet.launch.pyspark.description": "Отладка PySpark",
32-
"python.snippet.launch.module.label": "Python: Модуль",
33-
"python.snippet.launch.module.description": "Отладка модуля",
34-
"python.snippet.launch.terminal.label": "Python: Интегрированная консоль",
35-
"python.snippet.launch.terminal.description": "Отладка программы Python в интегрированной консоли",
36-
"python.snippet.launch.externalTerminal.label": "Python: Внешний терминал",
37-
"python.snippet.launch.externalTerminal.description": "Отладка программы Python во внешней консоли",
38-
"python.snippet.launch.django.label": "Python: Django",
39-
"python.snippet.launch.django.description": "Отладка приложения Django",
40-
"python.snippet.launch.flask.label": "Python: Flask (0.11.x или новее)",
41-
"python.snippet.launch.flask.description": "Отладка приложения Flask",
42-
"python.snippet.launch.flaskOld.label": "Python: Flask (0.10.x или старее)",
43-
"python.snippet.launch.flaskOld.description": "Отладка приложения Flask (старый стиль)",
44-
"python.snippet.launch.pyramid.label": "Python: Приложение Pyramid",
45-
"python.snippet.launch.pyramid.description": "Отладка приложения Pyramid",
46-
"python.snippet.launch.watson.label": "Python: Приложение Watson",
47-
"python.snippet.launch.watson.description": "Отладка приложения Watson",
48-
"python.snippet.launch.attach.label": "Python: Подключить отладчик",
49-
"python.snippet.launch.attach.description": "Подключить отладчик для удаленной отладки",
50-
"python.snippet.launch.scrapy.label": "Python: Scrapy",
51-
"python.snippet.launch.scrapy.description": "Scrapy в интегрированной консоли"
52-
}
28+
"python.command.python.runLinting.title": "Выполнить анализ кода",
29+
"python.snippet.launch.standard.label": "Python",
30+
"python.snippet.launch.standard.description": "Отладить программу Python со стандартным выводом",
31+
"python.snippet.launch.pyspark.label": "Python: PySpark",
32+
"python.snippet.launch.pyspark.description": "Отладка PySpark",
33+
"python.snippet.launch.module.label": "Python: Модуль",
34+
"python.snippet.launch.module.description": "Отладка модуля",
35+
"python.snippet.launch.terminal.label": "Python: Интегрированная консоль",
36+
"python.snippet.launch.terminal.description": "Отладка программы Python в интегрированной консоли",
37+
"python.snippet.launch.externalTerminal.label": "Python: Внешний терминал",
38+
"python.snippet.launch.externalTerminal.description": "Отладка программы Python во внешней консоли",
39+
"python.snippet.launch.django.label": "Python: Django",
40+
"python.snippet.launch.django.description": "Отладка приложения Django",
41+
"python.snippet.launch.flask.label": "Python: Flask (0.11.x или новее)",
42+
"python.snippet.launch.flask.description": "Отладка приложения Flask",
43+
"python.snippet.launch.flaskOld.label": "Python: Flask (0.10.x или старее)",
44+
"python.snippet.launch.flaskOld.description": "Отладка приложения Flask (старый стиль)",
45+
"python.snippet.launch.pyramid.label": "Python: Приложение Pyramid",
46+
"python.snippet.launch.pyramid.description": "Отладка приложения Pyramid",
47+
"python.snippet.launch.watson.label": "Python: Приложение Watson",
48+
"python.snippet.launch.watson.description": "Отладка приложения Watson",
49+
"python.snippet.launch.attach.label": "Python: Подключить отладчик",
50+
"python.snippet.launch.attach.description": "Подключить отладчик для удаленной отладки",
51+
"python.snippet.launch.scrapy.label": "Python: Scrapy",
52+
"python.snippet.launch.scrapy.description": "Scrapy в интегрированной консоли"
53+
}

src/client/common/application/documentManager.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import { IDocumentManager } from './types';
99

1010
@injectable()
1111
export class DocumentManager implements IDocumentManager {
12+
public get textDocuments(): TextDocument[] {
13+
return workspace.textDocuments;
14+
}
1215
public get activeTextEditor(): TextEditor | undefined {
1316
return window.activeTextEditor;
1417
}
@@ -30,6 +33,12 @@ export class DocumentManager implements IDocumentManager {
3033
public get onDidChangeTextEditorViewColumn(): Event<TextEditorViewColumnChangeEvent> {
3134
return window.onDidChangeTextEditorViewColumn;
3235
}
36+
public get onDidOpenTextDocument(): Event<TextDocument> {
37+
return workspace.onDidOpenTextDocument;
38+
}
39+
public get onDidCloseTextDocument(): Event<TextDocument> {
40+
return workspace.onDidCloseTextDocument;
41+
}
3342
public get onDidSaveTextDocument(): Event<TextDocument> {
3443
return workspace.onDidSaveTextDocument;
3544
}

src/client/common/application/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ export interface ICommandManager {
312312
export const IDocumentManager = Symbol('IDocumentManager');
313313

314314
export interface IDocumentManager {
315+
/**
316+
* All text documents currently known to the system.
317+
*
318+
* @readonly
319+
*/
320+
readonly textDocuments: TextDocument[];
315321
/**
316322
* The currently active editor or `undefined`. The active editor is the one
317323
* that currently has focus or, when none has focus, the one that has changed
@@ -352,6 +358,14 @@ export interface IDocumentManager {
352358
*/
353359
readonly onDidChangeTextEditorViewColumn: Event<TextEditorViewColumnChangeEvent>;
354360

361+
/**
362+
* An event that is emitted when a [text document](#TextDocument) is opened.
363+
*/
364+
readonly onDidOpenTextDocument: Event<TextDocument>;
365+
/**
366+
* An event that is emitted when a [text document](#TextDocument) is disposed.
367+
*/
368+
readonly onDidCloseTextDocument: Event<TextDocument>;
355369
/**
356370
* An event that is emitted when a [text document](#TextDocument) is saved to disk.
357371
*/

src/client/common/application/workspace.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,7 @@ export class WorkspaceService implements IWorkspaceService {
3535
public findFiles(include: vscode.GlobPattern, exclude?: vscode.GlobPattern, maxResults?: number, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> {
3636
return vscode.workspace.findFiles(include, exclude, maxResults, token);
3737
}
38+
public get onDidSaveTextDocument(): vscode.Event<vscode.TextDocument> {
39+
return vscode.workspace.onDidSaveTextDocument;
40+
}
3841
}

src/client/common/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export namespace Commands {
3131
export const Create_Terminal = 'python.createTerminal';
3232
export const Set_Linter = 'python.setLinter';
3333
export const Enable_Linter = 'python.enableLinting';
34+
export const Run_Linter = 'python.runLinting';
3435
}
3536
export namespace Octicons {
3637
export const Test_Pass = '$(check)';

src/client/extension.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ import { registerTypes as interpretersRegisterTypes } from './interpreter/servic
3131
import { ServiceContainer } from './ioc/container';
3232
import { ServiceManager } from './ioc/serviceManager';
3333
import { IServiceContainer } from './ioc/types';
34-
import { JupyterProvider } from './jupyter/provider';
3534
import { JediFactory } from './languageServices/jediProxyFactory';
3635
import { LinterCommands } from './linters/linterCommands';
3736
import { registerTypes as lintersRegisterTypes } from './linters/serviceRegistry';
37+
import { ILintingEngine } from './linters/types';
3838
import { PythonCompletionItemProvider } from './providers/completionProvider';
3939
import { PythonDefinitionProvider } from './providers/definitionProvider';
4040
import { PythonFormattingEditProvider } from './providers/formatProvider';
@@ -165,29 +165,16 @@ export async function activate(context: vscode.ExtensionContext) {
165165
context.subscriptions.push(vscode.languages.registerDocumentRangeFormattingEditProvider(PYTHON, formatProvider));
166166
}
167167

168-
// tslint:disable-next-line:promise-function-async
169-
const linterProvider = new LinterProvider(context, standardOutputChannel, (a, b) => Promise.resolve(false), serviceContainer);
168+
const linterProvider = new LinterProvider(context, serviceContainer);
170169
context.subscriptions.push(linterProvider);
171-
const jupyterExtInstalled = vscode.extensions.getExtension('donjayamanne.jupyter');
172-
if (jupyterExtInstalled) {
173-
if (jupyterExtInstalled.isActive) {
174-
// tslint:disable-next-line:no-unsafe-any
175-
jupyterExtInstalled.exports.registerLanguageProvider(PYTHON.language, new JupyterProvider());
176-
// tslint:disable-next-line:no-unsafe-any
177-
linterProvider.documentHasJupyterCodeCells = jupyterExtInstalled.exports.hasCodeCells;
178-
}
179-
180-
jupyterExtInstalled.activate().then(() => {
181-
// tslint:disable-next-line:no-unsafe-any
182-
jupyterExtInstalled.exports.registerLanguageProvider(PYTHON.language, new JupyterProvider());
183-
// tslint:disable-next-line:no-unsafe-any
184-
linterProvider.documentHasJupyterCodeCells = jupyterExtInstalled.exports.hasCodeCells;
185-
});
186-
}
170+
171+
const jupyterExtension = vscode.extensions.getExtension('donjayamanne.jupyter');
172+
const lintingEngine = serviceContainer.get<ILintingEngine>(ILintingEngine);
173+
lintingEngine.linkJupiterExtension(jupyterExtension).ignoreErrors();
174+
187175
tests.activate(context, unitTestOutChannel, symbolProvider, serviceContainer);
188176

189177
context.subscriptions.push(new WorkspaceSymbols(serviceContainer));
190-
191178
context.subscriptions.push(vscode.languages.registerOnTypeFormattingEditProvider(PYTHON, new BlockFormatProviders(), ':'));
192179
context.subscriptions.push(vscode.languages.registerOnTypeFormattingEditProvider(PYTHON, new OnEnterFormatter(), '\n'));
193180

@@ -199,9 +186,9 @@ export async function activate(context: vscode.ExtensionContext) {
199186
// tslint:disable-next-line:no-unused-expression
200187
new BannerService(persistentStateFactory);
201188

202-
const deprecationMgr = new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtInstalled);
189+
const deprecationMgr = new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtension);
203190
deprecationMgr.initialize();
204-
context.subscriptions.push(new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtInstalled));
191+
context.subscriptions.push(new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtension));
205192
}
206193

207194
async function sendStartupTelemetry(activatedPromise: Promise<void>, serviceContainer: IServiceContainer) {

src/client/interpreter/contracts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CodeLensProvider, ConfigurationTarget, Disposable, TextDocument, Uri } from 'vscode';
1+
import { CodeLensProvider, ConfigurationTarget, Disposable, Event, TextDocument, Uri } from 'vscode';
22
import { Architecture } from '../common/platform/types';
33

44
export const INTERPRETER_LOCATOR_SERVICE = 'IInterpreterLocatorService';
@@ -75,8 +75,8 @@ export type WorkspacePythonPath = {
7575
};
7676

7777
export const IInterpreterService = Symbol('IInterpreterService');
78-
7978
export interface IInterpreterService {
79+
onDidChangeInterpreter: Event<void>;
8080
getInterpreters(resource?: Uri): Promise<PythonInterpreter[]>;
8181
autoSetInterpreter(): Promise<void>;
8282
getActiveInterpreter(resource?: Uri): Promise<PythonInterpreter | undefined>;

src/client/interpreter/display/index.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export class InterpreterDisplay implements IInterpreterDisplay {
2020
private readonly configurationService: IConfigurationService;
2121
private readonly helper: IInterpreterHelper;
2222
private readonly workspaceService: IWorkspaceService;
23-
private currentWorkspaceInterpreter?: Uri;
23+
2424
constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) {
2525
this.interpreterService = serviceContainer.get<IInterpreterService>(IInterpreterService);
2626
this.virtualEnvMgr = serviceContainer.get<IVirtualEnvironmentManager>(IVirtualEnvironmentManager);
@@ -48,14 +48,7 @@ export class InterpreterDisplay implements IInterpreterDisplay {
4848
}
4949
await this.updateDisplay(resource);
5050
}
51-
private shouldRefresh(workspaceFolder?: Uri) {
52-
if (!workspaceFolder || !this.currentWorkspaceInterpreter) {
53-
return true;
54-
}
55-
return !this.fileSystem.arePathsSame(workspaceFolder.fsPath, this.currentWorkspaceInterpreter.fsPath);
56-
}
5751
private async updateDisplay(workspaceFolder?: Uri) {
58-
this.currentWorkspaceInterpreter = workspaceFolder;
5952
const interpreters = await this.interpreterService.getInterpreters(workspaceFolder);
6053
const interpreter = await this.interpreterService.getActiveInterpreter(workspaceFolder);
6154
const pythonPath = interpreter ? interpreter.path : this.configurationService.getSettings(workspaceFolder).pythonPath;

0 commit comments

Comments
 (0)