Repository: asottile/pyupgrade

Issue:
pyupgrade is introducing a raw string where a line continuation is being used.
Hi.

The pyupgrade tool is introducing a raw string where a line continuation is being used.

Check this example below:
```python
import textwrap


def test_importerror(tmpdir):
    print(tmpdir)
    p1 = tmpdir.join("test1.txt")
    p2 = tmpdir.join("test2.txt")
    p1.write(
        textwrap.dedent(
            """\
        import doesnotexist

        x = 1
        """
        )
    )
    p2.write(
        textwrap.dedent(
            """
        import doesnotexist

        x = 2
        """
        )
    )

```

after running pyupgrade on this file, a `r"""` is introduced as it's demonstrated above.

```python
def test_importerror(tmpdir):
    print(tmpdir)
    p1 = tmpdir.join("test1.txt")
    p2 = tmpdir.join("test2.txt")
    p1.write(
        textwrap.dedent(
            r"""\
        import doesnotexist

        x = 1
        """
        )
    )
    p2.write(
        textwrap.dedent(
            """
        import doesnotexist

        x = 2
        """
        )
    )
```

I'm running `pyupgrade (1.10.0)` with `python Python 3.6.2` on `Windows 10, version 1709`

Discussion:

Patch:
diff --git a/pyupgrade.py b/pyupgrade.py
index d6a196c..928b97e 100644
--- a/pyupgrade.py
+++ b/pyupgrade.py
@@ -437,7 +437,7 @@ def _fix_unicode_literals(contents_text, py3_plus):
 
 # https://docs.python.org/3/reference/lexical_analysis.html
 ESCAPE_STARTS = frozenset((
-    '\n', '\\', "'", '"', 'a', 'b', 'f', 'n', 'r', 't', 'v',
+    '\n', '\r', '\\', "'", '"', 'a', 'b', 'f', 'n', 'r', 't', 'v',
     '0', '1', '2', '3', '4', '5', '6', '7',  # octal escapes
     'x',  # hex escapes
     # only valid in non-bytestrings


Test patch:
diff --git a/tests/pyupgrade_test.py b/tests/pyupgrade_test.py
index 82acd34..c571357 100644
--- a/tests/pyupgrade_test.py
+++ b/tests/pyupgrade_test.py
@@ -343,6 +343,8 @@ def test_unicode_literals(s, py3_plus, expected):
         '"\\u2603"',
         # don't touch already valid escapes
         r'"\r\n"',
+        # don't touch escaped newlines
+        '"""\\\n"""', '"""\\\r\n"""', '"""\\\r"""',
     ),
 )
 def test_fix_escape_sequences_noop(s):