Skip to content

Commit

Permalink
VultureBear: Convert to global bear
Browse files Browse the repository at this point in the history
Fixes coala#817
  • Loading branch information
sils committed Nov 23, 2016
1 parent 6dee81a commit 7e9c19b
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 26 deletions.
47 changes: 34 additions & 13 deletions bears/python/VultureBear.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
from coalib.bearlib.abstractions.Linter import linter
from coalib.bears.requirements.PipRequirement import PipRequirement
import re
from shutil import which

from coalib.bears.GlobalBear import GlobalBear
from coalib.bears.requirements.PipRequirement import PipRequirement
from coalib.misc.Shell import run_shell_command
from coalib.results.Result import Result

@linter(executable='vulture',
output_format='regex',
output_regex=r'(?P<filename>.*):(?P<line>.*):\s*(?P<message>.*)')
class VultureBear:
"""
Checks Python code for unused variables and functions using ``vulture``.

See <https://bitbucket.org/jendrikseipp/vulture> for more information.
"""
class VultureBear(GlobalBear):
LANGUAGES = {'Python', 'Python 3'}
REQUIREMENTS = {PipRequirement('vulture', '0.10.0')}
AUTHORS = {'The coala developers'}
Expand All @@ -19,6 +16,30 @@ class VultureBear:
ASCIINEMA_URL = 'https://asciinema.org/a/82256'
CAN_DETECT = {'Unused Code'}

@staticmethod
def create_arguments(filename, file, config_file):
return filename,
EXECUTABLE = 'vulture'
OUTPUT_REGEX = re.compile(
r'(?P<filename>.*):(?P<line>.*):\s*(?P<message>.*)')

@classmethod
def check_prerequisites(cls):
return ('Vulture is missing. Make sure to install it using '
'`pip3 install vulture`.'
if which('vulture') is None else True)

def run(self):
"""
Check Python code for unused variables and functions using `vulture`.
See <https://bitbucket.org/jendrikseipp/vulture> for more information.
"""
stdout_output, _ = run_shell_command(
(self.EXECUTABLE,) +
tuple(filename for filename in self.file_dict.keys()),
cwd=self.get_config_dir())

for match in re.finditer(self.OUTPUT_REGEX, stdout_output):
groups = match.groupdict()
yield Result.from_values(origin=self,
message=groups['message'],
file=groups['filename'],
line=int(groups['line']))
82 changes: 69 additions & 13 deletions tests/python/VultureBearTest.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,74 @@
import unittest
from queue import Queue
from textwrap import dedent
from contextlib import ExitStack, contextmanager

from coala_utils.ContextManagers import prepare_file
from coalib.settings.Section import Section

from bears.python.VultureBear import VultureBear
from tests.LocalBearTestHelper import verify_local_bear


good_file = """
x = 2
print(x)
"""
class VultureBearTest(unittest.TestCase):

def setUp(self):
self.section = Section('name')
self.queue = Queue()
self.file_dict = {}
self.uut = VultureBear(self.file_dict, self.section, self.queue)

def get_results(self, *files):
"""
Runs the bears with the files given.
:param files: A list of lists containing the file lines. File contents
will automatically be dedented and splitted.
:return: A list of the results of the uut!
"""
with ExitStack() as stack:
for file in files:
@contextmanager
def prep_file():
with prepare_file(
dedent(file).splitlines(True),
None,
tempfile_kwargs={'suffix': '.py'}
) as lines_filename:
lines, filename = lines_filename
self.file_dict[filename] = file
yield

stack.enter_context(prep_file())

return list(self.uut.run())

def test_used_variable(self):
good_file = """
x = 2
print(x)
"""
self.assertEqual(len(self.get_results(good_file)), 0)

def test_unused_variable(self):
bad_file = """
b = 10
a = 12
print(a)
"""
self.assertEqual(len(self.get_results(bad_file)), 1)

def test_unused_parameter(self):
bad_file = """
def test(a):
return 1
bad_file = """
b = 10
a = 12
print(a)
"""
test(1)
"""
self.assertEqual(len(self.get_results(bad_file)), 1)

VultureBear = verify_local_bear(VultureBear,
valid_files=(good_file,),
invalid_files=(bad_file,))
def test_unused_function(self):
bad_file = """
def test(a):
return a
"""
self.assertEqual(len(self.get_results(bad_file)), 1)

0 comments on commit 7e9c19b

Please sign in to comment.