Skip to content

Commit ed42722

Browse files
saponasbrettcannon
authored andcommitted
Change message parsing in BaseLinter so it respects python.linting.maxNumberOfProblems (microsoft#2208)
1 parent 540dbbb commit ed42722

4 files changed

Lines changed: 58 additions & 13 deletions

File tree

news/2 Fixes/2198.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Change linter message parsing so it respects `python.linting.maxNumberOfProblems`.
2+
(thanks [Scott Saponas](https://github.com/saponas/))

src/client/linters/baseLinter.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,21 +149,21 @@ export abstract class BaseLinter implements ILinter {
149149
}
150150

151151
private parseLines(outputLines: string[], regEx: string): ILintMessage[] {
152-
return outputLines
153-
.filter((value, index) => index <= this.pythonSettings.linting.maxNumberOfProblems)
154-
.map(line => {
155-
try {
156-
const msg = this.parseLine(line, regEx);
157-
if (msg) {
158-
return msg;
152+
const messages: ILintMessage[] = [];
153+
for (const line of outputLines) {
154+
try {
155+
const msg = this.parseLine(line, regEx);
156+
if (msg) {
157+
messages.push(msg);
158+
if (messages.length >= this.pythonSettings.linting.maxNumberOfProblems) {
159+
break;
159160
}
160-
} catch (ex) {
161-
this.logger.logError(`Linter '${this.info.id}' failed to parse the line '${line}.`, ex);
162161
}
163-
return;
164-
})
165-
.filter(item => item !== undefined)
166-
.map(item => item!);
162+
} catch (ex) {
163+
this.logger.logError(`Linter '${this.info.id}' failed to parse the line '${line}.`, ex);
164+
}
165+
}
166+
return messages;
167167
}
168168

169169
private displayLinterResultHeader(data: string) {

src/test/linters/lint.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const pep8ConfigPath = path.join(pythoFilesPath, 'pep8config');
2323
const pydocstyleConfigPath27 = path.join(pythoFilesPath, 'pydocstyleconfig27');
2424
const pylintConfigPath = path.join(pythoFilesPath, 'pylintconfig');
2525
const fileToLint = path.join(pythoFilesPath, 'file.py');
26+
const threeLineLintsPath = path.join(pythoFilesPath, 'threeLineLints.py');
2627

2728
const pylintMessagesToBeReturned: ILintMessage[] = [
2829
{ line: 24, column: 0, severity: LintMessageSeverity.Information, code: 'I0011', message: 'Locally disabling no-member (E1101)', provider: '', type: '' },
@@ -279,4 +280,22 @@ suite('Linting - General Tests', () => {
279280
assert.notEqual(messages!.filter(x => x.source === 'pylint').length, 0, 'No pylint messages.');
280281
assert.notEqual(messages!.filter(x => x.source === 'flake8').length, 0, 'No flake8 messages.');
281282
});
283+
// tslint:disable-next-line:no-any
284+
async function testLinterMessageCount(product: Product, pythonFile: string, messageCountToBeReceived: number): Promise<any> {
285+
const outputChannel = ioc.serviceContainer.get<MockOutputChannel>(IOutputChannel, STANDARD_OUTPUT_CHANNEL);
286+
const cancelToken = new CancellationTokenSource();
287+
const document = await workspace.openTextDocument(pythonFile);
288+
289+
await linterManager.setActiveLintersAsync([product], document.uri);
290+
const linter = linterManager.createLinter(product, outputChannel, ioc.serviceContainer);
291+
292+
const messages = await linter.lint(document, cancelToken.token);
293+
assert.equal(messages.length, messageCountToBeReceived, 'Expected number of lint errors does not match lint error count');
294+
}
295+
test('Three line output counted as one message', async () => {
296+
const maxErrors = 5;
297+
const target = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace;
298+
await configService.updateSettingAsync('linting.maxNumberOfProblems', maxErrors, rootWorkspaceUri, target);
299+
await testLinterMessageCount(Product.pylint, threeLineLintsPath, maxErrors);
300+
});
282301
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""pylint messages with three lines of output"""
2+
3+
__revision__ = None
4+
5+
class Foo(object):
6+
7+
def __init__(self):
8+
pass
9+
10+
def meth1(self,arg):
11+
"""missing a space between 'self' and 'arg'. This should trigger the
12+
following three line lint warning::
13+
14+
C: 10, 0: Exactly one space required after comma
15+
def meth1(self,arg):
16+
^ (bad-whitespace)
17+
18+
The following three lines of tuples should also cause three-line lint
19+
errors due to "Exactly one space required after comma" messages.
20+
"""
21+
a = (1,2)
22+
b = (1,2)
23+
c = (1,2)
24+
print (self)

0 commit comments

Comments
 (0)