From 28bdaf2332dcf1c5f440f90b3d482347248db3d8 Mon Sep 17 00:00:00 2001 From: TERESH1 Date: Wed, 7 May 2025 21:11:25 +0300 Subject: [PATCH] [3.13] gh-133516: Raise `ValueError` when constants `True`, `False` or `None` are used as an identifier after NFKC normalization (GH-133523) (cherry picked from commit d9b0b07098ec4bdb47151948c77bcbbf3e796a5d) --- Lib/test/test_ast/test_ast.py | 11 +++++++++++ ...2025-05-06-15-01-41.gh-issue-133516.RqWVf2.rst | 2 ++ Parser/pegen.c | 15 +++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2025-05-06-15-01-41.gh-issue-133516.RqWVf2.rst diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 7ac5a816bf0229..db2ea9f546eb1a 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -960,6 +960,17 @@ def test_constant_as_name(self): ): compile(expr, "", "eval") + def test_constant_as_unicode_name(self): + constants = [ + ("True", b"Tru\xe1\xb5\x89"), + ("False", b"Fal\xc5\xbfe"), + ("None", b"N\xc2\xbane"), + ] + for constant in constants: + with self.assertRaisesRegex(ValueError, + f"identifier field can't represent '{constant[0]}' constant"): + ast.parse(constant[1], mode="eval") + def test_precedence_enum(self): class _Precedence(enum.IntEnum): """Precedence table that originated from python grammar.""" diff --git a/Misc/NEWS.d/next/Core and Builtins/2025-05-06-15-01-41.gh-issue-133516.RqWVf2.rst b/Misc/NEWS.d/next/Core and Builtins/2025-05-06-15-01-41.gh-issue-133516.RqWVf2.rst new file mode 100644 index 00000000000000..b93ba11f93252b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2025-05-06-15-01-41.gh-issue-133516.RqWVf2.rst @@ -0,0 +1,2 @@ +Raise :exc:`ValueError` when constants ``True``, ``False`` or ``None`` are +used as an identifier after NFKC normalization. diff --git a/Parser/pegen.c b/Parser/pegen.c index e0cfc16961987d..d167397919f56e 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -545,6 +545,21 @@ _PyPegen_new_identifier(Parser *p, const char *n) } id = id2; } + static const char * const forbidden[] = { + "None", + "True", + "False", + NULL + }; + for (int i = 0; forbidden[i] != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(id, forbidden[i])) { + PyErr_Format(PyExc_ValueError, + "identifier field can't represent '%s' constant", + forbidden[i]); + Py_DECREF(id); + goto error; + } + } PyInterpreterState *interp = _PyInterpreterState_GET(); _PyUnicode_InternImmortal(interp, &id); if (_PyArena_AddPyObject(p->arena, id) < 0)