bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649)

(cherry picked from commit 68874a8502da440a1dc4746cf73262648b870aee)

Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>
diff --git a/Python/ast.c b/Python/ast.c
index c524b8e..408591f 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -22,6 +22,25 @@
 static int validate_expr(expr_ty, expr_context_ty);
 
 static int
+validate_name(PyObject *name)
+{
+    assert(PyUnicode_Check(name));
+    static const char * const forbidden[] = {
+        "None",
+        "True",
+        "False",
+        NULL
+    };
+    for (int i = 0; forbidden[i] != NULL; i++) {
+        if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
+            PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int
 validate_comprehension(asdl_seq *gens)
 {
     Py_ssize_t i;
@@ -173,6 +192,9 @@
         actual_ctx = exp->v.Starred.ctx;
         break;
     case Name_kind:
+        if (!validate_name(exp->v.Name.id)) {
+            return 0;
+        }
         actual_ctx = exp->v.Name.ctx;
         break;
     case List_kind: