diff --git a/octaviaclient/hacking/checks.py b/octaviaclient/hacking/checks.py index f38c72d..2437b46 100644 --- a/octaviaclient/hacking/checks.py +++ b/octaviaclient/hacking/checks.py @@ -247,6 +247,27 @@ def check_no_eventlet_imports(logical_line): yield logical_line.index('eventlet'), msg +def check_line_continuation_no_backslash(logical_line, tokens): + """O346 - Don't use backslashes for line continuation. + + :param logical_line: The logical line to check. Not actually used. + :param tokens: List of tokens to check. + :returns: None if the tokens don't contain any issues, otherwise a tuple + is yielded that contains the offending index in the logical line and a + message describe the check validation failure. + """ + backslash = None + for token_type, text, start, end, orig_line in tokens: + m = re.match(r'.*(\\)\n', orig_line) + if m: + backslash = (start[0], m.start(1)) + break + + if backslash is not None: + msg = 'O346 Backslash line continuations not allowed' + yield backslash, msg + + def factory(register): register(assert_true_instance) register(assert_equal_or_not_none) @@ -261,3 +282,4 @@ def factory(register): register(check_no_basestring) register(check_python3_no_iteritems) register(check_no_eventlet_imports) + register(check_line_continuation_no_backslash) diff --git a/octaviaclient/tests/unit/test_hacking.py b/octaviaclient/tests/unit/test_hacking.py index 2a7990e..0618dd5 100644 --- a/octaviaclient/tests/unit/test_hacking.py +++ b/octaviaclient/tests/unit/test_hacking.py @@ -142,3 +142,10 @@ class HackingTestCase(base.BaseTestCase): self.assertEqual(0, len(list(checks.no_xrange( "range(45)")))) + + def test_line_continuation_no_backslash(self): + results = list(checks.check_line_continuation_no_backslash( + '', [(1, 'import', (2, 0), (2, 6), 'import \\\n'), + (1, 'os', (3, 4), (3, 6), ' os\n')])) + self.assertEqual(1, len(results)) + self.assertEqual((2, 7), results[0][0])