Fix blacklist filtering

Blacklist is now available as multiple plugin codes instead of
single B001. Filtering should work on each of those code separately.
This fixes both include and exclude.

Change-Id: I1426eacfe7d441431b52ff330066413ac0f01d5f
Closes-bug: 1576321
This commit is contained in:
Stanisław Pitucha 2016-08-16 17:59:21 +10:00 committed by Tim Kelsey
parent 8fae9a630f
commit 2e4e7cd2f7
2 changed files with 43 additions and 21 deletions

View File

@ -42,13 +42,30 @@ class BanditTestSet():
inc = set(profile.get('include', []))
exc = set(profile.get('exclude', []))
all_blacklist_tests = set()
for _node, tests in six.iteritems(extman.blacklist):
all_blacklist_tests.update(t['id'] for t in tests)
# this block is purely for backwards compatibility, the rules are as
# follows:
# B001,B401 means B401
# B401 means B401
# B001 means all blacklist tests
if 'B001' in inc:
if not inc.intersection(all_blacklist_tests):
inc.update(all_blacklist_tests)
inc.discard('B001')
if 'B001' in exc:
if not exc.intersection(all_blacklist_tests):
exc.update(all_blacklist_tests)
exc.discard('B001')
if inc:
filtered = inc
else:
filtered = set(extman.plugins_by_id.keys())
filtered.update(extman.builtin)
for node, tests in six.iteritems(extman.blacklist):
filtered.update(t['id'] for t in tests)
filtered.update(all_blacklist_tests)
return filtered - exc
def _load_builtins(self, filtering, profile):
@ -59,27 +76,25 @@ class BanditTestSet():
self.name = name
self.plugin = plugin
results = []
extman = extension_loader.MANAGER
blacklist = profile.get('blacklist')
if not blacklist: # not overriden by legacy data
blacklist = {}
for node, tests in six.iteritems(extman.blacklist):
values = [t for t in tests if t['id'] in filtering]
if values:
blacklist[node] = values
if 'B001' in filtering:
extman = extension_loader.MANAGER
blacklist = profile.get('blacklist')
if not blacklist: # not overridden by legacy data
blacklist = {}
for node, tests in six.iteritems(extman.blacklist):
values = [t for t in tests if t['id'] in filtering]
if values:
blacklist[node] = values
if not blacklist:
return []
# this dresses up the blacklist to look like a plugin, but
# the '_checks' data comes from the blacklist information.
# the '_config' is the filtered blacklist data set.
setattr(blacklisting.blacklist, "_test_id", 'B001')
setattr(blacklisting.blacklist, "_checks", blacklist.keys())
setattr(blacklisting.blacklist, "_config", blacklist)
results.append(Wrapper('blacklist', blacklisting.blacklist))
return results
# this dresses up the blacklist to look like a plugin, but
# the '_checks' data comes from the blacklist information.
# the '_config' is the filtered blacklist data set.
setattr(blacklisting.blacklist, "_test_id", 'B001')
setattr(blacklisting.blacklist, "_checks", blacklist.keys())
setattr(blacklisting.blacklist, "_config", blacklist)
return [Wrapper('blacklist', blacklisting.blacklist)]
def _load_tests(self, config, plugins):
'''Builds a dict mapping tests to node types.'''

View File

@ -101,6 +101,13 @@ class BanditTestSetTests(testtools.TestCase):
self.assertEqual(len(ts.get_tests('ImportFrom')), 0)
self.assertEqual(len(ts.get_tests('Call')), 0)
def test_profile_exclude_builtin_blacklist_specific(self):
profile = {'exclude': ['B302', 'B401']}
ts = test_set.BanditTestSet(self.config, profile)
self.assertEqual(len(ts.get_tests('Import')), 0)
self.assertEqual(len(ts.get_tests('ImportFrom')), 0)
self.assertEqual(len(ts.get_tests('Call')), 0)
def test_profile_filter_blacklist_none(self):
ts = test_set.BanditTestSet(self.config)
blacklist = ts.get_tests('Import')[0]