Skip to content
Merged
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
2 changes: 2 additions & 0 deletions news/2 Fixes/2198.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Change linter message parsing so it respects `python.linting.maxNumberOfProblems`.
(thanks [Scott Saponas](https://github.com/saponas/))
26 changes: 13 additions & 13 deletions src/client/linters/baseLinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,21 @@ export abstract class BaseLinter implements ILinter {
}

private parseLines(outputLines: string[], regEx: string): ILintMessage[] {
return outputLines
.filter((value, index) => index <= this.pythonSettings.linting.maxNumberOfProblems)
.map(line => {
try {
const msg = this.parseLine(line, regEx);
if (msg) {
return msg;
const messages: ILintMessage[] = [];
for (const line of outputLines) {
try {
const msg = this.parseLine(line, regEx);
if (msg) {
messages.push(msg);
if (messages.length >= this.pythonSettings.linting.maxNumberOfProblems) {
break;
}
} catch (ex) {
this.logger.logError(`Linter '${this.info.id}' failed to parse the line '${line}.`, ex);
}
return;
})
.filter(item => item !== undefined)
.map(item => item!);
} catch (ex) {
this.logger.logError(`Linter '${this.info.id}' failed to parse the line '${line}.`, ex);
}
}
return messages;
}

private displayLinterResultHeader(data: string) {
Expand Down
19 changes: 19 additions & 0 deletions src/test/linters/lint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const pep8ConfigPath = path.join(pythoFilesPath, 'pep8config');
const pydocstyleConfigPath27 = path.join(pythoFilesPath, 'pydocstyleconfig27');
const pylintConfigPath = path.join(pythoFilesPath, 'pylintconfig');
const fileToLint = path.join(pythoFilesPath, 'file.py');
const threeLineLintsPath = path.join(pythoFilesPath, 'threeLineLints.py');

const pylintMessagesToBeReturned: ILintMessage[] = [
{ line: 24, column: 0, severity: LintMessageSeverity.Information, code: 'I0011', message: 'Locally disabling no-member (E1101)', provider: '', type: '' },
Expand Down Expand Up @@ -279,4 +280,22 @@ suite('Linting - General Tests', () => {
assert.notEqual(messages!.filter(x => x.source === 'pylint').length, 0, 'No pylint messages.');
assert.notEqual(messages!.filter(x => x.source === 'flake8').length, 0, 'No flake8 messages.');
});
// tslint:disable-next-line:no-any
async function testLinterMessageCount(product: Product, pythonFile: string, messageCountToBeReceived: number): Promise<any> {
const outputChannel = ioc.serviceContainer.get<MockOutputChannel>(IOutputChannel, STANDARD_OUTPUT_CHANNEL);
const cancelToken = new CancellationTokenSource();
const document = await workspace.openTextDocument(pythonFile);

await linterManager.setActiveLintersAsync([product], document.uri);
const linter = linterManager.createLinter(product, outputChannel, ioc.serviceContainer);

const messages = await linter.lint(document, cancelToken.token);
assert.equal(messages.length, messageCountToBeReceived, 'Expected number of lint errors does not match lint error count');
}
test('Three line output counted as one message', async () => {
const maxErrors = 5;
const target = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace;
await configService.updateSettingAsync('linting.maxNumberOfProblems', maxErrors, rootWorkspaceUri, target);
await testLinterMessageCount(Product.pylint, threeLineLintsPath, maxErrors);
});
});
24 changes: 24 additions & 0 deletions src/test/pythonFiles/linting/threeLineLints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""pylint messages with three lines of output"""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you add comments what the linter warnings are triggered by and an example of what the linter warning is? This is to prevent someone from accidentally changing the file and breaking the test's expectations. It will also help for us to know the tests is testing multi-line tests. 😉


__revision__ = None

class Foo(object):

def __init__(self):
pass

def meth1(self,arg):
"""missing a space between 'self' and 'arg'. This should trigger the
following three line lint warning::

C: 10, 0: Exactly one space required after comma
def meth1(self,arg):
^ (bad-whitespace)

The following three lines of tuples should also cause three-line lint
errors due to "Exactly one space required after comma" messages.
"""
a = (1,2)
b = (1,2)
c = (1,2)
print (self)