Skip to content

Commit

Permalink
Add support for bandit
Browse files Browse the repository at this point in the history
This adds preliminary support for the bandit (https://github.com/PyCQA/bandit)
checker. No command-line options are yet supported -- notably, `ignore-codes`
is not yet respected for this checker.
  • Loading branch information
msherry committed May 7, 2018
1 parent 8102cf7 commit 3629cfb
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
63 changes: 54 additions & 9 deletions bin/pycheckers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@

from __future__ import absolute_import, division, print_function

from argparse import ArgumentParser, ArgumentTypeError
from functools import partial
import os
import re
from subprocess import call, Popen, PIPE
import sys
from argparse import ArgumentParser, ArgumentTypeError
from csv import DictReader
from functools import partial
from subprocess import PIPE, Popen, call

# TODO: Ignore the type of ConfigParser until
# TODO: Ignore the type of conditional imports until
# https://github.com/python/mypy/issues/1107 is fixed
try:
from StringIO import StringIO # type: ignore
except ImportError:
from io import StringIO # type: ignore
try:
from configparser import ConfigParser # type: ignore
except ImportError:
Expand Down Expand Up @@ -115,14 +120,17 @@ def name(self):

def get_run_flags(self, _filepath):
# type: (str) -> Iterable[str]
"""Called to build up the list of command-line arguments to pass to the checker."""
return ()

def get_env_vars(self):
# type: () -> Dict[str, str]
"""Called to return any environment variables that should be set for the checker."""
return {}

def get_filepath(self, filepath):
# type: (str) -> str
"""Called to manipulate the path to the file being checked, for checkers that need it."""
return filepath

def user_defined_command_line(self, _filepath):
Expand Down Expand Up @@ -155,15 +163,21 @@ def construct_args(self, filepath):
args.append(self.get_filepath(filepath))
return args

def fixup_data(self, _line, data, _filepath):
# type: (str, Dict[str, str], str) -> Dict[str, str]
return data

def process_output(self, line):
# type: (str) -> Optional[Dict[str, str]]
"""Use the matcher to extract fields from the line.
self.output_matcher can be a function, or a regex that yields named matches."""
if callable(self.output_matcher):
return self.output_matcher(line)
m = self.output_matcher.match(line)
return m.groupdict() if m else None

def fixup_data(self, _line, data, _filepath):
# type: (str, Dict[str, str], str) -> Dict[str, str]
"""Called to perform any optional cleanups of the parsed data."""
return data

def process_returncode(self, _returncode):
# type: (int) -> bool
"""Return True if the checker's returncode indicates successful check, False otherwise"""
Expand Down Expand Up @@ -538,16 +552,47 @@ def name(self):
return 'mypy3'


class BanditRunner(LintRunner):

command = 'bandit'
got_header = False

def output_matcher(self, line): # type: ignore
# type: (str) -> Optional[Dict[str, str]]
keys = ['filename', 'test_name', 'test_id', 'issue_severity',
'issue_confidence', 'issue_text', 'line_number', 'line_range']
f = StringIO(line)
reader = DictReader(f, fieldnames=keys)
res = next(reader)
if not self.got_header:
# This line was the CSV header, not a real error
self.got_header = True
return None
if res and res.get('test_id'):
return {
'description': res['issue_text'],
'error_number': res['test_id'],
'filename': res['filename'],
'level': 'WARNING',
'line_number': res['line_number'],
}
return None

def get_run_flags(self, _filepath):
# type: (str) -> Iterable[str]
return ['-f', 'csv']


RUNNERS = {
'pyflakes': PyflakesRunner,
'flake8': Flake8Runner,
'pep8': Pep8Runner,
'pylint': PylintRunner,
'mypy2': MyPy2Runner,
'mypy3': MyPy3Runner,
'bandit': BanditRunner,
}


def get_options_from_file(file_path):
# type: (str) -> Dict[str, Any]
"""Parse options from the config file at `file_path` and return them as a dict"""
Expand Down
3 changes: 2 additions & 1 deletion flycheck-pycheckers.el
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@
(const :tag "flake8" flake8)
(const :tag "pyflakes" pyflakes)
(const :tag "mypy 2" mypy2)
(const :tag "mypy 3" mypy3)))
(const :tag "mypy 3" mypy3)
(const :tag "bandit" mypy3)))

(flycheck-def-option-var flycheck-pycheckers-ignore-codes
'("C0411" "C0413" "C0103" "C0111" "W0142" "W0201" "W0232" "W0403" "W0511"
Expand Down

0 comments on commit 3629cfb

Please sign in to comment.