bpo-39988: Remove ast.AugLoad and ast.AugStore node classes. (GH-19038)

diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index fd3d333..6a6d1ee 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -678,9 +678,10 @@
   defining ``COUNT_ALLOCS`` macro.
   (Contributed by Victor Stinner in :issue:`39489`.)
 
-* The ``ast.Suite`` and ``ast.Param`` node classes has been removed due to no
-  longer being needed.
-  (Contributed by Batuhan Taskaya in :issue:`39639` and :issue:`39969`.)
+* The ``ast.Suite``, ``ast.Param``, ``ast.AugLoad`` and ``ast.AugStore``
+  node classes have been removed due to no longer being needed.
+  (Contributed by Batuhan Taskaya in :issue:`39639` and :issue:`39969`
+  and Serhiy Storchaka in :issue:`39988`.)
 
 
 Porting to Python 3.9
diff --git a/Include/Python-ast.h b/Include/Python-ast.h
index c44d6ea..7db0037 100644
--- a/Include/Python-ast.h
+++ b/Include/Python-ast.h
@@ -17,8 +17,7 @@
 
 typedef struct _expr *expr_ty;
 
-typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5 }
-                             expr_context_ty;
+typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty;
 
 typedef enum _boolop { And=1, Or=2 } boolop_ty;
 
diff --git a/Misc/NEWS.d/next/Library/2020-03-17-09-35-00.bpo-39988.kXGl35.rst b/Misc/NEWS.d/next/Library/2020-03-17-09-35-00.bpo-39988.kXGl35.rst
new file mode 100644
index 0000000..018e4cc
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-03-17-09-35-00.bpo-39988.kXGl35.rst
@@ -0,0 +1,2 @@
+Removed ``ast.AugLoad`` and ``ast.AugStore`` node classes because they are
+no longer used.
diff --git a/Parser/Python.asdl b/Parser/Python.asdl
index 19b5e1a..11d877d 100644
--- a/Parser/Python.asdl
+++ b/Parser/Python.asdl
@@ -90,7 +90,7 @@
           -- col_offset is the byte offset in the utf8 string the parser uses
           attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
 
-    expr_context = Load | Store | Del | AugLoad | AugStore
+    expr_context = Load | Store | Del
 
     boolop = And | Or
 
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 96ecc31..aba83fb 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -21,10 +21,6 @@
     PyObject *AsyncWith_type;
     PyObject *Attribute_type;
     PyObject *AugAssign_type;
-    PyObject *AugLoad_singleton;
-    PyObject *AugLoad_type;
-    PyObject *AugStore_singleton;
-    PyObject *AugStore_type;
     PyObject *Await_type;
     PyObject *BinOp_type;
     PyObject *BitAnd_singleton;
@@ -245,10 +241,6 @@
     Py_CLEAR(astmodulestate(module)->AsyncWith_type);
     Py_CLEAR(astmodulestate(module)->Attribute_type);
     Py_CLEAR(astmodulestate(module)->AugAssign_type);
-    Py_CLEAR(astmodulestate(module)->AugLoad_singleton);
-    Py_CLEAR(astmodulestate(module)->AugLoad_type);
-    Py_CLEAR(astmodulestate(module)->AugStore_singleton);
-    Py_CLEAR(astmodulestate(module)->AugStore_type);
     Py_CLEAR(astmodulestate(module)->Await_type);
     Py_CLEAR(astmodulestate(module)->BinOp_type);
     Py_CLEAR(astmodulestate(module)->BitAnd_singleton);
@@ -468,10 +460,6 @@
     Py_VISIT(astmodulestate(module)->AsyncWith_type);
     Py_VISIT(astmodulestate(module)->Attribute_type);
     Py_VISIT(astmodulestate(module)->AugAssign_type);
