mirror of https://github.com/python/cpython
gh-87999: Change warning type for numeric literal followed by keyword (GH-91980)
The warning emitted by the Python parser for a numeric literal immediately followed by keyword has been changed from deprecation warning to syntax warning.
This commit is contained in:
parent
f60b4c3d74
commit
43a8bf1ea4
|
@ -104,6 +104,7 @@ INVALID_UNDERSCORE_LITERALS = [
|
||||||
class TokenTests(unittest.TestCase):
|
class TokenTests(unittest.TestCase):
|
||||||
|
|
||||||
from test.support import check_syntax_error
|
from test.support import check_syntax_error
|
||||||
|
from test.support.warnings_helper import check_syntax_warning
|
||||||
|
|
||||||
def test_backslash(self):
|
def test_backslash(self):
|
||||||
# Backslash means line continuation:
|
# Backslash means line continuation:
|
||||||
|
@ -178,7 +179,7 @@ class TokenTests(unittest.TestCase):
|
||||||
def test_float_exponent_tokenization(self):
|
def test_float_exponent_tokenization(self):
|
||||||
# See issue 21642.
|
# See issue 21642.
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter('ignore', DeprecationWarning)
|
warnings.simplefilter('ignore', SyntaxWarning)
|
||||||
self.assertEqual(eval("1 if 1else 0"), 1)
|
self.assertEqual(eval("1 if 1else 0"), 1)
|
||||||
self.assertEqual(eval("1 if 0else 0"), 0)
|
self.assertEqual(eval("1 if 0else 0"), 0)
|
||||||
self.assertRaises(SyntaxError, eval, "0 if 1Else 0")
|
self.assertRaises(SyntaxError, eval, "0 if 1Else 0")
|
||||||
|
@ -218,12 +219,13 @@ class TokenTests(unittest.TestCase):
|
||||||
with self.subTest(expr=test):
|
with self.subTest(expr=test):
|
||||||
if error:
|
if error:
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
with self.assertRaises(SyntaxError):
|
with self.assertRaisesRegex(SyntaxError,
|
||||||
|
r'invalid \w+ literal'):
|
||||||
compile(test, "<testcase>", "eval")
|
compile(test, "<testcase>", "eval")
|
||||||
self.assertEqual(w, [])
|
self.assertEqual(w, [])
|
||||||
else:
|
else:
|
||||||
with self.assertWarns(DeprecationWarning):
|
self.check_syntax_warning(test,
|
||||||
compile(test, "<testcase>", "eval")
|
errtext=r'invalid \w+ literal')
|
||||||
|
|
||||||
for num in "0xf", "0o7", "0b1", "9", "0", "1.", "1e3", "1j":
|
for num in "0xf", "0o7", "0b1", "9", "0", "1.", "1e3", "1j":
|
||||||
compile(num, "<testcase>", "eval")
|
compile(num, "<testcase>", "eval")
|
||||||
|
@ -231,15 +233,22 @@ class TokenTests(unittest.TestCase):
|
||||||
check(f"{num}or x", error=(num == "0"))
|
check(f"{num}or x", error=(num == "0"))
|
||||||
check(f"{num}in x")
|
check(f"{num}in x")
|
||||||
check(f"{num}not in x")
|
check(f"{num}not in x")
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.filterwarnings('ignore', '"is" with a literal',
|
|
||||||
SyntaxWarning)
|
|
||||||
check(f"{num}is x")
|
|
||||||
check(f"{num}if x else y")
|
check(f"{num}if x else y")
|
||||||
check(f"x if {num}else y", error=(num == "0xf"))
|
check(f"x if {num}else y", error=(num == "0xf"))
|
||||||
check(f"[{num}for x in ()]")
|
check(f"[{num}for x in ()]")
|
||||||
check(f"{num}spam", error=True)
|
check(f"{num}spam", error=True)
|
||||||
|
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.filterwarnings('ignore', '"is" with a literal',
|
||||||
|
SyntaxWarning)
|
||||||
|
with self.assertWarnsRegex(SyntaxWarning,
|
||||||
|
r'invalid \w+ literal'):
|
||||||
|
compile(f"{num}is x", "<testcase>", "eval")
|
||||||
|
warnings.simplefilter('error', SyntaxWarning)
|
||||||
|
with self.assertRaisesRegex(SyntaxError,
|
||||||
|
r'invalid \w+ literal'):
|
||||||
|
compile(f"{num}is x", "<testcase>", "eval")
|
||||||
|
|
||||||
check("[0x1ffor x in ()]")
|
check("[0x1ffor x in ()]")
|
||||||
check("[0x1for x in ()]")
|
check("[0x1for x in ()]")
|
||||||
check("[0xfor x in ()]")
|
check("[0xfor x in ()]")
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
The warning emitted by the Python parser for a numeric literal immediately
|
||||||
|
followed by keyword has been changed from deprecation warning to syntax
|
||||||
|
warning.
|
|
@ -1139,7 +1139,7 @@ indenterror(struct tok_state *tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parser_warn(struct tok_state *tok, const char *format, ...)
|
parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...)
|
||||||
{
|
{
|
||||||
PyObject *errmsg;
|
PyObject *errmsg;
|
||||||
va_list vargs;
|
va_list vargs;
|
||||||
|
@ -1154,9 +1154,9 @@ parser_warn(struct tok_state *tok, const char *format, ...)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, errmsg, tok->filename,
|
if (PyErr_WarnExplicitObject(category, errmsg, tok->filename,
|
||||||
tok->lineno, NULL, NULL) < 0) {
|
tok->lineno, NULL, NULL) < 0) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
|
if (PyErr_ExceptionMatches(category)) {
|
||||||
/* Replace the DeprecationWarning exception with a SyntaxError
|
/* Replace the DeprecationWarning exception with a SyntaxError
|
||||||
to get a more accurate error report */
|
to get a more accurate error report */
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
@ -1234,7 +1234,9 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind)
|
||||||
}
|
}
|
||||||
if (r) {
|
if (r) {
|
||||||
tok_backup(tok, c);
|
tok_backup(tok, c);
|
||||||
if (parser_warn(tok, "invalid %s literal", kind)) {
|
if (parser_warn(tok, PyExc_SyntaxWarning,
|
||||||
|
"invalid %s literal", kind))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tok_nextc(tok);
|
tok_nextc(tok);
|
||||||
|
|
Loading…
Reference in New Issue