Skip to content

Commit

Permalink
bpo-32912: Replace a DeprecationWarning with a SyntaxWarning (GH-9652)
Browse files Browse the repository at this point in the history
for invalid escape sequences in string and bytes literals.
  • Loading branch information
serhiy-storchaka authored Oct 19, 2018
1 parent 2091448 commit 6543912
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 12 deletions.
7 changes: 5 additions & 2 deletions Doc/reference/lexical_analysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,11 @@ 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 DeprecationWarning. In
some future version of Python they will be a SyntaxError.
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`.

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
Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ 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`.)


New Modules
===========

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_fstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ def test_backslashes_in_string_part(self):
self.assertEqual(f'2\x203', '2 3')
self.assertEqual(f'\x203', ' 3')

with self.assertWarns(DeprecationWarning): # invalid escape sequence
with self.assertWarns(SyntaxWarning): # invalid escape sequence
value = eval(r"f'\{6*7}'")
self.assertEqual(value, '\\42')
self.assertEqual(f'\\{6*7}', '\\42')
Expand Down
12 changes: 6 additions & 6 deletions Lib/test/test_string_literals.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,18 @@ 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(DeprecationWarning):
with self.assertWarns(SyntaxWarning):
self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b))

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always', category=DeprecationWarning)
warnings.simplefilter('always', category=SyntaxWarning)
eval("'''\n\\z'''")
self.assertEqual(len(w), 1)
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)
warnings.simplefilter('error', category=SyntaxWarning)
with self.assertRaises(SyntaxError) as cm:
eval("'''\n\\z'''")
exc = cm.exception
Expand Down Expand Up @@ -158,18 +158,18 @@ 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(DeprecationWarning):
with self.assertWarns(SyntaxWarning):
self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b]))

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always', category=DeprecationWarning)
warnings.simplefilter('always', category=SyntaxWarning)
eval("b'''\n\\z'''")
self.assertEqual(len(w), 1)
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)
warnings.simplefilter('error', category=SyntaxWarning)
with self.assertRaises(SyntaxError) as cm:
eval("b'''\n\\z'''")
exc = cm.exception
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
A :exc:`SyntaxWarning` is now emitted instead of a :exc:`DeprecationWarning`
for invalid escape sequences in string and bytes literals.
6 changes: 3 additions & 3 deletions Python/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -4128,14 +4128,14 @@ warn_invalid_escape_sequence(struct compiling *c, const node *n,
if (msg == NULL) {
return -1;
}
if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg,
if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg,
c->c_filename, LINENO(n),
NULL, NULL) < 0)
{
if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
const char *s;

/* Replace the DeprecationWarning exception with a SyntaxError
/* Replace the SyntaxWarning exception with a SyntaxError
to get a more accurate error report */
PyErr_Clear();

Expand Down

0 comments on commit 6543912

Please sign in to comment.