bpo-36187: Remove NamedStore. (GH-12167)

NamedStore has been replaced with Store. The difference between
NamedStore and Store is handled when precess the NamedExpr node
one level upper.
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 5467d19..92ec157 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -365,8 +365,7 @@
 };
 static PyTypeObject *expr_context_type;
 static PyObject *Load_singleton, *Store_singleton, *Del_singleton,
-*AugLoad_singleton, *AugStore_singleton, *Param_singleton,
-*NamedStore_singleton;
+*AugLoad_singleton, *AugStore_singleton, *Param_singleton;
 static PyObject* ast2obj_expr_context(expr_context_ty);
 static PyTypeObject *Load_type;
 static PyTypeObject *Store_type;
@@ -374,7 +373,6 @@
 static PyTypeObject *AugLoad_type;
 static PyTypeObject *AugStore_type;
 static PyTypeObject *Param_type;
-static PyTypeObject *NamedStore_type;
 static PyTypeObject *slice_type;
 static PyObject* ast2obj_slice(void*);
 static PyTypeObject *Slice_type;
@@ -993,10 +991,6 @@
     if (!Param_type) return 0;
     Param_singleton = PyType_GenericNew(Param_type, NULL, NULL);
     if (!Param_singleton) return 0;
-    NamedStore_type = make_type("NamedStore", expr_context_type, NULL, 0);
-    if (!NamedStore_type) return 0;
-    NamedStore_singleton = PyType_GenericNew(NamedStore_type, NULL, NULL);
-    if (!NamedStore_singleton) return 0;
     slice_type = make_type("slice", &AST_type, NULL, 0);
     if (!slice_type) return 0;
     if (!add_attributes(slice_type, NULL, 0)) return 0;
@@ -3657,9 +3651,6 @@
         case Param:
             Py_INCREF(Param_singleton);
             return Param_singleton;
-        case NamedStore:
-            Py_INCREF(NamedStore_singleton);
-            return NamedStore_singleton;
         default:
             /* should never happen, but just in case ... */
             PyErr_Format(PyExc_SystemError, "unknown expr_context found");
@@ -7608,14 +7599,6 @@
         *out = Param;
         return 0;
     }
-    isinstance = PyObject_IsInstance(obj, (PyObject *)NamedStore_type);
-    if (isinstance == -1) {
-        return 1;
-    }
-    if (isinstance) {
-        *out = NamedStore;
-        return 0;
-    }
 
     PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
     return 1;
@@ -8828,8 +8811,6 @@
         return NULL;
     if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return
         NULL;
-    if (PyDict_SetItemString(d, "NamedStore", (PyObject*)NamedStore_type) < 0)
-        return NULL;
     if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return
         NULL;
     if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return
diff --git a/Python/ast.c b/Python/ast.c
index 62ff868..2e96048 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -94,8 +94,6 @@
         return "Load";
     case Store:
         return "Store";
-    case NamedStore:
-        return "NamedStore";
     case Del:
         return "Del";
     case AugLoad:
@@ -1029,6 +1027,80 @@
     return e;
 }
 
