]> granicus.if.org Git - python/commitdiff
Fix warn_invalid_escape_sequence()
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 15 Nov 2016 08:12:10 +0000 (09:12 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 15 Nov 2016 08:12:10 +0000 (09:12 +0100)
Issue #28691: Fix warn_invalid_escape_sequence(): handle correctly
DeprecationWarning raised as an exception. First clear the current exception to
replace the DeprecationWarning exception with a SyntaxError exception.

Unit test written by Serhiy Storchaka.

Lib/test/test_string_literals.py
Python/ast.c

index 54f2be3598396a99012883915ddc46b8de069774..aba4fc46676245409954fb216b98a6db49ada5b2 100644 (file)
@@ -111,6 +111,7 @@ class TestLiterals(unittest.TestCase):
                 continue
             with self.assertWarns(DeprecationWarning):
                 self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b))
+
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter('always', category=DeprecationWarning)
             eval("'''\n\\z'''")
@@ -118,6 +119,15 @@ class TestLiterals(unittest.TestCase):
         self.assertEqual(w[0].filename, '<string>')
         self.assertEqual(w[0].lineno, 2)
 
+        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, 2)
+
     def test_eval_str_raw(self):
         self.assertEqual(eval(""" r'x' """), 'x')
         self.assertEqual(eval(r""" r'\x01' """), '\\' + 'x01')
@@ -150,6 +160,7 @@ class TestLiterals(unittest.TestCase):
                 continue
             with self.assertWarns(DeprecationWarning):
                 self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b]))
+
         with warnings.catch_warnings(record=True) as w:
             warnings.simplefilter('always', category=DeprecationWarning)
             eval("b'''\n\\z'''")
@@ -157,6 +168,15 @@ class TestLiterals(unittest.TestCase):
         self.assertEqual(w[0].filename, '<string>')
         self.assertEqual(w[0].lineno, 2)
 
+        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, 2)
+
     def test_eval_bytes_raw(self):
         self.assertEqual(eval(""" br'x' """), b'x')
         self.assertEqual(eval(""" rb'x' """), b'x')
index bfae6ed7d4adc4132c7a033090ee26d0128d3ab2..14bcdb1b0a11a5b46c96f478a64a62b94163345e 100644 (file)
@@ -4129,7 +4129,13 @@ warn_invalid_escape_sequence(struct compiling *c, const node *n,
                                    NULL, NULL) < 0 &&
         PyErr_ExceptionMatches(PyExc_DeprecationWarning))
     {
-        const char *s = PyUnicode_AsUTF8(msg);
+        const char *s;
+
+        /* Replace the DeprecationWarning exception with a SyntaxError
+           to get a more accurate error report */
+        PyErr_Clear();
+
+        s = PyUnicode_AsUTF8(msg);
         if (s != NULL) {
             ast_error(c, n, s);
         }