-    Py_VISIT(astmodulestate(module)->AugLoad_singleton);
-    Py_VISIT(astmodulestate(module)->AugLoad_type);
-    Py_VISIT(astmodulestate(module)->AugStore_singleton);
-    Py_VISIT(astmodulestate(module)->AugStore_type);
     Py_VISIT(astmodulestate(module)->Await_type);
     Py_VISIT(astmodulestate(module)->BinOp_type);
     Py_VISIT(astmodulestate(module)->BitAnd_singleton);
@@ -1728,7 +1716,7 @@
         return 0;
     state->expr_context_type = make_type("expr_context", state->AST_type, NULL,
                                          0,
-        "expr_context = Load | Store | Del | AugLoad | AugStore");
+        "expr_context = Load | Store | Del");
     if (!state->expr_context_type) return 0;
     if (!add_attributes(state->expr_context_type, NULL, 0)) return 0;
     state->Load_type = make_type("Load", state->expr_context_type, NULL, 0,
@@ -1749,22 +1737,6 @@
     state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type,
                                              NULL, NULL);
     if (!state->Del_singleton) return 0;
-    state->AugLoad_type = make_type("AugLoad", state->expr_context_type, NULL,
-                                    0,
-        "AugLoad");
-    if (!state->AugLoad_type) return 0;
-    state->AugLoad_singleton = PyType_GenericNew((PyTypeObject
-                                                 *)state->AugLoad_type, NULL,
-                                                 NULL);
-    if (!state->AugLoad_singleton) return 0;
-    state->AugStore_type = make_type("AugStore", state->expr_context_type,
-                                     NULL, 0,
-        "AugStore");
-    if (!state->AugStore_type) return 0;
-    state->AugStore_singleton = PyType_GenericNew((PyTypeObject
-                                                  *)state->AugStore_type, NULL,
-                                                  NULL);
-    if (!state->AugStore_singleton) return 0;
     state->boolop_type = make_type("boolop", state->AST_type, NULL, 0,
         "boolop = And | Or");
     if (!state->boolop_type) return 0;
@@ -4614,12 +4586,6 @@
         case Del:
             Py_INCREF(astmodulestate_global->Del_singleton);
             return astmodulestate_global->Del_singleton;
-        case AugLoad:
-            Py_INCREF(astmodulestate_global->AugLoad_singleton);
-            return astmodulestate_global->AugLoad_singleton;
-        case AugStore:
-            Py_INCREF(astmodulestate_global->AugStore_singleton);
-            return astmodulestate_global->AugStore_singleton;
         default:
             /* should never happen, but just in case ... */
             PyErr_Format(PyExc_SystemError, "unknown expr_context found");
@@ -8809,22 +8775,6 @@
         *out = Del;
         return 0;
     }
-    isinstance = PyObject_IsInstance(obj, astmodulestate_global->AugLoad_type);
-    if (isinstance == -1) {
-        return 1;
-    }
-    if (isinstance) {
-        *out = AugLoad;
-        return 0;
-    }
-    isinstance = PyObject_IsInstance(obj, astmodulestate_global->AugStore_type);
-    if (isinstance == -1) {
-        return 1;
-    }
-    if (isinstance) {
-        *out = AugStore;
-        return 0;
-    }
 
     PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
     return 1;
@@ -10163,16 +10113,6 @@
         goto error;
     }
     Py_INCREF(astmodulestate(m)->Del_type);
-    if (PyModule_AddObject(m, "AugLoad", astmodulestate_global->AugLoad_type) <
-        0) {
-        goto error;
-    }
-    Py_INCREF(astmodulestate(m)->AugLoad_type);
-    if (PyModule_AddObject(m, "AugStore", astmodulestate_global->AugStore_type)
-        < 0) {
-        goto error;
-    }
-    Py_INCREF(astmodulestate(m)->AugStore_type);
     if (PyModule_AddObject(m, "boolop", astmodulestate_global->boolop_type) <
         0) {
         goto error;
diff --git a/Python/ast.c b/Python/ast.c
index 1c1395f..2e9a8d0 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -71,10 +71,6 @@
         return "Store";
     case Del:
         return "Del";
-    case AugLoad:
-        return "AugLoad";
-    case AugStore:
-        return "AugStore";
     default:
         Py_UNREACHABLE();
     }
