diff --git a/autopep8.py b/autopep8.py index 53a84467..e30b4eb3 100755 --- a/autopep8.py +++ b/autopep8.py @@ -1363,7 +1363,7 @@ def get_w605_position(tokens): 'N', 'u', 'U', ] - for token_type, text, start, end, line in tokens: + for token_type, text, start_pos, end_pos, line in tokens: if token_type == tokenize.STRING: quote = text[-3:] if text[-3:] in ('"""', "'''") else text[-1] # Extract string modifiers (e.g. u or r) @@ -1378,7 +1378,8 @@ def get_w605_position(tokens): pos += 1 if string[pos] not in valid: yield ( - line.find(text), + # No need to search line, token stores position + start_pos[1], "W605 invalid escape sequence '\\%s'" % string[pos], ) diff --git a/test/test_autopep8.py b/test/test_autopep8.py index 03e3084e..cfb80d48 100755 --- a/test/test_autopep8.py +++ b/test/test_autopep8.py @@ -4734,6 +4734,25 @@ def test_w605_simple(self): with autopep8_context(line, options=['--aggressive']) as result: self.assertEqual(fixed, result) + def test_w605_identical_token(self): + # ***NOTE***: The --pep8-passes option is requred to prevent an infinite loop in + # the old, failing code. DO NOT REMOVE. + line = "escape = foo('\.bar', '\.kilroy')\n" + fixed = "escape = foo(r'\.bar', r'\.kilroy')\n" + with autopep8_context(line, options=['--aggressive', '--pep8-passes', '5']) as result: + self.assertEqual(fixed, result, "Two tokens get r added") + + line = "escape = foo('\.bar', r'\.kilroy')\n" + fixed = "escape = foo(r'\.bar', r'\.kilroy')\n" + with autopep8_context(line, options=['--aggressive', '--pep8-passes', '5']) as result: + self.assertEqual(fixed, result, "r not added if already there") + + # Test Case to catch bad behavior reported in Issue #449 + line = "escape = foo('\.bar', '\.bar')\n" + fixed = "escape = foo(r'\.bar', r'\.bar')\n" + with autopep8_context(line, options=['--aggressive', '--pep8-passes', '5']) as result: + self.assertEqual(fixed, result) + def test_trailing_whitespace_in_multiline_string(self): line = 'x = """ \nhello""" \n' fixed = 'x = """ \nhello"""\n'