diff --git a/docs/examples/tutorial/pure/py_cimport.py b/docs/examples/tutorial/pure/py_cimport.py
new file mode 100644
index 0000000000000000000000000000000000000000..233ddde7ec141a4f710ece3b4675e2f5e5e9fcd0
--- /dev/null
+++ b/docs/examples/tutorial/pure/py_cimport.py
@@ -0,0 +1,5 @@
+
+from cython.cimports.libc import math
+
+def use_libc_math():
+    return math.ceil(5.5)
diff --git a/docs/src/tutorial/pure.rst b/docs/src/tutorial/pure.rst
index 4665de95a75fd972d20178c3d68696f4277fe6e8..8be08fece2eea055916f3942a278ecfd5ee47983 100644
--- a/docs/src/tutorial/pure.rst
+++ b/docs/src/tutorial/pure.rst
@@ -218,11 +218,7 @@ libraries become available to Python code.  It only means that you can
 tell Cython what cimports you want to use, without requiring special
 syntax.  Running such code in plain Python will fail.
 
-::
-
-    from cython.cimports.libc import math
-
-    print(math.ceil(5.5))
+.. literalinclude:: ../../examples/tutorial/pure/py_cimport.py
 
 Since such code must necessarily refer to the non-existing
 ``cython.cimports`` 'package', the plain cimport form
diff --git a/runtests.py b/runtests.py
index 3dd27fcbc5be3c32fa48ba15b48832d09ebc7f16..702fc3a024eec2a00d72712c85d79aef848a33c6 100755
--- a/runtests.py
+++ b/runtests.py
@@ -980,6 +980,15 @@ class CythonCompileTestCase(unittest.TestCase):
         if self.workdir not in sys.path:
             sys.path.insert(0, self.workdir)
 
+        if self.add_cython_import:
+            with open(self.module_path, 'rb') as f:
+                source = f.read()
+                if b'cython.cimports.' in source:
+                    from Cython.Shadow import CythonCImports
+                    for name in set(re.findall(br"(cython\.cimports(?:\.\w+)+)", source)):
+                        name = name.decode()
+                        sys.modules[name] = CythonCImports(name)
+
     def tearDown(self):
         from Cython.Compiler import Options
         for name, value in self._saved_options:
@@ -995,6 +1004,13 @@ class CythonCompileTestCase(unittest.TestCase):
             del sys.modules[self.module]
         except KeyError:
             pass
+
+        # remove any stubs of cimported modules in pure Python mode
+        if self.add_cython_import:
+            for name in list(sys.modules):
+                if name.startswith('cython.cimports.'):
+                    del sys.modules[name]
+
         cleanup = self.cleanup_failures or self.success
         cleanup_c_files = WITH_CYTHON and self.cleanup_workdir and cleanup
         cleanup_lib_files = self.cleanup_sharedlibs and cleanup