@@ -1099,14 +1095,7 @@
 {
     asdl_seq *s = NULL;
 
-    /* The ast defines augmented store and load contexts, but the
-       implementation here doesn't actually use them.  The code may be
-       a little more complex than necessary as a result.  It also means
-       that expressions in an augmented assignment have a Store context.
-       Consider restructuring so that augmented assignment uses
-       set_context(), too.
-    */
-    assert(ctx != AugStore && ctx != AugLoad);
+    /* Expressions in an augmented assignment have a Store context. */
 
     switch (e->kind) {
         case Attribute_kind:
diff --git a/Python/compile.c b/Python/compile.c
index d98caba..486b7bb 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -3506,7 +3506,6 @@
 
     PyObject *dict = c->u->u_names;
     PyObject *mangled;
-    /* XXX AugStore isn't used anywhere! */
 
     assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
            !_PyUnicode_EqualToASCIIString(name, "True") &&
@@ -3553,70 +3552,30 @@
         case Load:
             op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
             break;
-        case Store:
-            op = STORE_DEREF;
-            break;
-        case AugLoad:
-        case AugStore:
-            break;
+        case Store: op = STORE_DEREF; break;
         case Del: op = DELETE_DEREF; break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "expr_context kind %d should not be possible",
-                         ctx);
-            return 0;
         }
         break;
     case OP_FAST:
         switch (ctx) {
         case Load: op = LOAD_FAST; break;
-        case Store:
-            op = STORE_FAST;
-            break;
+        case Store: op = STORE_FAST; break;
         case Del: op = DELETE_FAST; break;
-        case AugLoad:
-        case AugStore:
-            break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "expr_context kind %d should not be possible",
-                         ctx);
-            return 0;
         }
         ADDOP_N(c, op, mangled, varnames);
         return 1;
     case OP_GLOBAL:
         switch (ctx) {
         case Load: op = LOAD_GLOBAL; break;
-        case Store:
-            op = STORE_GLOBAL;
-            break;
+        case Store: op = STORE_GLOBAL; break;
         case Del: op = DELETE_GLOBAL; break;
-        case AugLoad:
-        case AugStore:
-            break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "expr_context kind %d should not be possible",
-                         ctx);
-            return 0;
         }
         break;
     case OP_NAME:
         switch (ctx) {
         case Load: op = LOAD_NAME; break;
-        case Store:
-            op = STORE_NAME;
-            break;
+        case Store: op = STORE_NAME; break;
         case Del: op = DELETE_NAME; break;
-        case AugLoad:
-        case AugStore:
-            break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "expr_context kind %d should not be possible",
-                         ctx);
-            return 0;
         }
         break;
     }
@@ -5021,29 +4980,17 @@
         return compiler_formatted_value(c, e);
     /* The following exprs can be assignment targets. */
     case Attribute_kind:
-        if (e->v.Attribute.ctx != AugStore)
-            VISIT(c, expr, e->v.Attribute.value);
+        VISIT(c, expr, e->v.Attribute.value);
         switch (e->v.Attribute.ctx) {
-        case AugLoad:
-            ADDOP(c, DUP_TOP);
-            /* Fall through */
         case Load:
             ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
             break;
-        case AugStore:
-            ADDOP(c, ROT_TWO);
-            /* Fall through */
         case Store:
             ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
             break;
         case Del:
             ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
             break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "expr_context kind %d should not be possible",
-                         e->v.Attribute.ctx);
-            return 0;
         }
         break;
     case Subscript_kind:
