Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Update pylint msg-template to show human-friendly error symbols. #495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,7 @@
},
"python.linting.pylintArgs": {
"type": "array",
"description": "Arguments passed in. Each argument is a separate item in the array.",
"description": "Arguments passed in. Each argument is a separate item in the array. --msg-template is set by VSCode and cannot be overridden here. Use python.linting.pylintMsgTemplate instead.",
"default": [],
"items": {
"type": "string"
Expand Down Expand Up @@ -1228,6 +1228,16 @@
},
"scope": "resource"
},
"python.linting.pylintMsgTemplate": {
"type": "string",
"description": "Controls the message template for linting results. Options are 'standard' and 'legacy'. 'standard' displays error codes as symbolic names like 'missing-docstring'. 'legacy' displays error codes as alphanumeric codes like 'C0111'.",
"default": "legacy",
"enum": [
"standard",
"legacy"
],
"scope": "resource"
},
"python.formatting.provider": {
"type": "string",
"default": "autopep8",
Expand Down
3 changes: 2 additions & 1 deletion src/client/common/configSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export interface ILintingSettings {
prospectorArgs: string[];
pylintEnabled: boolean;
pylintArgs: string[];
pylintMsgTemplate: string;
pep8Enabled: boolean;
pep8Args: string[];
pylamaEnabled: boolean;
Expand Down Expand Up @@ -251,7 +252,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings {
pylamaArgs: [], pylamaEnabled: false, pylamaPath: 'pylama',
prospectorArgs: [], prospectorEnabled: false, prospectorPath: 'prospector',
pydocstyleArgs: [], pydocstyleEnabled: false, pydocstylePath: 'pydocstyle',
pylintArgs: [], pylintEnabled: false, pylintPath: 'pylint',
pylintArgs: [], pylintEnabled: false, pylintPath: 'pylint', pylintMsgTemplate: 'legacy',
pylintCategorySeverity: {
convention: vscode.DiagnosticSeverity.Hint,
error: vscode.DiagnosticSeverity.Error,
Expand Down
1 change: 1 addition & 0 deletions src/client/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export namespace Delays {
export namespace LinterErrors {
export namespace pylint {
export const InvalidSyntax = 'E0001';
export const InvalidSyntaxSymbolic = 'invalid-syntax';
}
export namespace prospector {
export const InvalidSyntax = 'F999';
Expand Down
4 changes: 3 additions & 1 deletion src/client/linters/baseLinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface ILintMessage {
type: string;
severity?: LintMessageSeverity;
provider: string;
preformattedMessage?: boolean;
}
export enum LintMessageSeverity {
Hint,
Expand Down Expand Up @@ -152,7 +153,8 @@ export abstract class BaseLinter {
column: isNaN(match.column) || match.column === 0 ? 0 : match.column - this.columnOffset,
line: match.line,
type: match.type,
provider: this.Id
provider: this.Id,
preformattedMessage: false
};
}
private parseLines(outputLines: string[], regEx: string): ILintMessage[] {
Expand Down
3 changes: 2 additions & 1 deletion src/client/linters/prospector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export class Linter extends baseLinter.BaseLinter {
column: msg.location.character,
line: lineNumber,
type: msg.code,
provider: `${this.Id} - ${msg.source}`
provider: `${this.Id} - ${msg.source}`,
messageContainsCode: false
};
});
}
Expand Down
16 changes: 15 additions & 1 deletion src/client/linters/pylint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,23 @@ export class Linter extends baseLinter.BaseLinter {
}

protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise<baseLinter.ILintMessage[]> {
const messages = await this.run(['--msg-template=\'{line},{column},{category},{msg_id}:{msg}\'', '--reports=n', '--output-format=text', document.uri.fsPath], document, cancellation);
let msgBody;
let regex;
if (this.pythonSettings.linting.pylintMsgTemplate === 'legacy') {
msgBody = '{msg_id}:{msg}';
} else if (this.pythonSettings.linting.pylintMsgTemplate === 'standard') {
msgBody = '{msg} ({symbol})';
regex = '(?<line>\\d+),(?<column>\\d+),(?<type>\\w+),(?<code>[a-z-]+):(?<message>.*)\\r?(\\n|$)';
}
let codeVar = '{symbol}';
if (msgBody.includes('{msg_id}') && !msgBody.includes('{symbol}')) {
codeVar = '{msg_id}';
}
const msgTemplate = `'{line},{column},{category},${codeVar}:${msgBody}'`;
const messages = await this.run([`--msg-template=${msgTemplate}`, '--reports=n', '--output-format=text', document.uri.fsPath], document, cancellation, regex);
messages.forEach(msg => {
msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.pylintCategorySeverity);
msg.preformattedMessage = true;
});

return messages;
Expand Down
9 changes: 8 additions & 1 deletion src/client/providers/lintProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ function createDiagnostics(message: linter.ILintMessage, document: vscode.TextDo
const range = new vscode.Range(position, position);

const severity = lintSeverityToVSSeverity.get(message.severity!)!;
const diagnostic = new vscode.Diagnostic(range, `${message.code}:${message.message}`, severity);
let formattedMessage;
if (message.preformattedMessage) {
formattedMessage = message.message;
} else {
formattedMessage = `${message.code}:${message.message}`;
}
const diagnostic = new vscode.Diagnostic(range, formattedMessage, severity);
diagnostic.code = message.code;
diagnostic.source = message.provider;
return diagnostic;
Expand Down Expand Up @@ -218,6 +224,7 @@ export class LintProvider implements vscode.Disposable {
// Ignore magic commands from jupyter.
if (hasJupyterCodeCells && document.lineAt(d.line - 1).text.trim().startsWith('%') &&
(d.code === LinterErrors.pylint.InvalidSyntax ||
d.code === LinterErrors.pylint.InvalidSyntaxSymbolic ||
d.code === LinterErrors.prospector.InvalidSyntax ||
d.code === LinterErrors.flake8.InvalidSyntax)) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/test/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"python.linting.pylintEnabled": false,
"python.linting.pylintEnabled": true,
"python.linting.flake8Enabled": false,
"python.workspaceSymbols.enabled": false,
"python.unitTest.nosetestArgs": [],
Expand Down
2 changes: 1 addition & 1 deletion src/test/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const rootWorkspaceUri = getWorkspaceRoot();

export type PythonSettingKeys = 'workspaceSymbols.enabled' | 'pythonPath' |
'linting.lintOnSave' |
'linting.enabled' | 'linting.pylintEnabled' |
'linting.enabled' | 'linting.pylintEnabled' | 'linting.pylintMsgTemplate' |
'linting.flake8Enabled' | 'linting.pep8Enabled' | 'linting.pylamaEnabled' |
'linting.prospectorEnabled' | 'linting.pydocstyleEnabled' | 'linting.mypyEnabled' |
'unitTest.nosetestArgs' | 'unitTest.pyTestArgs' | 'unitTest.unittestArgs' |
Expand Down
12 changes: 6 additions & 6 deletions src/test/debugger/portAndHost.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,23 @@ suite('Standard Debugging', () => {
await debugClient.waitForEvent('terminated');
}

test('Confirm debuggig works if both port and host are not provided', async () => {
test('Confirm debugging works if both port and host are not provided', async () => {
await testDebuggingWithProvidedPort();
});

test('Confirm debuggig works if port=0', async () => {
test('Confirm debugging works if port=0', async () => {
await testDebuggingWithProvidedPort(0, 'localhost');
});

test('Confirm debuggig works if port=0 or host=localhost', async () => {
test('Confirm debugging works if port=0 or host=localhost', async () => {
await testDebuggingWithProvidedPort(0, 'localhost');
});

test('Confirm debuggig works if port=0 or host=127.0.0.1', async () => {
test('Confirm debugging works if port=0 or host=127.0.0.1', async () => {
await testDebuggingWithProvidedPort(0, '127.0.0.1');
});

test('Confirm debuggig fails when an invalid host is provided', async () => {
test('Confirm debugging fails when an invalid host is provided', async () => {
const promise = testDebuggingWithProvidedPort(0, 'xyz123409924ple_ewf');
let exception: Error | undefined;
try {
Expand All @@ -110,7 +110,7 @@ suite('Standard Debugging', () => {
}
expect(exception!.message).contains('ENOTFOUND', 'Debugging failed for some other reason');
});
test('Confirm debuggig fails when provided port is in use', async () => {
test('Confirm debugging fails when provided port is in use', async () => {
// tslint:disable-next-line:no-empty
const server = net.createServer((s) => { });
const port = await new Promise<number>((resolve, reject) => server.listen({ host: 'localhost', port: 0 }, () => resolve(server.address().port)));
Expand Down
Loading