Skip to content

Commit 94a246b

Browse files
demusDonJayamanne
authored andcommitted
Add bandit to supported linters (microsoft#2775)
For microsoft#2726 Add support for Bandit
1 parent cb9fb90 commit 94a246b

File tree

19 files changed

+94
-10
lines changed

19 files changed

+94
-10
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ make this extension useful:
3737
[venv](https://docs.python.org/3/library/venv.html#module-venv),
3838
[virtualenv](https://pypi.org/project/virtualenv/)
3939
- Linting:
40+
[bandit](https://pypi.org/project/bandit/),
4041
[flake8](https://pypi.org/project/flake8/),
4142
[mypy](https://pypi.org/project/mypy/),
4243
[prospector](https://pypi.org/project/prospector/),
@@ -82,7 +83,10 @@ part of!
8283
1. Language server now provides rename functionality.
8384
([#2650](https://github.com/Microsoft/vscode-python/issues/2650))
8485
1. Search for default known paths for conda environments on windows.
85-
([#2794](https://github.com/Microsoft/vscode-python/issues/2794))
86+
([#2794](https://github.com/Microsoft/vscode-python/issues/2794)
87+
1. Add [bandit](https://pypi.org/project/bandit/) to supported linters.
88+
(thanks [Steven Demurjian](https://github.com/demus))
89+
([#2775](https://github.com/Microsoft/vscode-python/issues/2775))
8690

8791
### Fixes
8892

news/1 Enhancements/2775.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add [bandit](https://pypi.org/project/bandit/) to supported linters.
2+
(thanks [Steven Demurjian Jr.](https://github.com/demus/))

package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,27 @@
994994
"description": "Controls the maximum number of problems produced by the server.",
995995
"scope": "resource"
996996
},
997+
"python.linting.banditArgs": {
998+
"type": "array",
999+
"description": "Arguments passed in. Each argument is a separate item in the array.",
1000+
"default": [],
1001+
"items": {
1002+
"type": "string"
1003+
},
1004+
"scope": "resource"
1005+
},
1006+
"python.linting.banditEnabled": {
1007+
"type": "boolean",
1008+
"default": false,
1009+
"description": "Whether to lint Python files using bandit.",
1010+
"scope": "resource"
1011+
},
1012+
"python.linting.banditPath": {
1013+
"type": "string",
1014+
"default": "bandit",
1015+
"description": "Path to bandit, you can use a custom version of bandit by modifying this setting to include the full path.",
1016+
"scope": "resource"
1017+
},
9971018
"python.linting.mypyArgs": {
9981019
"type": "array",
9991020
"description": "Arguments passed in. Each argument is a separate item in the array.",

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# but flake8 has a tighter pinning.
33
flake8
44
autopep8
5+
bandit
56
black ; python_version>='3.6'
67
yapf
78
pylint

src/client/common/configSettings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings {
175175
flake8Args: [], flake8Enabled: false, flake8Path: 'flake',
176176
lintOnSave: false, maxNumberOfProblems: 100,
177177
mypyArgs: [], mypyEnabled: false, mypyPath: 'mypy',
178+
banditArgs: [], banditEnabled: false, banditPath: 'bandit',
178179
pep8Args: [], pep8Enabled: false, pep8Path: 'pep8',
179180
pylamaArgs: [], pylamaEnabled: false, pylamaPath: 'pylama',
180181
prospectorArgs: [], prospectorEnabled: false, prospectorPath: 'prospector',
@@ -212,6 +213,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings {
212213
this.linting.prospectorPath = getAbsolutePath(systemVariables.resolveAny(this.linting.prospectorPath), workspaceRoot);
213214
this.linting.pydocstylePath = getAbsolutePath(systemVariables.resolveAny(this.linting.pydocstylePath), workspaceRoot);
214215
this.linting.mypyPath = getAbsolutePath(systemVariables.resolveAny(this.linting.mypyPath), workspaceRoot);
216+
this.linting.banditPath = getAbsolutePath(systemVariables.resolveAny(this.linting.banditPath), workspaceRoot);
215217

216218
// tslint:disable-next-line:no-backbone-get-set-outside-model no-non-null-assertion
217219
const formattingSettings = systemVariables.resolveAny(pythonSettings.get<IFormattingSettings>('formatting'))!;

src/client/common/installer/productInstaller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ function translateProductToModule(product: Product, purpose: ModuleNamePurpose):
285285
case Product.flake8: return 'flake8';
286286
case Product.unittest: return 'unittest';
287287
case Product.rope: return 'rope';
288+
case Product.bandit: return 'bandit';
288289
default: {
289290
throw new Error(`Product ${product} cannot be installed as a Python Module.`);
290291
}

src/client/common/installer/productNames.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Product } from '../types';
66
// tslint:disable-next-line:variable-name
77
export const ProductNames = new Map<Product, string>();
88
ProductNames.set(Product.autopep8, 'autopep8');
9+
ProductNames.set(Product.bandit, 'bandit');
910
ProductNames.set(Product.black, 'black');
1011
ProductNames.set(Product.flake8, 'flake8');
1112
ProductNames.set(Product.mypy, 'mypy');

src/client/common/installer/productService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class ProductService implements IProductService {
1212
private ProductTypes = new Map<Product, ProductType>();
1313

1414
constructor() {
15+
this.ProductTypes.set(Product.bandit, ProductType.Linter);
1516
this.ProductTypes.set(Product.flake8, ProductType.Linter);
1617
this.ProductTypes.set(Product.mypy, ProductType.Linter);
1718
this.ProductTypes.set(Product.pep8, ProductType.Linter);

src/client/common/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ export enum Product {
7878
ctags = 13,
7979
rope = 14,
8080
isort = 15,
81-
black = 16
81+
black = 16,
82+
bandit = 17
8283
}
8384

8485
export enum ModuleNamePurpose {
@@ -212,6 +213,9 @@ export interface ILintingSettings {
212213
mypyEnabled: boolean;
213214
mypyArgs: string[];
214215
mypyPath: string;
216+
banditEnabled: boolean;
217+
banditArgs: string[];
218+
banditPath: string;
215219
readonly pylintUseMinimalCheckers: boolean;
216220
}
217221
export interface IFormattingSettings {

src/client/linters/bandit.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import { CancellationToken, OutputChannel, TextDocument } from 'vscode';
5+
import '../common/extensions';
6+
import { Product } from '../common/types';
7+
import { IServiceContainer } from '../ioc/types';
8+
import { BaseLinter } from './baseLinter';
9+
import { ILintMessage, LintMessageSeverity } from './types';
10+
11+
export class Bandit extends BaseLinter {
12+
constructor(outputChannel: OutputChannel, serviceContainer: IServiceContainer) {
13+
super(Product.bandit, outputChannel, serviceContainer);
14+
}
15+
16+
protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise<ILintMessage[]> {
17+
// View all errors in bandit <= 1.5.1 (https://github.com/PyCQA/bandit/issues/371)
18+
const messages = await this.run([
19+
'-f', 'custom', '--msg-template', '{line},0,{severity},{test_id}:{msg}', '-n', '-1', document.uri.fsPath
20+
], document, cancellation);
21+
22+
messages.forEach(msg => {
23+
msg.severity = {
24+
LOW: LintMessageSeverity.Information,
25+
MEDIUM: LintMessageSeverity.Warning,
26+
HIGH: LintMessageSeverity.Error
27+
}[msg.type];
28+
});
29+
return messages;
30+
}
31+
}

0 commit comments

Comments
 (0)