+static const char *
+get_expr_name(expr_ty e)
+{
+    switch (e->kind) {
+        case Attribute_kind:
+            return "attribute";
+        case Subscript_kind:
+            return "subscript";
+        case Starred_kind:
+            return "starred";
+        case Name_kind:
+            return "name";
+        case List_kind:
+            return "list";
+        case Tuple_kind:
+            return "tuple";
+        case Lambda_kind:
+            return "lambda";
+        case Call_kind:
+            return "function call";
+        case BoolOp_kind:
+        case BinOp_kind:
+        case UnaryOp_kind:
+            return "operator";
+        case GeneratorExp_kind:
+            return "generator expression";
+        case Yield_kind:
+        case YieldFrom_kind:
+            return "yield expression";
+        case Await_kind:
+            return "await expression";
+        case ListComp_kind:
+            return "list comprehension";
+        case SetComp_kind:
+            return "set comprehension";
+        case DictComp_kind:
+            return "dict comprehension";
+        case Dict_kind:
+            return "dict display";
+        case Set_kind:
+            return "set display";
+        case JoinedStr_kind:
+        case FormattedValue_kind:
+            return "f-string expression";
+        case Constant_kind: {
+            PyObject *value = e->v.Constant.value;
+            if (value == Py_None) {
+                return "None";
+            }
+            if (value == Py_False) {
+                return "False";
+            }
+            if (value == Py_True) {
+                return "True";
+            }
+            if (value == Py_Ellipsis) {
+                return "Ellipsis";
+            }
+            return "literal";
+        }
+        case Compare_kind:
+            return "comparison";
+        case IfExp_kind:
+            return "conditional expression";
+        case NamedExpr_kind:
+            return "named expression";
+        default:
+            PyErr_Format(PyExc_SystemError,
+                         "unexpected expression in assignment %d (line %d)",
+                         e->kind, e->lineno);
+            return NULL;
+    }
+}
+
 /* Set the context ctx for expr_ty e, recursively traversing e.
 
    Only sets context for expr kinds that "can appear in assignment context"
@@ -1040,10 +1112,6 @@
 set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
 {
     asdl_seq *s = NULL;
-    /* If a particular expression type can't be used for assign / delete,
-       set expr_name to its name and an error message will be generated.
-    */
-    const char* expr_name = NULL;
 
     /* The ast defines augmented store and load contexts, but the
        implementation here doesn't actually use them.  The code may be
@@ -1056,136 +1124,41 @@
 
     switch (e->kind) {
         case Attribute_kind:
-            if (ctx == NamedStore) {
-                expr_name = "attribute";
-                break;
-            }
-
             e->v.Attribute.ctx = ctx;
             if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1))
                 return 0;
             break;
         case Subscript_kind:
-            if (ctx == NamedStore) {
-                expr_name = "subscript";
-                break;
-            }
-
             e->v.Subscript.ctx = ctx;
             break;
         case Starred_kind:
-            if (ctx == NamedStore) {
-                expr_name = "starred";
-                break;
-            }
-
             e->v.Starred.ctx = ctx;
             if (!set_context(c, e->v.Starred.value, ctx, n))
                 return 0;
             break;
         case Name_kind:
-            if (ctx == Store || ctx == NamedStore) {
+            if (ctx == Store) {
                 if (forbidden_name(c, e->v.Name.id, n, 0))
                     return 0; /* forbidden_name() calls ast_error() */
             }
             e->v.Name.ctx = ctx;
             break;
         case List_kind:
-            if (ctx == NamedStore) {
-                expr_name = "list";
-                break;
-            }
-
             e->v.List.ctx = ctx;
             s = e->v.List.elts;
             break;
         case Tuple_kind:
-            if (ctx == NamedStore) {
-                expr_name = "tuple";
-                break;
-            }
-
             e->v.Tuple.ctx = ctx;
             s = e->v.Tuple.elts;
             break;
-        case Lambda_kind:
-            expr_name = "lambda";
-            break;
-        case Call_kind:
-            expr_name = "function call";
-            break;
-        case BoolOp_kind:
-        case BinOp_kind:
-        case UnaryOp_kind:
-            expr_name = "operator";
-            break;
-        case GeneratorExp_kind:
-            expr_name = "generator expression";
-            break;
-        case Yield_kind:
-        case YieldFrom_kind:
-            expr_name = "yield expression";
-            break;
-        case Await_kind:
-            expr_name = "await expression";
-            break;
-        case ListComp_kind:
-            expr_name = "list comprehension";
-            break;
-        case SetComp_kind:
-            expr_name = "set comprehension";
-            break;
-        case DictComp_kind:
-            expr_name = "dict comprehension";
-            break;
-        case Dict_kind:
-            expr_name = "dict display";
-            break;
-        case Set_kind:
-            expr_name = "set display";
-            break;
-        case JoinedStr_kind:
-        case FormattedValue_kind:
-            expr_name = "f-string expression";
-            break;
-        case Constant_kind: {
-            PyObject *value = e->v.Constant.value;
-            if (value == Py_None || value == Py_False || value == Py_True
-                    || value == Py_Ellipsis)
-            {
-                return ast_error(c, n, "cannot %s %R",
-                                 ctx == Store ? "assign to" : "delete",
-                                 value);
+        default: {
+            const char *expr_name = get_expr_name(e);
+            if (expr_name != NULL) {
+                ast_error(c, n, "cannot %s %s",
+                          ctx == Store ? "assign to" : "delete",
+                          expr_name);
             }
-            expr_name = "literal";
-            break;
-        }
-        case Compare_kind:
-            expr_name = "comparison";
-            break;
-        case IfExp_kind:
-            expr_name = "conditional expression";
-            break;
-        case NamedExpr_kind:
-            expr_name = "named expression";
-            break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "unexpected expression in %sassignment %d (line %d)",
-                         ctx == NamedStore ? "named ": "",
-                         e->kind, e->lineno);
             return 0;
-    }
-    /* Check for error string set by switch */
-    if (expr_name) {
-        if (ctx == NamedStore) {
-            return ast_error(c, n, "cannot use named assignment with %s",
-                         expr_name);
-        }
-        else {
-            return ast_error(c, n, "cannot %s %s",
-                         ctx == Store ? "assign to" : "delete",
-                         expr_name);
         }
     }
 
