Skip to content

Commit 6d4ae18

Browse files
committed
Pycheckbear.py: Add new PyCheckBear
New Bear is added to find bugs in python file. Closes #2151
1 parent fd5a5a7 commit 6d4ae18

File tree

7 files changed

+103
-0
lines changed

7 files changed

+103
-0
lines changed

.ci/deps.apt.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set -x
1010
export DEBIAN_FRONTEND=noninteractive
1111

1212
deps="libclang1-3.4 astyle indent mono-mcs chktex r-base julia golang-go luarocks verilator cppcheck flawfinder devscripts mercurial"
13+
deps="libclang1-3.4 indent mono-mcs chktex r-base julia golang-go luarocks verilator cppcheck flawfinder devscripts pychecker"
1314
deps_infer="m4 opam"
1415

1516
case $CIRCLE_BUILD_IMAGE in

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ addons:
129129
- php-codesniffer
130130
- r-base
131131
- verilator
132+
- pychecker
132133

133134
cache:
134135
pip: true

bears/python/PyCheckerBear.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import shlex
2+
3+
from coalib.bearlib.abstractions.Linter import linter
4+
from dependency_management.requirements.DistributionRequirement import (
5+
DistributionRequirement)
6+
7+
8+
@linter(executable='pychecker',
9+
output_format='regex',
10+
output_regex=r'(?P<filename>\w+\.py):(?P<line>\d+): '
11+
r'(?P<message>.*)')
12+
class PyCheckerBear:
13+
"""
14+
Find bugs in your Python source code.
15+
The code for each function, class, and method is checked for possible
16+
problems. Checks for unused globals and locals(module or variable), unused
17+
method arguments and using a variable before setting it or if you are
18+
redefining a function/class/method in the same scope.
19+
"""
20+
LANGUAGES = {'Python', 'Python 2', 'Python 3'}
21+
REQUIREMENTS = {DistributionRequirement(apt_get='pychecker')}
22+
AUTHORS = {'The coala developers'}
23+
AUTHORS_EMAILS = {'[email protected]'}
24+
LICENSE = 'AGPL-3.0'
25+
CAN_DETECT = {'Unused method/function arguments',
26+
'No doc string', 'Redefining'}
27+
SEE_MORE = 'http://pychecker.sourceforge.net/'
28+
29+
@staticmethod
30+
def create_arguments(filename, file, config_file,
31+
pychecker_cli_options: str = ''):
32+
"""
33+
:param pychecker_cli_options: Command line options you wish to be
34+
passed to pychecker.
35+
"""
36+
args = ()
37+
if pychecker_cli_options:
38+
args += tuple(shlex.split(pychecker_cli_options))
39+
40+
return args + (filename,)

tests/python/PycheckerBearTest.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from queue import Queue
2+
import os.path
3+
4+
from coalib.settings.Section import Section
5+
from coalib.results.Result import Result
6+
from coalib.testing.LocalBearTestHelper import LocalBearTestHelper
7+
from coalib.testing.BearTestHelper import generate_skip_decorator
8+
9+
from bears.python.PyCheckerBear import PyCheckerBear
10+
11+
12+
def get_testfile_path(file):
13+
return os.path.join(os.path.dirname(__file__),
14+
'pychecker_test_files', file)
15+
16+
17+
def load_testfiles(name):
18+
with open(get_testfile_path(name)) as f1:
19+
contents = f1.read().splitlines(True)
20+
21+
return contents
22+
23+
24+
@generate_skip_decorator(PyCheckerBear)
25+
class PyCheckerBearTest(LocalBearTestHelper):
26+
27+
def setUp(self):
28+
self.uut = PyCheckerBear(Section('name'), Queue())
29+
self.good_file = get_testfile_path('good_file.py')
30+
self.bad_file = get_testfile_path('bad_file.py')
31+
self.maxDiff = None
32+
33+
def test_good_file(self):
34+
self.check_results(self.uut, load_testfiles('good_file.py'),
35+
[],
36+
self.good_file)
37+
38+
def test_bad_file(self):
39+
self.check_results(self.uut, load_testfiles('bad_file.py'),
40+
[Result.from_values('PyCheckerBear',
41+
'Parameter (c) not used',
42+
self.bad_file,
43+
line=1)],
44+
self.bad_file)
45+
46+
def test_cli_options(self):
47+
self.check_results(self.uut, load_testfiles('bad_file.py'),
48+
[],
49+
self.bad_file,
50+
settings={'pychecker_cli_options': '--argsused=off'}
51+
)

tests/python/pychecker_test_files/__init__.py

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def multiply(a, b, c):
2+
return a * b
3+
4+
5+
result = multiply(1, 2, 3)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def multiply(a, b, c):
2+
return a * b * c
3+
4+
5+
result = multiply(1, 2, 3)

0 commit comments

Comments
 (0)