Switch to hacking 3.0.1
In hacking 2.0 or later, local-check-factory was removed as it is not compatible with flake8 3.x and it is advised to use flake8's local plugins [1]. neutron-lib provided a factory to register common hacking rules, but it no longer works with hacking 2, so we need to define rules defined in neutron-lib as flake8 local check plugin [2] explicitly. This needs to be done in each neutron related project, so it is the downside of the migration to hacking 2.x (I explored a way to continue to use the factory but failed to find a good way to achieve this) but I believe it is good to migrate the newer libraries. * flake8ext decorator in neutron/hacking/checks.py is also replaced with hacking.core.flake8ext to avoid the copy-and-paste code. * neutron-lib dependency is updated as neutron-lib 2.3 added hacking 3 support. * Python modules related to coding style checks (listed in blacklist.txt in openstack/requirements repo) are dropped from lower-constraints.txt as they are not actually used in tests (other than pep8). * HackingDocTestCase is now converted into normal test cases. HackingDocTestCase depends on the internal of hacking and pycodestyle so it looks better to use normal style of writing tests. [1] https://docs.openstack.org/releasenotes/hacking/unreleased.html#relnotes-2-0-0 [2] https://flake8.pycqa.org/en/3.7.0/user/configuration.html#using-local-plugins Change-Id: I92cf50a84bb587a0649a7cffee15cce4ce37d086
This commit is contained in:
parent
08e9ec1b56
commit
52e3fee5ef
@ -2,9 +2,7 @@ alabaster==0.7.10
|
|||||||
alembic==0.8.10
|
alembic==0.8.10
|
||||||
amqp==2.1.1
|
amqp==2.1.1
|
||||||
appdirs==1.4.3
|
appdirs==1.4.3
|
||||||
astroid==2.1.0
|
|
||||||
Babel==2.3.4
|
Babel==2.3.4
|
||||||
bandit==1.1.0
|
|
||||||
bashate==0.5.1
|
bashate==0.5.1
|
||||||
beautifulsoup4==4.6.0
|
beautifulsoup4==4.6.0
|
||||||
cachetools==2.0.0
|
cachetools==2.0.0
|
||||||
@ -25,14 +23,11 @@ eventlet==0.18.2
|
|||||||
extras==1.0.0
|
extras==1.0.0
|
||||||
fasteners==0.7.0
|
fasteners==0.7.0
|
||||||
fixtures==3.0.0
|
fixtures==3.0.0
|
||||||
flake8-import-order==0.12
|
|
||||||
flake8==2.6.2
|
|
||||||
future==0.16.0
|
future==0.16.0
|
||||||
futurist==1.2.0
|
futurist==1.2.0
|
||||||
gitdb==0.6.4
|
gitdb==0.6.4
|
||||||
GitPython==1.0.1
|
GitPython==1.0.1
|
||||||
greenlet==0.4.10
|
greenlet==0.4.10
|
||||||
hacking==1.1.0
|
|
||||||
httplib2==0.9.1
|
httplib2==0.9.1
|
||||||
imagesize==0.7.1
|
imagesize==0.7.1
|
||||||
iso8601==0.1.11
|
iso8601==0.1.11
|
||||||
@ -49,7 +44,6 @@ logilab-common==1.4.1
|
|||||||
logutils==0.3.5
|
logutils==0.3.5
|
||||||
Mako==0.4.0
|
Mako==0.4.0
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
mccabe==0.2.1
|
|
||||||
mock==3.0.0
|
mock==3.0.0
|
||||||
monotonic==0.6;python_version<'3.3'
|
monotonic==0.6;python_version<'3.3'
|
||||||
mox3==0.20.0
|
mox3==0.20.0
|
||||||
@ -57,7 +51,7 @@ msgpack-python==0.4.0
|
|||||||
munch==2.1.0
|
munch==2.1.0
|
||||||
netaddr==0.7.18
|
netaddr==0.7.18
|
||||||
netifaces==0.10.4
|
netifaces==0.10.4
|
||||||
neutron-lib==2.2.0
|
neutron-lib==2.3.0
|
||||||
openstackdocstheme==1.30.0
|
openstackdocstheme==1.30.0
|
||||||
openstacksdk==0.31.2
|
openstacksdk==0.31.2
|
||||||
os-client-config==1.28.0
|
os-client-config==1.28.0
|
||||||
@ -92,19 +86,15 @@ Paste==2.0.2
|
|||||||
PasteDeploy==1.5.0
|
PasteDeploy==1.5.0
|
||||||
pbr==4.0.0
|
pbr==4.0.0
|
||||||
pecan==1.3.2
|
pecan==1.3.2
|
||||||
pep8==1.5.7
|
|
||||||
pika-pool==0.1.3
|
pika-pool==0.1.3
|
||||||
pika==0.10.0
|
pika==0.10.0
|
||||||
positional==1.2.1
|
positional==1.2.1
|
||||||
prettytable==0.7.2
|
prettytable==0.7.2
|
||||||
psutil==3.2.2
|
psutil==3.2.2
|
||||||
pycadf==1.1.0
|
pycadf==1.1.0
|
||||||
pycodestyle==2.4.0
|
|
||||||
pycparser==2.18
|
pycparser==2.18
|
||||||
pyflakes==0.8.1
|
|
||||||
Pygments==2.2.0
|
Pygments==2.2.0
|
||||||
pyinotify==0.9.6
|
pyinotify==0.9.6
|
||||||
pylint==2.2.0
|
|
||||||
PyMySQL==0.7.6
|
PyMySQL==0.7.6
|
||||||
pyOpenSSL==17.1.0
|
pyOpenSSL==17.1.0
|
||||||
pyparsing==2.1.0
|
pyparsing==2.1.0
|
||||||
|
@ -15,17 +15,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from neutron_lib.hacking import checks
|
from hacking import core
|
||||||
|
|
||||||
|
|
||||||
def flake8ext(f):
|
|
||||||
"""Decorator to indicate flake8 extension.
|
|
||||||
|
|
||||||
This is borrowed from hacking.core.flake8ext(), but at now it is used
|
|
||||||
only for unit tests to know which are neutron flake8 extensions.
|
|
||||||
"""
|
|
||||||
f.name = __name__
|
|
||||||
return f
|
|
||||||
|
|
||||||
|
|
||||||
# Guidelines for writing new hacking checks
|
# Guidelines for writing new hacking checks
|
||||||
@ -50,7 +40,7 @@ tests_imports_from2 = re.compile(r"\bfrom[\s]+neutron[\s]+import[\s]+tests\b")
|
|||||||
import_mock = re.compile(r"\bimport[\s]+mock\b")
|
import_mock = re.compile(r"\bimport[\s]+mock\b")
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_assert_called_once_with(logical_line, filename):
|
def check_assert_called_once_with(logical_line, filename):
|
||||||
"""N322 - Try to detect unintended calls of nonexistent mock methods like:
|
"""N322 - Try to detect unintended calls of nonexistent mock methods like:
|
||||||
assertCalledOnceWith
|
assertCalledOnceWith
|
||||||
@ -74,7 +64,7 @@ def check_assert_called_once_with(logical_line, filename):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_asserttruefalse(logical_line, filename):
|
def check_asserttruefalse(logical_line, filename):
|
||||||
"""N328 - Don't use assertEqual(True/False, observed)."""
|
"""N328 - Don't use assertEqual(True/False, observed)."""
|
||||||
if 'neutron/tests/' in filename:
|
if 'neutron/tests/' in filename:
|
||||||
@ -96,7 +86,7 @@ def check_asserttruefalse(logical_line, filename):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_assertempty(logical_line, filename):
|
def check_assertempty(logical_line, filename):
|
||||||
"""N330 - Enforce using assertEqual parameter ordering in case of empty
|
"""N330 - Enforce using assertEqual parameter ordering in case of empty
|
||||||
objects.
|
objects.
|
||||||
@ -111,7 +101,7 @@ def check_assertempty(logical_line, filename):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_assertisinstance(logical_line, filename):
|
def check_assertisinstance(logical_line, filename):
|
||||||
"""N331 - Enforce using assertIsInstance."""
|
"""N331 - Enforce using assertIsInstance."""
|
||||||
if 'neutron/tests/' in filename:
|
if 'neutron/tests/' in filename:
|
||||||
@ -122,7 +112,7 @@ def check_assertisinstance(logical_line, filename):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_assertequal_for_httpcode(logical_line, filename):
|
def check_assertequal_for_httpcode(logical_line, filename):
|
||||||
"""N332 - Enforce correct oredering for httpcode in assertEqual."""
|
"""N332 - Enforce correct oredering for httpcode in assertEqual."""
|
||||||
msg = ("N332: Use assertEqual(expected_http_code, observed_http_code) "
|
msg = ("N332: Use assertEqual(expected_http_code, observed_http_code) "
|
||||||
@ -133,18 +123,9 @@ def check_assertequal_for_httpcode(logical_line, filename):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_oslo_i18n_wrapper(logical_line, filename, noqa):
|
def check_oslo_i18n_wrapper(logical_line, filename, noqa):
|
||||||
"""N340 - Check for neutron.i18n usage.
|
"""N340 - Check for neutron.i18n usage."""
|
||||||
|
|
||||||
Okay(neutron/foo/bar.py): from neutron._i18n import _
|
|
||||||
Okay(neutron_fwaas/foo/bar.py): from neutron_fwaas._i18n import _
|
|
||||||
N340(neutron/foo/bar.py): from neutron.i18n import _
|
|
||||||
N340(neutron_fwaas/foo/bar.py): from neutron_fwaas.i18n import _
|
|
||||||
N340(neutron_fwaas/foo/bar.py): from neutron.i18n import _
|
|
||||||
N340(neutron_fwaas/foo/bar.py): from neutron._i18n import _
|
|
||||||
Okay(neutron/foo/bar.py): from neutron.i18n import _ # noqa
|
|
||||||
"""
|
|
||||||
|
|
||||||
if noqa:
|
if noqa:
|
||||||
return
|
return
|
||||||
@ -162,16 +143,9 @@ def check_oslo_i18n_wrapper(logical_line, filename, noqa):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_builtins_gettext(logical_line, tokens, filename, lines, noqa):
|
def check_builtins_gettext(logical_line, tokens, filename, lines, noqa):
|
||||||
"""N341 - Check usage of builtins gettext _().
|
"""N341 - Check usage of builtins gettext _()."""
|
||||||
|
|
||||||
Okay(neutron/foo.py): from neutron._i18n import _\n_('foo')
|
|
||||||
N341(neutron/foo.py): _('foo')
|
|
||||||
Okay(neutron/_i18n.py): _('foo')
|
|
||||||
Okay(neutron/i18n.py): _('foo')
|
|
||||||
Okay(neutron/foo.py): _('foo') # noqa
|
|
||||||
"""
|
|
||||||
|
|
||||||
if noqa:
|
if noqa:
|
||||||
return
|
return
|
||||||
@ -202,7 +176,7 @@ def check_builtins_gettext(logical_line, tokens, filename, lines, noqa):
|
|||||||
yield (0, msg)
|
yield (0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_no_imports_from_tests(logical_line, filename, noqa):
|
def check_no_imports_from_tests(logical_line, filename, noqa):
|
||||||
"""N343 - Production code must not import from neutron.tests.*
|
"""N343 - Production code must not import from neutron.tests.*
|
||||||
"""
|
"""
|
||||||
@ -219,7 +193,7 @@ def check_no_imports_from_tests(logical_line, filename, noqa):
|
|||||||
yield(0, msg)
|
yield(0, msg)
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_python3_no_filter(logical_line):
|
def check_python3_no_filter(logical_line):
|
||||||
"""N344 - Use list comprehension instead of filter(lambda)."""
|
"""N344 - Use list comprehension instead of filter(lambda)."""
|
||||||
|
|
||||||
@ -231,7 +205,7 @@ def check_python3_no_filter(logical_line):
|
|||||||
|
|
||||||
|
|
||||||
# TODO(boden): rehome this check to neutron-lib
|
# TODO(boden): rehome this check to neutron-lib
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_no_sqlalchemy_event_import(logical_line, filename, noqa):
|
def check_no_sqlalchemy_event_import(logical_line, filename, noqa):
|
||||||
"""N346 - Use neutron_lib.db.api.sqla_listen rather than sqlalchemy."""
|
"""N346 - Use neutron_lib.db.api.sqla_listen rather than sqlalchemy."""
|
||||||
if noqa:
|
if noqa:
|
||||||
@ -248,7 +222,7 @@ def check_no_sqlalchemy_event_import(logical_line, filename, noqa):
|
|||||||
"between unit tests")
|
"between unit tests")
|
||||||
|
|
||||||
|
|
||||||
@flake8ext
|
@core.flake8ext
|
||||||
def check_no_import_mock(logical_line, filename, noqa):
|
def check_no_import_mock(logical_line, filename, noqa):
|
||||||
"""N347 - Test code must not import mock library
|
"""N347 - Test code must not import mock library
|
||||||
"""
|
"""
|
||||||
@ -262,18 +236,3 @@ def check_no_import_mock(logical_line, filename, noqa):
|
|||||||
|
|
||||||
if re.match(import_mock, logical_line):
|
if re.match(import_mock, logical_line):
|
||||||
yield(0, msg)
|
yield(0, msg)
|
||||||
|
|
||||||
|
|
||||||
def factory(register):
|
|
||||||
checks.factory(register)
|
|
||||||
register(check_assert_called_once_with)
|
|
||||||
register(check_asserttruefalse)
|
|
||||||
register(check_assertempty)
|
|
||||||
register(check_assertisinstance)
|
|
||||||
register(check_assertequal_for_httpcode)
|
|
||||||
register(check_oslo_i18n_wrapper)
|
|
||||||
register(check_builtins_gettext)
|
|
||||||
register(check_no_imports_from_tests)
|
|
||||||
register(check_python3_no_filter)
|
|
||||||
register(check_no_sqlalchemy_event_import)
|
|
||||||
register(check_no_import_mock)
|
|
||||||
|
@ -10,16 +10,11 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import io
|
||||||
import re
|
import re
|
||||||
|
import tokenize
|
||||||
|
|
||||||
from flake8 import engine
|
|
||||||
from hacking.tests import test_doctest as hacking_doctest
|
|
||||||
import pkg_resources
|
|
||||||
import pycodestyle
|
|
||||||
import testscenarios
|
|
||||||
import testtools
|
import testtools
|
||||||
from testtools import content
|
|
||||||
from testtools import matchers
|
|
||||||
|
|
||||||
from neutron.hacking import checks
|
from neutron.hacking import checks
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
@ -30,12 +25,14 @@ CREATE_DUMMY_MATCH_OBJECT = re.compile('a')
|
|||||||
|
|
||||||
class HackingTestCase(base.BaseTestCase):
|
class HackingTestCase(base.BaseTestCase):
|
||||||
|
|
||||||
def assertLinePasses(self, func, line):
|
def assertLinePasses(self, func, line, *args, **kwargs):
|
||||||
with testtools.ExpectedException(StopIteration):
|
with testtools.ExpectedException(StopIteration):
|
||||||
next(func(line))
|
next(func(line, *args, **kwargs))
|
||||||
|
|
||||||
def assertLineFails(self, func, line):
|
def assertLineFails(self, expected_code, func, line, *args, **kwargs):
|
||||||
self.assertIsInstance(next(func(line)), tuple)
|
value = next(func(line, *args, **kwargs))
|
||||||
|
self.assertIsInstance(value, tuple)
|
||||||
|
self.assertIn(expected_code, value[1])
|
||||||
|
|
||||||
def test_assert_called_once_with(self):
|
def test_assert_called_once_with(self):
|
||||||
fail_code2 = """
|
fail_code2 = """
|
||||||
@ -201,9 +198,9 @@ class HackingTestCase(base.BaseTestCase):
|
|||||||
checks.check_no_imports_from_tests(
|
checks.check_no_imports_from_tests(
|
||||||
fail_code, "neutron/tests/test_fake.py", None))))
|
fail_code, "neutron/tests/test_fake.py", None))))
|
||||||
|
|
||||||
def test_check_python3_filter(self):
|
def test_check_python3_no_filter(self):
|
||||||
f = checks.check_python3_no_filter
|
f = checks.check_python3_no_filter
|
||||||
self.assertLineFails(f, "filter(lambda obj: test(obj), data)")
|
self.assertLineFails('N344', f, "filter(lambda obj: test(obj), data)")
|
||||||
self.assertLinePasses(f, "[obj for obj in data if test(obj)]")
|
self.assertLinePasses(f, "[obj for obj in data if test(obj)]")
|
||||||
self.assertLinePasses(f, "filter(function, range(0,10))")
|
self.assertLinePasses(f, "filter(function, range(0,10))")
|
||||||
self.assertLinePasses(f, "lambda x, y: x+y")
|
self.assertLinePasses(f, "lambda x, y: x+y")
|
||||||
@ -226,88 +223,50 @@ class HackingTestCase(base.BaseTestCase):
|
|||||||
checks.check_no_import_mock(
|
checks.check_no_import_mock(
|
||||||
fail_line, "neutron/tests/test_fake.py", None))))
|
fail_line, "neutron/tests/test_fake.py", None))))
|
||||||
|
|
||||||
|
def test_check_oslo_i18n_wrapper(self):
|
||||||
|
def _pass(line, filename, noqa=False):
|
||||||
|
self.assertLinePasses(
|
||||||
|
checks.check_oslo_i18n_wrapper,
|
||||||
|
line, filename, noqa)
|
||||||
|
|
||||||
# The following is borrowed from hacking/tests/test_doctest.py.
|
def _fail(line, filename):
|
||||||
# Tests defined in docstring is easier to understand
|
self.assertLineFails(
|
||||||
# in some cases, for example, hacking rules which take tokens as argument.
|
"N340", checks.check_oslo_i18n_wrapper,
|
||||||
|
line, filename, noqa=False)
|
||||||
|
|
||||||
# TODO(amotoki): Migrate existing unit tests above to docstring tests.
|
_pass("from neutron._i18n import _", "neutron/foo/bar.py")
|
||||||
# NOTE(amotoki): Is it better to enhance HackingDocTestCase in hacking repo to
|
_pass("from neutron_fwaas._i18n import _", "neutron_fwaas/foo/bar.py")
|
||||||
# pass filename to pycodestyle.Checker so that we can reuse it in this test.
|
_fail("from neutron.i18n import _", "neutron/foo/bar.py")
|
||||||
# I am not sure whether unit test class is public.
|
_fail("from neutron_fwaas.i18n import _", "neutron_fwaas/foo/bar.py")
|
||||||
|
_fail("from neutron.i18n import _", "neutron_fwaas/foo/bar.py")
|
||||||
|
_fail("from neutron._i18n import _", "neutron_fwaas/foo/bar.py")
|
||||||
|
_pass("from neutron.i18n import _", "neutron/foo/bar.py", noqa=True)
|
||||||
|
|
||||||
SELFTEST_REGEX = re.compile(r'\b(Okay|N\d{3})(\((\S+)\))?:\s(.*)')
|
def test_check_builtins_gettext(self):
|
||||||
|
# NOTE: check_builtins_gettext() takes two additional arguments,
|
||||||
|
# "tokens" and "lines". "tokens" is a list of tokens from the target
|
||||||
|
# logical line, and "lines" is a list of lines of the input file.
|
||||||
|
# Considering this, test functions (_pass and _fail) take "lines"
|
||||||
|
# as an argument and calls the hacking check function line by line
|
||||||
|
# after generating tokens from the target line.
|
||||||
|
|
||||||
|
def _get_tokens(line):
|
||||||
|
return tokenize.tokenize(io.BytesIO(line.encode('utf-8')).readline)
|
||||||
|
|
||||||
# Each scenario is (name, dict(filename=..., lines=.., options=..., code=...))
|
def _pass(lines, filename, noqa=False):
|
||||||
file_cases = []
|
for line in lines:
|
||||||
|
self.assertLinePasses(
|
||||||
|
checks.check_builtins_gettext,
|
||||||
|
line, _get_tokens(line), filename, lines, noqa)
|
||||||
|
|
||||||
|
def _fail(lines, filename):
|
||||||
|
for line in lines:
|
||||||
|
self.assertLineFails(
|
||||||
|
"N341", checks.check_builtins_gettext,
|
||||||
|
line, _get_tokens(line), filename, lines, noqa=False)
|
||||||
|
|
||||||
class HackingDocTestCase(hacking_doctest.HackingTestCase):
|
_pass(["from neutron._i18n import _", "_('foo')"], "neutron/foo.py")
|
||||||
|
_fail(["_('foo')"], "neutron/foo.py")
|
||||||
scenarios = file_cases
|
_pass(["_('foo')"], "neutron/_i18n.py")
|
||||||
|
_pass(["_('foo')"], "neutron/i18n.py")
|
||||||
def test_pycodestyle(self):
|
_pass(["_('foo')"], "neutron/foo.py", noqa=True)
|
||||||
|
|
||||||
# NOTE(jecarey): Add tests marked as off_by_default to enable testing
|
|
||||||
turn_on = set(['H106'])
|
|
||||||
if self.options.select:
|
|
||||||
turn_on.update(self.options.select)
|
|
||||||
self.options.select = tuple(turn_on)
|
|
||||||
self.options.ignore = ('N530',)
|
|
||||||
|
|
||||||
report = pycodestyle.BaseReport(self.options)
|
|
||||||
checker = pycodestyle.Checker(filename=self.filename, lines=self.lines,
|
|
||||||
options=self.options, report=report)
|
|
||||||
checker.check_all()
|
|
||||||
self.addDetail('doctest', content.text_content(self.raw))
|
|
||||||
if self.code == 'Okay':
|
|
||||||
self.assertThat(
|
|
||||||
len(report.counters),
|
|
||||||
matchers.Not(matchers.GreaterThan(
|
|
||||||
len(self.options.benchmark_keys))),
|
|
||||||
"incorrectly found %s" % ', '.join(
|
|
||||||
[key for key in report.counters
|
|
||||||
if key not in self.options.benchmark_keys]))
|
|
||||||
else:
|
|
||||||
self.addDetail('reason',
|
|
||||||
content.text_content("Failed to trigger rule %s" %
|
|
||||||
self.code))
|
|
||||||
self.assertIn(self.code, report.counters)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_lines(check):
|
|
||||||
for line in check.__doc__.splitlines():
|
|
||||||
line = line.lstrip()
|
|
||||||
match = SELFTEST_REGEX.match(line)
|
|
||||||
if match is None:
|
|
||||||
continue
|
|
||||||
yield (line, match.groups())
|
|
||||||
|
|
||||||
|
|
||||||
def load_tests(loader, tests, pattern):
|
|
||||||
|
|
||||||
default_checks = [e.name for e
|
|
||||||
in pkg_resources.iter_entry_points('flake8.extension')]
|
|
||||||
flake8_style = engine.get_style_guide(
|
|
||||||
parse_argv=False,
|
|
||||||
# We are testing neutron-specific hacking rules, so there is no need
|
|
||||||
# to run the checks registered by hacking or other flake8 extensions.
|
|
||||||
ignore=default_checks)
|
|
||||||
options = flake8_style.options
|
|
||||||
|
|
||||||
for name, check in checks.__dict__.items():
|
|
||||||
if not hasattr(check, 'name'):
|
|
||||||
continue
|
|
||||||
if check.name != checks.__name__:
|
|
||||||
continue
|
|
||||||
if not check.__doc__:
|
|
||||||
continue
|
|
||||||
for (lineno, (raw, line)) in enumerate(_get_lines(check)):
|
|
||||||
code, __, filename, source = line
|
|
||||||
lines = [part.replace(r'\t', '\t') + '\n'
|
|
||||||
for part in source.split(r'\n')]
|
|
||||||
file_cases.append(("%s-line-%s" % (name, lineno),
|
|
||||||
dict(lines=lines, raw=raw, options=options,
|
|
||||||
code=code, filename=filename)))
|
|
||||||
return testscenarios.load_tests_apply_scenarios(loader, tests, pattern)
|
|
||||||
|
@ -16,7 +16,7 @@ Jinja2>=2.10 # BSD License (3 clause)
|
|||||||
keystonemiddleware>=4.17.0 # Apache-2.0
|
keystonemiddleware>=4.17.0 # Apache-2.0
|
||||||
netaddr>=0.7.18 # BSD
|
netaddr>=0.7.18 # BSD
|
||||||
netifaces>=0.10.4 # MIT
|
netifaces>=0.10.4 # MIT
|
||||||
neutron-lib>=2.2.0 # Apache-2.0
|
neutron-lib>=2.3.0 # Apache-2.0
|
||||||
python-neutronclient>=6.7.0 # Apache-2.0
|
python-neutronclient>=6.7.0 # Apache-2.0
|
||||||
tenacity>=4.4.0 # Apache-2.0
|
tenacity>=4.4.0 # Apache-2.0
|
||||||
SQLAlchemy>=1.2.0 # MIT
|
SQLAlchemy>=1.2.0 # MIT
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# The order of packages is significant, because pip processes them in the order
|
# The order of packages is significant, because pip processes them in the order
|
||||||
# of appearance. Changing the order has an impact on the overall integration
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
hacking>=1.1.0,<1.2.0 # Apache-2.0
|
hacking>=3.0.1,<3.1.0 # Apache-2.0
|
||||||
bandit!=1.6.0,>=1.1.0 # Apache-2.0
|
bandit!=1.6.0,>=1.1.0 # Apache-2.0
|
||||||
coverage!=4.4,>=4.0 # Apache-2.0
|
coverage!=4.4,>=4.0 # Apache-2.0
|
||||||
fixtures>=3.0.0 # Apache-2.0/BSD
|
fixtures>=3.0.0 # Apache-2.0/BSD
|
||||||
flake8-import-order==0.12 # LGPLv3
|
flake8-import-order==0.12 # LGPLv3
|
||||||
pycodestyle>=2.0.0 # MIT
|
|
||||||
python-subunit>=1.0.0 # Apache-2.0/BSD
|
python-subunit>=1.0.0 # Apache-2.0/BSD
|
||||||
testtools>=2.2.0 # MIT
|
testtools>=2.2.0 # MIT
|
||||||
testresources>=2.0.0 # Apache-2.0/BSD
|
testresources>=2.0.0 # Apache-2.0/BSD
|
||||||
|
16
tox.ini
16
tox.ini
@ -169,9 +169,23 @@ show-source = true
|
|||||||
exclude = ./.*,build,dist,doc
|
exclude = ./.*,build,dist,doc
|
||||||
import-order-style = pep8
|
import-order-style = pep8
|
||||||
|
|
||||||
|
[flake8:local-plugins]
|
||||||
|
extension =
|
||||||
|
# Checks specific to neutron repo
|
||||||
|
N340 = neutron.hacking.checks:check_oslo_i18n_wrapper
|
||||||
|
N341 = neutron.hacking.checks:check_builtins_gettext
|
||||||
|
# Checks from neutron-lib
|
||||||
|
N521 = neutron_lib.hacking.checks:use_jsonutils
|
||||||
|
N524 = neutron_lib.hacking.checks:check_no_contextlib_nested
|
||||||
|
N529 = neutron_lib.hacking.checks:no_mutable_default_args
|
||||||
|
N530 = neutron_lib.hacking.checks:check_neutron_namespace_imports
|
||||||
|
N532 = neutron_lib.hacking.translation_checks:check_log_warn_deprecated
|
||||||
|
N534 = neutron_lib.hacking.translation_checks:check_raised_localized_exceptions
|
||||||
|
N536 = neutron_lib.hacking.checks:assert_equal_none
|
||||||
|
N537 = neutron_lib.hacking.translation_checks:no_translate_logs
|
||||||
|
|
||||||
[hacking]
|
[hacking]
|
||||||
import_exceptions = neutron._i18n
|
import_exceptions = neutron._i18n
|
||||||
local-check-factory = neutron.hacking.checks.factory
|
|
||||||
|
|
||||||
[testenv:bandit]
|
[testenv:bandit]
|
||||||
envdir = {toxworkdir}/shared
|
envdir = {toxworkdir}/shared
|
||||||
|
Loading…
x
Reference in New Issue
Block a user