@@ -5088,48 +5035,58 @@
 static int
 compiler_augassign(struct compiler *c, stmt_ty s)
 {
-    expr_ty e = s->v.AugAssign.target;
-    expr_ty auge;
-
     assert(s->kind == AugAssign_kind);
+    expr_ty e = s->v.AugAssign.target;
+
+    int old_lineno = c->u->u_lineno;
+    int old_col_offset = c->u->u_col_offset;
+    SET_LOC(c, e);
 
     switch (e->kind) {
     case Attribute_kind:
-        auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,
-                         AugLoad, e->lineno, e->col_offset,
-                         e->end_lineno, e->end_col_offset, c->c_arena);
-        if (auge == NULL)
-            return 0;
-        VISIT(c, expr, auge);
-        VISIT(c, expr, s->v.AugAssign.value);
-        ADDOP(c, inplace_binop(s->v.AugAssign.op));
-        auge->v.Attribute.ctx = AugStore;
-        VISIT(c, expr, auge);
+        VISIT(c, expr, e->v.Attribute.value);
+        ADDOP(c, DUP_TOP);
+        ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
         break;
     case Subscript_kind:
-        auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,
-                         AugLoad, e->lineno, e->col_offset,
-                         e->end_lineno, e->end_col_offset, c->c_arena);
-        if (auge == NULL)
-            return 0;
-        VISIT(c, expr, auge);
-        VISIT(c, expr, s->v.AugAssign.value);
-        ADDOP(c, inplace_binop(s->v.AugAssign.op));
-        auge->v.Subscript.ctx = AugStore;
-        VISIT(c, expr, auge);
+        VISIT(c, expr, e->v.Subscript.value);
+        VISIT(c, expr, e->v.Subscript.slice);
+        ADDOP(c, DUP_TOP_TWO);
+        ADDOP(c, BINARY_SUBSCR);
         break;
     case Name_kind:
         if (!compiler_nameop(c, e->v.Name.id, Load))
             return 0;
-        VISIT(c, expr, s->v.AugAssign.value);
-        ADDOP(c, inplace_binop(s->v.AugAssign.op));
-        return compiler_nameop(c, e->v.Name.id, Store);
+        break;
     default:
         PyErr_Format(PyExc_SystemError,
             "invalid node type (%d) for augmented assignment",
             e->kind);
         return 0;
     }
+
+    c->u->u_lineno = old_lineno;
+    c->u->u_col_offset = old_col_offset;
+
+    VISIT(c, expr, s->v.AugAssign.value);
+    ADDOP(c, inplace_binop(s->v.AugAssign.op));
+
+    SET_LOC(c, e);
+
+    switch (e->kind) {
+    case Attribute_kind:
+        ADDOP(c, ROT_TWO);
+        ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
+        break;
+    case Subscript_kind:
+        ADDOP(c, ROT_THREE);
+        ADDOP(c, STORE_SUBSCR);
+        break;
+    case Name_kind:
+        return compiler_nameop(c, e->v.Name.id, Store);
+    default:
+        Py_UNREACHABLE();
+    }
     return 1;
 }
 
@@ -5322,27 +5279,13 @@
     }
 
     switch (ctx) {
-        case AugLoad: /* fall through to Load */
         case Load:    op = BINARY_SUBSCR; break;
-        case AugStore:/* fall through to Store */
         case Store:   op = STORE_SUBSCR; break;
         case Del:     op = DELETE_SUBSCR; break;
-        default:
-            PyErr_Format(PyExc_SystemError,
-                         "expr_context kind %d should not be possible",
-                         ctx);
-            return 0;
     }
-    if (ctx == AugStore) {
-        ADDOP(c, ROT_THREE);
-    }
-    else {
-        VISIT(c, expr, e->v.Subscript.value);
-        VISIT(c, expr, e->v.Subscript.slice);
-        if (ctx == AugLoad) {
-            ADDOP(c, DUP_TOP_TWO);
-        }
-    }
+    assert(op);
+    VISIT(c, expr, e->v.Subscript.value);
+    VISIT(c, expr, e->v.Subscript.slice);
     ADDOP(c, op);
     return 1;
 }