bpo-28765: Use concrete types API in _sre.c. (#1009)

diff --git a/Modules/_sre.c b/Modules/_sre.c
index 84c47bb..ef8295a 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -701,6 +701,9 @@
 {
     PyObject* copy;
 
+    if (!*object)
+        return 1;
+
     copy = call(
         "copy", "deepcopy",
         PyTuple_Pack(2, *object, memo)
@@ -1368,6 +1371,8 @@
 static PyObject *
 pattern_groupindex(PatternObject *self)
 {
+    if (self->groupindex == NULL)
+        return PyDict_New();
     return PyDictProxy_New(self->groupindex);
 }
 
@@ -1448,11 +1453,14 @@
 
     self->groups = groups;
 
-    Py_INCREF(groupindex);
-    self->groupindex = groupindex;
-
-    Py_INCREF(indexgroup);
-    self->indexgroup = indexgroup;
+    if (PyDict_GET_SIZE(groupindex) > 0) {
+        Py_INCREF(groupindex);
+        self->groupindex = groupindex;
+        if (PyTuple_GET_SIZE(indexgroup) > 0) {
+            Py_INCREF(indexgroup);
+            self->indexgroup = indexgroup;
+        }
+    }
 
     if (!_validate(self)) {
         Py_DECREF(self);
@@ -1994,13 +2002,10 @@
     i = -1;
 
     if (self->pattern->groupindex) {
-        index = PyObject_GetItem(self->pattern->groupindex, index);
-        if (index) {
-            if (PyLong_Check(index))
-                i = PyLong_AsSsize_t(index);
-            Py_DECREF(index);
-        } else
-            PyErr_Clear();
+        index = PyDict_GetItem(self->pattern->groupindex, index);
+        if (index && PyLong_Check(index)) {
+            i = PyLong_AsSsize_t(index);
+        }
     }
 
     return i;
@@ -2118,40 +2123,34 @@
 _sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value)
 /*[clinic end generated code: output=29917c9073e41757 input=0ded7960b23780aa]*/
 {
-    PyObject* result;
-    PyObject* keys;
-    Py_ssize_t index;
+    PyObject *result;
+    PyObject *key;
+    PyObject *value;
+    Py_ssize_t pos = 0;
+    Py_hash_t hash;
 
     result = PyDict_New();
     if (!result || !self->pattern->groupindex)
         return result;
 
-    keys = PyMapping_Keys(self->pattern->groupindex);
-    if (!keys)
-        goto failed;
-
-    for (index = 0; index < PyList_GET_SIZE(keys); index++) {
+    while (_PyDict_Next(self->pattern->groupindex, &pos, &key, &value, &hash)) {
         int status;
-        PyObject* key;
-        PyObject* value;
-        key = PyList_GET_ITEM(keys, index);
-        if (!key)
-            goto failed;
+        Py_INCREF(key);
         value = match_getslice(self, key, default_value);
-        if (!value)
+        if (!value) {
+            Py_DECREF(key);
             goto failed;
-        status = PyDict_SetItem(result, key, value);
+        }
+        status = _PyDict_SetItem_KnownHash(result, key, value, hash);
         Py_DECREF(value);
+        Py_DECREF(key);
         if (status < 0)
             goto failed;
     }
 
-    Py_DECREF(keys);
-
     return result;
 
 failed:
-    Py_XDECREF(keys);
     Py_DECREF(result);
     return NULL;
 }
@@ -2378,13 +2377,14 @@
 static PyObject *
 match_lastgroup_get(MatchObject *self)
 {
-    if (self->pattern->indexgroup && self->lastindex >= 0) {
-        PyObject* result = PySequence_GetItem(
-            self->pattern->indexgroup, self->lastindex
-            );
-        if (result)
-            return result;
-        PyErr_Clear();
+    if (self->pattern->indexgroup &&
+        self->lastindex >= 0 &&
+        self->lastindex < PyTuple_GET_SIZE(self->pattern->indexgroup))
+    {
+        PyObject *result = PyTuple_GET_ITEM(self->pattern->indexgroup,
+                                            self->lastindex);
+        Py_INCREF(result);
+        return result;
     }
     Py_RETURN_NONE;
 }