mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-32912: Replace a DeprecationWarning with a SyntaxWarning (GH-9652)
for invalid escape sequences in string and bytes literals.
This commit is contained in:
parent
209144831b
commit
6543912c90
6 changed files with 23 additions and 12 deletions
|
@ -559,8 +559,11 @@ escape sequences only recognized in string literals fall into the category of
|
||||||
unrecognized escapes for bytes literals.
|
unrecognized escapes for bytes literals.
|
||||||
|
|
||||||
.. versionchanged:: 3.6
|
.. versionchanged:: 3.6
|
||||||
Unrecognized escape sequences produce a DeprecationWarning. In
|
Unrecognized escape sequences produce a :exc:`DeprecationWarning`.
|
||||||
some future version of Python they will be a SyntaxError.
|
|
||||||
|
.. 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
|
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
|
backslash remains in the result; for example, ``r"\""`` is a valid string
|
||||||
|
|
|
@ -107,6 +107,12 @@ Other Language Changes
|
||||||
and :keyword:`return` statements.
|
and :keyword:`return` statements.
|
||||||
(Contributed by David Cuthbert and Jordan Chapman in :issue:`32117`.)
|
(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
|
New Modules
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
|
@ -626,7 +626,7 @@ non-important content
|
||||||
self.assertEqual(f'2\x203', '2 3')
|
self.assertEqual(f'2\x203', '2 3')
|
||||||
self.assertEqual(f'\x203', ' 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}'")
|
value = eval(r"f'\{6*7}'")
|
||||||
self.assertEqual(value, '\\42')
|
self.assertEqual(value, '\\42')
|
||||||
self.assertEqual(f'\\{6*7}', '\\42')
|
self.assertEqual(f'\\{6*7}', '\\42')
|
||||||
|
|
|
@ -109,18 +109,18 @@ class TestLiterals(unittest.TestCase):
|
||||||
for b in range(1, 128):
|
for b in range(1, 128):
|
||||||
if b in b"""\n\r"'01234567NU\\abfnrtuvx""":
|
if b in b"""\n\r"'01234567NU\\abfnrtuvx""":
|
||||||
continue
|
continue
|
||||||
with self.assertWarns(DeprecationWarning):
|
with self.assertWarns(SyntaxWarning):
|
||||||
self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b))
|
self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b))
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
warnings.simplefilter('always', category=DeprecationWarning)
|
warnings.simplefilter('always', category=SyntaxWarning)
|
||||||
eval("'''\n\\z'''")
|
eval("'''\n\\z'''")
|
||||||
self.assertEqual(len(w), 1)
|
self.assertEqual(len(w), 1)
|
||||||
self.assertEqual(w[0].filename, '<string>')
|
self.assertEqual(w[0].filename, '<string>')
|
||||||
self.assertEqual(w[0].lineno, 2)
|
self.assertEqual(w[0].lineno, 2)
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
warnings.simplefilter('error', category=DeprecationWarning)
|
warnings.simplefilter('error', category=SyntaxWarning)
|
||||||
with self.assertRaises(SyntaxError) as cm:
|
with self.assertRaises(SyntaxError) as cm:
|
||||||
eval("'''\n\\z'''")
|
eval("'''\n\\z'''")
|
||||||
exc = cm.exception
|
exc = cm.exception
|
||||||
|
@ -158,18 +158,18 @@ class TestLiterals(unittest.TestCase):
|
||||||
for b in range(1, 128):
|
for b in range(1, 128):
|
||||||
if b in b"""\n\r"'01234567\\abfnrtvx""":
|
if b in b"""\n\r"'01234567\\abfnrtvx""":
|
||||||
continue
|
continue
|
||||||
with self.assertWarns(DeprecationWarning):
|
with self.assertWarns(SyntaxWarning):
|
||||||
self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b]))
|
self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b]))
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
warnings.simplefilter('always', category=DeprecationWarning)
|
warnings.simplefilter('always', category=SyntaxWarning)
|
||||||
eval("b'''\n\\z'''")
|
eval("b'''\n\\z'''")
|
||||||
self.assertEqual(len(w), 1)
|
self.assertEqual(len(w), 1)
|
||||||
self.assertEqual(w[0].filename, '<string>')
|
self.assertEqual(w[0].filename, '<string>')
|
||||||
self.assertEqual(w[0].lineno, 2)
|
self.assertEqual(w[0].lineno, 2)
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
warnings.simplefilter('error', category=DeprecationWarning)
|
warnings.simplefilter('error', category=SyntaxWarning)
|
||||||
with self.assertRaises(SyntaxError) as cm:
|
with self.assertRaises(SyntaxError) as cm:
|
||||||
eval("b'''\n\\z'''")
|
eval("b'''\n\\z'''")
|
||||||
exc = cm.exception
|
exc = cm.exception
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
A :exc:`SyntaxWarning` is now emitted instead of a :exc:`DeprecationWarning`
|
||||||
|
for invalid escape sequences in string and bytes literals.
|
|
@ -4128,14 +4128,14 @@ warn_invalid_escape_sequence(struct compiling *c, const node *n,
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg,
|
if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg,
|
||||||
c->c_filename, LINENO(n),
|
c->c_filename, LINENO(n),
|
||||||
NULL, NULL) < 0)
|
NULL, NULL) < 0)
|
||||||
{
|
{
|
||||||
if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
|
if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
/* Replace the DeprecationWarning exception with a SyntaxError
|
/* Replace the SyntaxWarning exception with a SyntaxError
|
||||||
to get a more accurate error report */
|
to get a more accurate error report */
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue