diff --git a/HACKING.rst b/HACKING.rst index d4d792e..3c726b3 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -25,6 +25,7 @@ General - [H201] Do not write ``except:``, use ``except Exception:`` at the very least - [H101] Include your name with TODOs as in ``# TODO(yourname)`` - [H105] Don't use author tags. +- [H106] Don't put vim configuration in source files (off by default) - Do not shadow a built-in or reserved word. Example:: def list(): diff --git a/README.rst b/README.rst index 71dbbdb..ae54b12 100644 --- a/README.rst +++ b/README.rst @@ -53,6 +53,8 @@ But, as always, remember that these are Guidelines. Treat them as such. There are always times for exceptions. All new rules should support noqa. +If a check needs to be staged in, or it does not apply to every project or its +branch, it can be added as off by default. Requirements ------------ diff --git a/hacking/checks/vim_check.py b/hacking/checks/vim_check.py new file mode 100644 index 0000000..17c501a --- /dev/null +++ b/hacking/checks/vim_check.py @@ -0,0 +1,39 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import re + +from hacking import core + + +vim_header_re = re.compile(r"^#\s+vim?:.+") + + +@core.flake8ext +@core.off_by_default +def no_vim_headers(physical_line, line_number, lines): + r"""Check for vim editor configuration in source files. + + By default vim modelines can only appear in the first or + last 5 lines of a source file. + + Examples: + H106: # vim: set tabstop=4 shiftwidth=4\n#\n#\n#\n#\n# + H106: # Lic\n# vim: set tabstop=4 shiftwidth=4\n#\n#\n#\n#\n# + H106: # Lic\n#\n#\n#\n#\n#\n#\n#\n#\n# vim: set tabstop=4 shiftwidth=4 + Okay: # Lic\n#\n#\n#\n#\n#\n#\n# + Okay: # viminal hill is located in Rome + Okay: # vim, ze nemluvis cesky + """ + if ((line_number <= 5 or line_number > len(lines) - 5) and + vim_header_re.match(physical_line)): + return 0, "H106: Don't put vim configuration in source files" diff --git a/hacking/core.py b/hacking/core.py index e43db20..338f81f 100644 --- a/hacking/core.py +++ b/hacking/core.py @@ -40,6 +40,21 @@ def flake8ext(f): f.name = __name__ f.version = '0.0.1' f.skip_on_py3 = False + if not hasattr(f, 'off_by_default'): + f.off_by_default = False + return f + + +def off_by_default(f): + """Decorator to turn check off by default. + + To enable the check use the flake8 select setting in + tox.ini. + + flake8 documentation: + http://flake8.readthedocs.org/en/latest/extensions.html. + """ + f.off_by_default = True return f diff --git a/hacking/tests/test_doctest.py b/hacking/tests/test_doctest.py index f330dc9..af76dfb 100644 --- a/hacking/tests/test_doctest.py +++ b/hacking/tests/test_doctest.py @@ -37,6 +37,13 @@ class HackingTestCase(hacking.tests.TestCase): scenarios = file_cases def test_pep8(self): + + # 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) + report = pep8.BaseReport(self.options) checker = pep8.Checker(lines=self.lines, options=self.options, report=report) diff --git a/setup.cfg b/setup.cfg index 49e9868..7f16d1f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,7 @@ flake8.extension = H103 = hacking.checks.comments:hacking_has_correct_license H104 = hacking.checks.comments:hacking_has_only_comments H105 = hacking.checks.comments:hacking_no_author_tags + H106 = hacking.checks.vim_check:no_vim_headers H201 = hacking.checks.except_checks:hacking_except_format H202 = hacking.checks.except_checks:hacking_except_format_assert H231 = hacking.checks.python23:hacking_python3x_except_compatible diff --git a/tox.ini b/tox.ini index 6eddcdb..9bfa2e4 100644 --- a/tox.ini +++ b/tox.ini @@ -38,6 +38,7 @@ commands = python setup.py build_sphinx [flake8] exclude = .venv,.tox,dist,doc,*.egg,build show-source = true +select = H106 [hacking] local-check = hacking.tests.test_local.check