From 42494c3fb9ceb5ad4ea45e1143b922d7c524646e Mon Sep 17 00:00:00 2001 From: Joe Gordon Date: Tue, 25 Jun 2013 16:42:21 -0700 Subject: [PATCH] Add no locals() for string formatting test Using locals() for formatting strings is not as clear as explicit dictionaries and can produce hidden errors during refactoring. locals() are already being partially removed in nova and cinder. Related to bug 1171936 Change-Id: I6ef790ebf50d640af62c535952c7a98053869e43 --- HACKING.rst | 2 ++ hacking/core.py | 22 ++++++++++++++++++++++ setup.cfg | 1 + 3 files changed, 25 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index e3d49e77..64a6ddcc 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -152,6 +152,8 @@ Example:: }, } +Do not use ``locals()`` for formatting strings, it is not clear as using +explicit dictionaries and can hide errors during refactoring. Calling Methods --------------- diff --git a/hacking/core.py b/hacking/core.py index d1cd1dfd..ff757327 100755 --- a/hacking/core.py +++ b/hacking/core.py @@ -586,6 +586,28 @@ def hacking_docstring_multiline_start(physical_line, previous_logical, tokens): "should start with a summary") +@flake8ext +def hacking_no_locals(logical_line, physical_line, tokens): + """Do not use locals() for string formatting. + + Okay: 'locals()' + Okay: 'locals' + Okay: locals() + Okay: print(locals()) + H501: print("%(something)" % locals()) + Okay: print("%(something)" % locals()) # noqa + """ + if pep8.noqa(physical_line): + return + for_formatting = False + for token_type, text, start, _, _ in tokens: + if text == "%" and token_type == tokenize.OP: + for_formatting = True + if (for_formatting and token_type == tokenize.NAME and text == + "locals" and "locals()" in logical_line): + yield (start[1], "H501: Do not use locals() for string formatting") + + @flake8ext def hacking_no_cr(physical_line): r"""Check that we only use newlines not carriage returns. diff --git a/setup.cfg b/setup.cfg index ac41d068..ce4e4abe 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,6 +41,7 @@ flake8.extension = H402 = hacking.core:hacking_docstring_one_line H403 = hacking.core:hacking_docstring_multiline_end H404 = hacking.core:hacking_docstring_multiline_start + H501 = hacking.core:hacking_no_locals H601 = hacking.core:hacking_no_cr H700 = hacking.core:hacking_localization_strings H801 = hacking.core:OnceGitCheckCommitTitleBug