@@ -1895,7 +1868,15 @@
     if (!value)
         return NULL;
 
-    if (!set_context(c, target, NamedStore, n))
+    if (target->kind != Name_kind) {
+        const char *expr_name = get_expr_name(target);
+        if (expr_name != NULL) {
+            ast_error(c, n, "cannot use named assignment with %s", expr_name);
+        }
+        return NULL;
+    }
+
+    if (!set_context(c, target, Store, n))
         return NULL;
 
     return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno,
diff --git a/Python/compile.c b/Python/compile.c
index 18877d9..c262106 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -3429,7 +3429,6 @@
             op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
             break;
         case Store:
-        case NamedStore:
             op = STORE_DEREF;
             break;
         case AugLoad:
@@ -3447,7 +3446,6 @@
         switch (ctx) {
         case Load: op = LOAD_FAST; break;
         case Store:
-        case NamedStore:
             op = STORE_FAST;
             break;
         case Del: op = DELETE_FAST; break;
@@ -3466,7 +3464,6 @@
         switch (ctx) {
         case Load: op = LOAD_GLOBAL; break;
         case Store:
-        case NamedStore:
             op = STORE_GLOBAL;
             break;
         case Del: op = DELETE_GLOBAL; break;
@@ -3484,7 +3481,6 @@
         switch (ctx) {
         case Load: op = LOAD_NAME; break;
         case Store:
-        case NamedStore:
             op = STORE_NAME;
             break;
         case Del: op = DELETE_NAME; break;
@@ -3604,7 +3600,7 @@
 compiler_list(struct compiler *c, expr_ty e)
 {
     asdl_seq *elts = e->v.List.elts;
-    if (e->v.List.ctx == Store || e->v.List.ctx == NamedStore) {
+    if (e->v.List.ctx == Store) {
         return assignment_helper(c, elts);
     }
     else if (e->v.List.ctx == Load) {
@@ -3620,7 +3616,7 @@
 compiler_tuple(struct compiler *c, expr_ty e)
 {
     asdl_seq *elts = e->v.Tuple.elts;
-    if (e->v.Tuple.ctx == Store || e->v.Tuple.ctx == NamedStore) {
+    if (e->v.Tuple.ctx == Store) {
         return assignment_helper(c, elts);
     }
     else if (e->v.Tuple.ctx == Load) {
@@ -5154,7 +5150,6 @@
         case AugStore:/* fall through to Store */
         case Store:   op = STORE_SUBSCR; break;
         case Del:     op = DELETE_SUBSCR; break;
-        case NamedStore:
         case Param:
             PyErr_Format(PyExc_SystemError,
                          "invalid %s kind %d in subscript\n",
diff --git a/Python/symtable.c b/Python/symtable.c
index 6e2df2f..1d68a7d 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -1452,6 +1452,10 @@
     }
     switch (e->kind) {
     case NamedExpr_kind:
+        if (st->st_cur->ste_comprehension) {
+            if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target))
+                VISIT_QUIT(st, 0);
+        }
         VISIT(st, expr, e->v.NamedExpr.value);
         VISIT(st, expr, e->v.NamedExpr.target);
         break;
@@ -1555,11 +1559,6 @@
         VISIT(st, expr, e->v.Starred.value);
         break;
     case Name_kind:
-        /* Special-case: named expr */
-        if (e->v.Name.ctx == NamedStore && st->st_cur->ste_comprehension) {
-            if(!symtable_extend_namedexpr_scope(st, e))
-                VISIT_QUIT(st, 0);
-        }
         if (!symtable_add_def(st, e->v.Name.id,
                               e->v.Name.ctx == Load ? USE : DEF_LOCAL))
             VISIT_QUIT(st, 0);