bpo-32912: Revert SyntaxWarning on invalid escape sequences. (GH-15195)

DeprecationWarning will continue to be emitted for invalid escape
sequences in string and bytes literals 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.

(Applies 4c5b6bac24 to the master branch).
(This is https://github.com/python/cpython/pull/15142 for master/3.9)


https://bugs.python.org/issue32912



Automerge-Triggered-By: @gpshead
This commit is contained in:
Gregory P. Smith 2019-08-10 00:19:07 -07:00 committed by Miss Islington (bot)
parent 92c7e30adf
commit b4be87a04a
6 changed files with 43 additions and 18 deletions

View File

@ -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

View File

@ -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::

View File

@ -649,7 +649,7 @@ non-important content
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')

View File

@ -32,6 +32,7 @@ import sys
import shutil
import tempfile
import unittest
import warnings
TEMPLATE = r"""# coding: %s
@ -110,10 +111,24 @@ class TestLiterals(unittest.TestCase):
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 @@ class TestLiterals(unittest.TestCase):
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')

View File

@ -0,0 +1,3 @@
Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead of
:exc:`DeprecationWarning` for invalid escape sequences in string and bytes
literals.

View File

@ -4671,12 +4671,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);