From 43a8bf1ea43127aa0d4d05f9db74827899808266 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 27 Apr 2022 20:15:14 +0300 Subject: 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. --- Lib/test/test_grammar.py | 25 +++++++++++++++------- .../2022-04-27-10-36-43.gh-issue-87999.YSPHfO.rst | 3 +++ Parser/tokenizer.c | 10 +++++---- 3 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-04-27-10-36-43.gh-issue-87999.YSPHfO.rst diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 2e29cdb..da88519 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -104,6 +104,7 @@ INVALID_UNDERSCORE_LITERALS = [ class TokenTests(unittest.TestCase): from test.support import check_syntax_error + from test.support.warnings_helper import check_syntax_warning def test_backslash(self): # Backslash means line continuation: @@ -178,7 +179,7 @@ class TokenTests(unittest.TestCase): def test_float_exponent_tokenization(self): # See issue 21642. 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 0else 0"), 0) self.assertRaises(SyntaxError, eval, "0 if 1Else 0") @@ -218,12 +219,13 @@ class TokenTests(unittest.TestCase): with self.subTest(expr=test): if error: with warnings.catch_warnings(record=True) as w: - with self.assertRaises(SyntaxError): + with self.assertRaisesRegex(SyntaxError, + r'invalid \w+ literal'): compile(test, "", "eval") self.assertEqual(w, []) else: - with self.assertWarns(DeprecationWarning): - compile(test, "", "eval") + self.check_syntax_warning(test, + errtext=r'invalid \w+ literal') for num in "0xf", "0o7", "0b1", "9", "0", "1.", "1e3", "1j": compile(num, "", "eval") @@ -231,15 +233,22 @@ class TokenTests(unittest.TestCase): check(f"{num}or x", error=(num == "0")) check(f"{num}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"x if {num}else y", error=(num == "0xf")) check(f"[{num}for x in ()]") 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", "", "eval") + warnings.simplefilter('error', SyntaxWarning) + with self.assertRaisesRegex(SyntaxError, + r'invalid \w+ literal'): + compile(f"{num}is x", "", "eval") + check("[0x1ffor x in ()]") check("[0x1for x in ()]") check("[0xfor x in ()]") diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-27-10-36-43.gh-issue-87999.YSPHfO.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-27-10-36-43.gh-issue-87999.YSPHfO.rst new file mode 100644 index 0000000..b0ad9b5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-04-27-10-36-43.gh-issue-87999.YSPHfO.rst @@ -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. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index db84e2e..c450aa8 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1139,7 +1139,7 @@ indenterror(struct tok_state *tok) } static int -parser_warn(struct tok_state *tok, const char *format, ...) +parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...) { PyObject *errmsg; va_list vargs; @@ -1154,9 +1154,9 @@ parser_warn(struct tok_state *tok, const char *format, ...) goto error; } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, errmsg, tok->filename, + if (PyErr_WarnExplicitObject(category, errmsg, tok->filename, tok->lineno, NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + if (PyErr_ExceptionMatches(category)) { /* Replace the DeprecationWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); @@ -1234,7 +1234,9 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) } if (r) { tok_backup(tok, c); - if (parser_warn(tok, "invalid %s literal", kind)) { + if (parser_warn(tok, PyExc_SyntaxWarning, + "invalid %s literal", kind)) + { return 0; } tok_nextc(tok); -- cgit v0.12