Issue #25698: Importing module if the stack is too deep no longer replaces
imported module with the empty one.
diff --git a/Include/dictobject.h b/Include/dictobject.h
index ece01c6..ef524a4 100644
--- a/Include/dictobject.h
+++ b/Include/dictobject.h
@@ -108,6 +108,7 @@
 
 PyAPI_FUNC(PyObject *) PyDict_New(void);
 PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
+PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *mp, PyObject *key);
 PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
 PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
 PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
diff --git a/Misc/NEWS b/Misc/NEWS
index a917523..659d7ca 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,9 @@
 Library
 -------
 
+- Issue #25698: Importing module if the stack is too deep no longer replaces
+  imported module with the empty one.
+
 - Issue #12923: Reset FancyURLopener's redirect counter even if there is an
   exception.  Based on patches by Brian Brazil and Daniel Rocco.
 
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index b281948..3e1c583 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -749,6 +749,36 @@
     return ep->me_value;
 }
 
+/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
+   This returns NULL *with* an exception set if an exception occurred.
+   It returns NULL *without* an exception set if the key wasn't present.
+*/
+PyObject *
+_PyDict_GetItemWithError(PyObject *op, PyObject *key)
+{
+    long hash;
+    PyDictObject *mp = (PyDictObject *)op;
+    PyDictEntry *ep;
+    if (!PyDict_Check(op)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    if (!PyString_CheckExact(key) ||
+        (hash = ((PyStringObject *) key)->ob_shash) == -1)
+    {
+        hash = PyObject_Hash(key);
+        if (hash == -1) {
+            return NULL;
+        }
+    }
+
+    ep = (mp->ma_lookup)(mp, key, hash);
+    if (ep == NULL) {
+        return NULL;
+    }
+    return ep->me_value;
+}
+
 static int
 dict_set_item_by_hash_or_entry(register PyObject *op, PyObject *key,
                                long hash, PyDictEntry *ep, PyObject *value)
diff --git a/Python/import.c b/Python/import.c
index e47ce63..96f7d47 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -632,27 +632,45 @@
    Because the former action is most common, THIS DOES NOT RETURN A
    'NEW' REFERENCE! */
 
-PyObject *
-PyImport_AddModule(const char *name)
+static PyObject *
+_PyImport_AddModuleObject(PyObject *name)
 {
     PyObject *modules = PyImport_GetModuleDict();
     PyObject *m;
 
-    if ((m = PyDict_GetItemString(modules, name)) != NULL &&
-        PyModule_Check(m))
+    if ((m = _PyDict_GetItemWithError(modules, name)) != NULL &&
+        PyModule_Check(m)) {
         return m;
-    m = PyModule_New(name);
-    if (m == NULL)
+    }
+    if (PyErr_Occurred()) {
         return NULL;
-    if (PyDict_SetItemString(modules, name, m) != 0) {
+    }
+    m = PyModule_New(PyString_AS_STRING(name));
+    if (m == NULL) {
+        return NULL;
+    }
+    if (PyDict_SetItem(modules, name, m) != 0) {
         Py_DECREF(m);
         return NULL;
     }
+    assert(Py_REFCNT(m) > 1);
     Py_DECREF(m); /* Yes, it still exists, in modules! */
 
     return m;
 }
 
+PyObject *
+PyImport_AddModule(const char *name)
+{
+    PyObject *nameobj, *module;
+    nameobj = PyString_FromString(name);
+    if (nameobj == NULL)
+        return NULL;
+    module = _PyImport_AddModuleObject(nameobj);
+    Py_DECREF(nameobj);
+    return module;
+}
+
 /* Remove name from sys.modules, if it's there. */
 static void
 remove_module(const char *name)