diff --git a/lower-constraints.txt b/lower-constraints.txt index b53dfe6b9..9e08fa04d 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -22,12 +22,10 @@ eventlet==0.20.0 extras==1.0.0 fasteners==0.14.1 fixtures==3.0.0 -flake8==2.5.5 future==0.16.0 futurist==1.6.0 gnocchiclient==3.3.1 greenlet==0.4.13 -hacking==0.12.0 idna==2.6 iso8601==0.1.12 Jinja2==2.10 @@ -77,14 +75,12 @@ Paste==2.0.3 PasteDeploy==1.5.2 pbr==3.1.1 pecan==1.2.1 -pep8==1.5.7 pika==0.10.0 pika-pool==0.1.3 ply==3.11 prettytable==0.7.2 pyasn1==0.4.2 pycadf==2.7.0 -pyflakes==0.8.1 pyinotify==0.9.6 PyJWT==1.6.0 PyMySQL==0.8.0 diff --git a/test-requirements.txt b/test-requirements.txt index 62da7ffec..222e763ae 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,7 +2,7 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -hacking>=1.1.0 # Apache-2.0 +hacking>=3.0,<3.1.0 # Apache-2.0 coverage>=4.5.1 # Apache-2.0 python-subunit>=1.2.0 # Apache-2.0/BSD oslotest>=3.3.0 # Apache-2.0 diff --git a/tox.ini b/tox.ini index bc6a20532..609451b61 100644 --- a/tox.ini +++ b/tox.ini @@ -65,9 +65,25 @@ filename = *.py,app.wsgi exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools/datasource-scaffold [hacking] -local-check-factory = vitrage.hacking.checks.factory import_exceptions = vitrage.i18n +[flake8:local-plugins] +extension = + V316 = checks:assert_true_instance + V329 = checks:check_assert_true_false + V317 = checks:assert_equal_type + V319 = checks:no_translate_logs + V320 = checks:no_direct_use_of_unicode_function + V327 = checks:no_mutable_default_args + V321 = checks:check_no_contextlib_nested + V322 = checks:dict_constructor_with_list_copy + V323 = checks:check_python3_xrange + V324 = checks:check_python3_no_iteritems + V325 = checks:check_python3_no_iterkeys + V326 = checks:check_python3_no_itervalues + V328 = checks:no_log_warn +paths = ./vitrage/hacking + [testenv:releasenotes] deps = -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt} diff --git a/vitrage/hacking/checks.py b/vitrage/hacking/checks.py index f73710ea5..74f5af466 100644 --- a/vitrage/hacking/checks.py +++ b/vitrage/hacking/checks.py @@ -15,6 +15,8 @@ import re +from hacking import core + mutable_default_args = re.compile(r"^\s*def .+\((.+={\}|.+=\[\])") asse_trueinst_re = re.compile( @@ -38,6 +40,7 @@ translated_logs = re.compile( dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?([(\[])") +@core.flake8ext def assert_true_instance(logical_line): """Check for assertTrue(isinstance(a, b)) sentences @@ -47,6 +50,7 @@ def assert_true_instance(logical_line): yield (0, "V316: assertTrue(isinstance(a, b)) sentences not allowed") +@core.flake8ext def assert_equal_type(logical_line): """Check for assertEqual(type(A), B) sentences @@ -56,6 +60,7 @@ def assert_equal_type(logical_line): yield (0, "V317: assertEqual(type(A), B) sentences not allowed") +@core.flake8ext def no_translate_logs(logical_line): """Check for use of LOG.*(_( @@ -65,6 +70,7 @@ def no_translate_logs(logical_line): yield (0, "V319: Don't translate logs") +@core.flake8ext def no_direct_use_of_unicode_function(logical_line): """Check for use of unicode() builtin @@ -74,6 +80,7 @@ def no_direct_use_of_unicode_function(logical_line): yield(0, "V320: Use six.text_type() instead of unicode()") +@core.flake8ext def check_no_contextlib_nested(logical_line): msg = ("V321: contextlib.nested is deprecated since Python 2.7. See " "https://docs.python.org/2/library/contextlib.html#contextlib." @@ -83,6 +90,7 @@ def check_no_contextlib_nested(logical_line): yield(0, msg) +@core.flake8ext def dict_constructor_with_list_copy(logical_line): msg = ("V322: Must use a dict comprehension instead of a dict constructor " "with a sequence of key-value pairs.") @@ -90,12 +98,14 @@ def dict_constructor_with_list_copy(logical_line): yield (0, msg) +@core.flake8ext def check_python3_xrange(logical_line): if re.search(r"\bxrange\s*\(", logical_line): yield(0, "V323: Do not use xrange. Use range, or six.moves.range for " "large loops.") +@core.flake8ext def check_python3_no_iteritems(logical_line): msg = ("V324: Use six.iteritems() or dict.items() instead of " "dict.iteritems().") @@ -103,6 +113,7 @@ def check_python3_no_iteritems(logical_line): yield(0, msg) +@core.flake8ext def check_python3_no_iterkeys(logical_line): msg = ("V325: Use six.iterkeys() or dict.keys() instead of " "dict.iterkeys().") @@ -110,6 +121,7 @@ def check_python3_no_iterkeys(logical_line): yield(0, msg) +@core.flake8ext def check_python3_no_itervalues(logical_line): msg = ("V326: Use six.itervalues() or dict.values instead of " "dict.itervalues().") @@ -117,12 +129,14 @@ def check_python3_no_itervalues(logical_line): yield(0, msg) +@core.flake8ext def no_mutable_default_args(logical_line): msg = "V327: Method's default argument shouldn't be mutable!" if mutable_default_args.match(logical_line): yield (0, msg) +@core.flake8ext def no_log_warn(logical_line): """Disallow 'LOG.warn(' @@ -132,6 +146,7 @@ def no_log_warn(logical_line): yield(0, 'V328: Use LOG.warning() rather than LOG.warn()') +@core.flake8ext def check_assert_true_false(logical_line): """V329 - Don't use assertEqual(True/False, observed).""" if re.search(r"assertEqual\(\s*True,[^,]*(,[^,]*)?", logical_line): @@ -150,19 +165,3 @@ def check_assert_true_false(logical_line): msg = ("V329: Use assertFalse(observed) instead of " "assertEqual(False, observed)") yield (0, msg) - - -def factory(register): - register(assert_true_instance) - register(check_assert_true_false) - register(assert_equal_type) - register(no_translate_logs) - register(no_direct_use_of_unicode_function) - register(no_mutable_default_args) - register(check_no_contextlib_nested) - register(dict_constructor_with_list_copy) - register(check_python3_xrange) - register(check_python3_no_iteritems) - register(check_python3_no_iterkeys) - register(check_python3_no_itervalues) - register(no_log_warn) diff --git a/vitrage/tests/unit/hacking/test_hacking.py b/vitrage/tests/unit/hacking/test_hacking.py index 5149564a2..4307453fc 100644 --- a/vitrage/tests/unit/hacking/test_hacking.py +++ b/vitrage/tests/unit/hacking/test_hacking.py @@ -13,7 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import inspect from testtools import matchers @@ -199,17 +198,3 @@ class HackingTestCase(base.BaseTest): self.assertThat(list(checks.check_assert_true_false( false_fail_code2)), matchers.HasLength(1)) self.assertFalse(list(checks.check_assert_true_false(false_pass_code))) - - def test_factory(self): - class Register(object): - def __init__(self): - self.funcs = [] - - def __call__(self, _func): - self.funcs.append(_func) - - register = Register() - checks.factory(register) - for name, func in inspect.getmembers(checks, inspect.isfunction): - if name != 'factory': - self.assertIn(func, register.funcs)