[Python-checkins] [3.8] bpo-32912: Revert SyntaxWarning on invalid escape sequences (GH-15142)

Gregory P. Smith webhook-mailer at python.org
Fri Aug 9 18:34:28 EDT 2019


https://github.com/python/cpython/commit/4c5b6bac2408f879231c7cd38d67657dd4804e7c
commit: 4c5b6bac2408f879231c7cd38d67657dd4804e7c
branch: 3.8
author: Serhiy Storchaka <storchaka at gmail.com>
committer: Gregory P. Smith <greg at krypto.org>
date: 2019-08-09T15:34:22-07:00
summary:

[3.8] bpo-32912: Revert SyntaxWarning on invalid escape sequences (GH-15142)

* bpo-32912: Revert warnings for invalid escape sequences.

DeprecationWarning will continue to be emitted for invalid escape sequences in string and bytes literals in 3.8 just as it did in 3.7.

SyntaxWarning may be emitted in the future. But per mailing list discussion, we don't yet know when because we haven't settled on how to do so in a non-disruptive manner.

files:
A Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912.UDwSMJ.rst
M Doc/reference/lexical_analysis.rst
M Doc/whatsnew/3.8.rst
M Lib/test/test_fstring.py
M Lib/test/test_string_literals.py
M Python/ast.c

diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst
index cc1b2f57a70e..7e1e17edb2d8 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -594,11 +594,9 @@ escape sequences only recognized in string literals fall into the category of
 unrecognized escapes for bytes literals.
 
    .. versionchanged:: 3.6
-      Unrecognized escape sequences produce a :exc:`DeprecationWarning`.
-
-   .. versionchanged:: 3.8
-      Unrecognized escape sequences produce a :exc:`SyntaxWarning`.  In
-      some future version of Python they will be a :exc:`SyntaxError`.
+      Unrecognized escape sequences produce a :exc:`DeprecationWarning`.  In
+      a future Python version they will be a :exc:`SyntaxWarning` and
+      eventually a :exc:`SyntaxError`.
 
 Even in a raw literal, quotes can be escaped with a backslash, but the
 backslash remains in the result; for example, ``r"\""`` is a valid string
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 9f7058274514..83caa2cc5abc 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -414,11 +414,6 @@ Other Language Changes
   and :keyword:`return` statements.
   (Contributed by David Cuthbert and Jordan Chapman in :issue:`32117`.)
 
-* A backslash-character pair that is not a valid escape sequence generates
-  a :exc:`DeprecationWarning` since Python 3.6. In Python 3.8 it generates
-  a :exc:`SyntaxWarning` instead.
-  (Contributed by Serhiy Storchaka in :issue:`32912`.)
-
 * The compiler now produces a :exc:`SyntaxWarning` in some cases when a comma
   is missed before tuple or list.  For example::
 
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
index fb761441fcee..49663923e7f5 100644
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -649,7 +649,7 @@ def test_backslashes_in_string_part(self):
         self.assertEqual(f'2\x203', '2 3')
         self.assertEqual(f'\x203', ' 3')
 
-        with self.assertWarns(SyntaxWarning):  # invalid escape sequence
+        with self.assertWarns(DeprecationWarning):  # invalid escape sequence
             value = eval(r"f'\{6*7}'")
         self.assertEqual(value, '\\42')
         self.assertEqual(f'\\{6*7}', '\\42')
diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py
index 5961d591c448..0cea2edc32af 100644
--- a/Lib/test/test_string_literals.py
+++ b/Lib/test/test_string_literals.py
@@ -32,6 +32,7 @@
 import shutil
 import tempfile
 import unittest
+import warnings
 
 
 TEMPLATE = r"""# coding: %s
@@ -110,10 +111,24 @@ def test_eval_str_invalid_escape(self):
         for b in range(1, 128):
             if b in b"""\n\r"'01234567NU\\abfnrtuvx""":
                 continue
-            with self.assertWarns(SyntaxWarning):
+            with self.assertWarns(DeprecationWarning):
                 self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b))
 
-        self.check_syntax_warning("'''\n\\z'''")
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always', category=DeprecationWarning)
+            eval("'''\n\\z'''")
+        self.assertEqual(len(w), 1)
+        self.assertEqual(w[0].filename, '<string>')
+        self.assertEqual(w[0].lineno, 1)
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('error', category=DeprecationWarning)
+            with self.assertRaises(SyntaxError) as cm:
+                eval("'''\n\\z'''")
+            exc = cm.exception
+        self.assertEqual(w, [])
+        self.assertEqual(exc.filename, '<string>')
+        self.assertEqual(exc.lineno, 1)
 
     def test_eval_str_raw(self):
         self.assertEqual(eval(""" r'x' """), 'x')
@@ -145,10 +160,24 @@ def test_eval_bytes_invalid_escape(self):
         for b in range(1, 128):
             if b in b"""\n\r"'01234567\\abfnrtvx""":
                 continue
-            with self.assertWarns(SyntaxWarning):
+            with self.assertWarns(DeprecationWarning):
                 self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b]))
 
-        self.check_syntax_warning("b'''\n\\z'''")
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always', category=DeprecationWarning)
+            eval("b'''\n\\z'''")
+        self.assertEqual(len(w), 1)
+        self.assertEqual(w[0].filename, '<string>')
+        self.assertEqual(w[0].lineno, 1)
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('error', category=DeprecationWarning)
+            with self.assertRaises(SyntaxError) as cm:
+                eval("b'''\n\\z'''")
+            exc = cm.exception
+        self.assertEqual(w, [])
+        self.assertEqual(exc.filename, '<string>')
+        self.assertEqual(exc.lineno, 1)
 
     def test_eval_bytes_raw(self):
         self.assertEqual(eval(""" br'x' """), b'x')
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912.UDwSMJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912.UDwSMJ.rst
new file mode 100644
index 000000000000..e18d8adfbee9
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912.UDwSMJ.rst	
@@ -0,0 +1,3 @@
+Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead of
+:exc:`DeprecationWarning` for invalid escape sequences in string and bytes
+literals.
diff --git a/Python/ast.c b/Python/ast.c
index f6c2049ae2cf..9947824de744 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -4674,12 +4674,12 @@ warn_invalid_escape_sequence(struct compiling *c, const node *n,
     if (msg == NULL) {
         return -1;
     }
-    if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg,
+    if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg,
                                    c->c_filename, LINENO(n),
                                    NULL, NULL) < 0)
     {
-        if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
-            /* Replace the SyntaxWarning exception with a SyntaxError
+        if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
+            /* Replace the DeprecationWarning exception with a SyntaxError
                to get a more accurate error report */
             PyErr_Clear();
             ast_error(c, n, "%U", msg);



More information about the Python-checkins mailing list