Skip to content

Commit 43a8bf1

Browse files
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.
1 parent f60b4c3 commit 43a8bf1

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

Lib/test/test_grammar.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
class TokenTests(unittest.TestCase):
105105

106106
from test.support import check_syntax_error
107+
from test.support.warnings_helper import check_syntax_warning
107108

108109
def test_backslash(self):
109110
# Backslash means line continuation:
@@ -178,7 +179,7 @@ def test_floats(self):
178179
def test_float_exponent_tokenization(self):
179180
# See issue 21642.
180181
with warnings.catch_warnings():
181-
warnings.simplefilter('ignore', DeprecationWarning)
182+
warnings.simplefilter('ignore', SyntaxWarning)
182183
self.assertEqual(eval("1 if 1else 0"), 1)
183184
self.assertEqual(eval("1 if 0else 0"), 0)
184185
self.assertRaises(SyntaxError, eval, "0 if 1Else 0")
@@ -218,28 +219,36 @@ def check(test, error=False):
218219
with self.subTest(expr=test):
219220
if error:
220221
with warnings.catch_warnings(record=True) as w:
221-
with self.assertRaises(SyntaxError):
222+
with self.assertRaisesRegex(SyntaxError,
223+
r'invalid \w+ literal'):
222224
compile(test, "<testcase>", "eval")
223225
self.assertEqual(w, [])
224226
else:
225-
with self.assertWarns(DeprecationWarning):
226-
compile(test, "<testcase>", "eval")
227+
self.check_syntax_warning(test,
228+
errtext=r'invalid \w+ literal')
227229

228230
for num in "0xf", "0o7", "0b1", "9", "0", "1.", "1e3", "1j":
229231
compile(num, "<testcase>", "eval")
230232
check(f"{num}and x", error=(num == "0xf"))
231233
check(f"{num}or x", error=(num == "0"))
232234
check(f"{num}in x")
233235
check(f"{num}not in x")
234-
with warnings.catch_warnings():
235-
warnings.filterwarnings('ignore', '"is" with a literal',
236-
SyntaxWarning)
237-
check(f"{num}is x")
238236
check(f"{num}if x else y")
239237
check(f"x if {num}else y", error=(num == "0xf"))
240238
check(f"[{num}for x in ()]")
241239
check(f"{num}spam", error=True)
242240

241+
with warnings.catch_warnings():
242+
warnings.filterwarnings('ignore', '"is" with a literal',
243+
SyntaxWarning)
244+
with self.assertWarnsRegex(SyntaxWarning,
245+
r'invalid \w+ literal'):
246+
compile(f"{num}is x", "<testcase>", "eval")
247+
warnings.simplefilter('error', SyntaxWarning)
248+
with self.assertRaisesRegex(SyntaxError,
249+
r'invalid \w+ literal'):
250+
compile(f"{num}is x", "<testcase>", "eval")
251+
243252
check("[0x1ffor x in ()]")
244253
check("[0x1for x in ()]")
245254
check("[0xfor x in ()]")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The warning emitted by the Python parser for a numeric literal immediately
2+
followed by keyword has been changed from deprecation warning to syntax
3+
warning.

Parser/tokenizer.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ indenterror(struct tok_state *tok)
11391139
}
11401140

11411141
static int
1142-
parser_warn(struct tok_state *tok, const char *format, ...)
1142+
parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...)
11431143
{
11441144
PyObject *errmsg;
11451145
va_list vargs;
@@ -1154,9 +1154,9 @@ parser_warn(struct tok_state *tok, const char *format, ...)
11541154
goto error;
11551155
}
11561156

1157-
if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, errmsg, tok->filename,
1157+
if (PyErr_WarnExplicitObject(category, errmsg, tok->filename,
11581158
tok->lineno, NULL, NULL) < 0) {
1159-
if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
1159+
if (PyErr_ExceptionMatches(category)) {
11601160
/* Replace the DeprecationWarning exception with a SyntaxError
11611161
to get a more accurate error report */
11621162
PyErr_Clear();
@@ -1234,7 +1234,9 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind)
12341234
}
12351235
if (r) {
12361236
tok_backup(tok, c);
1237-
if (parser_warn(tok, "invalid %s literal", kind)) {
1237+
if (parser_warn(tok, PyExc_SyntaxWarning,
1238+
"invalid %s literal", kind))
1239+
{
12381240
return 0;
12391241
}
12401242
tok_nextc(tok);

0 commit comments

Comments
 (0)