[Python-checkins] cpython (3.2): Issue #10914: Add a minimal embedding test to test_capi.

antoine.pitrou python-checkins at python.org
Mon Apr 25 21:23:40 CEST 2011


http://hg.python.org/cpython/rev/d195ff5c44f4
changeset:   69553:d195ff5c44f4
branch:      3.2
parent:      69547:66ef5e844e6c
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Mon Apr 25 21:21:07 2011 +0200
summary:
  Issue #10914: Add a minimal embedding test to test_capi.

files:
  .hgignore             |   1 +
  Lib/test/test_capi.py |  35 +++++++++++++++++++-
  Makefile.pre.in       |   5 ++-
  Modules/_testembed.c  |  52 +++++++++++++++++++++++++++++++
  4 files changed, 89 insertions(+), 4 deletions(-)


diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -64,3 +64,4 @@
 PCbuild/*.bsc
 PCbuild/Win32-temp-*
 __pycache__
+Modules/_testembed
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -2,6 +2,7 @@
 # these are all functions _testcapi exports whose name begins with 'test_'.
 
 from __future__ import with_statement
+import os
 import random
 import subprocess
 import sys
@@ -141,8 +142,38 @@
     def test(self):
         self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
 
+
+class EmbeddingTest(unittest.TestCase):
+
+    def test_subinterps(self):
+        # XXX only tested under Unix checkouts
+        basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
+        oldcwd = os.getcwd()
+        # This is needed otherwise we get a fatal error:
+        # "Py_Initialize: Unable to get the locale encoding
+        # LookupError: no codec search functions registered: can't find encoding"
+        os.chdir(basepath)
+        try:
+            exe = os.path.join(basepath, "Modules", "_testembed")
+            if not os.path.exists(exe):
+                self.skipTest("%r doesn't exist" % exe)
+            p = subprocess.Popen([exe],
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE)
+            (out, err) = p.communicate()
+            self.assertEqual(p.returncode, 0,
+                             "bad returncode %d, stderr is %r" %
+                             (p.returncode, err))
+            if support.verbose:
+                print()
+                print(out.decode('latin1'))
+                print(err.decode('latin1'))
+        finally:
+            os.chdir(oldcwd)
+
+
 def test_main():
-    support.run_unittest(CAPITest)
+    support.run_unittest(CAPITest, TestPendingCalls, Test6012, EmbeddingTest)
 
     for name in dir(_testcapi):
         if name.startswith('test_'):
@@ -177,8 +208,6 @@
         t.start()
         t.join()
 
-    support.run_unittest(TestPendingCalls, Test6012)
-
 
 if __name__ == "__main__":
     test_main()
diff --git a/Makefile.pre.in b/Makefile.pre.in
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -394,7 +394,7 @@
 
 # Default target
 all:		build_all
-build_all:	$(BUILDPYTHON) oldsharedmods sharedmods gdbhooks
+build_all:	$(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Modules/_testembed
 
 # Compile a binary with gcc profile guided optimization.
 profile-opt:
@@ -539,6 +539,9 @@
 		echo "-----------------------------------------------"; \
 	fi
 
+Modules/_testembed: Modules/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
+	$(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
+
 ############################################################################
 # Special rules for object files
 
diff --git a/Modules/_testembed.c b/Modules/_testembed.c
new file mode 100644
--- /dev/null
+++ b/Modules/_testembed.c
@@ -0,0 +1,52 @@
+#include <Python.h>
+#include <stdio.h>
+
+void print_subinterp(void)
+{
+    /* Just output some debug stuff */
+    PyThreadState *ts = PyThreadState_Get();
+    printf("interp %p, thread state %p: ", ts->interp, ts);
+    fflush(stdout);
+    PyRun_SimpleString(
+        "import sys;"
+        "print('id(modules) =', id(sys.modules));"
+        "sys.stdout.flush()"
+    );
+}
+
+int main(int argc, char *argv[])
+{
+    PyThreadState *mainstate, *substate;
+    PyGILState_STATE gilstate;
+    int i, j;
+
+    for (i=0; i<3; i++) {
+        printf("--- Pass %d ---\n", i);
+        /* HACK: the "./" at front avoids a search along the PATH in
+           Modules/getpath.c */
+        Py_SetProgramName(L"./_testembed");
+        Py_Initialize();
+        mainstate = PyThreadState_Get();
+
+        PyEval_InitThreads();
+        PyEval_ReleaseThread(mainstate);
+
+        gilstate = PyGILState_Ensure();
+        print_subinterp();
+        PyThreadState_Swap(NULL);
+
+        for (j=0; j<3; j++) {
+            substate = Py_NewInterpreter();
+            print_subinterp();
+            Py_EndInterpreter(substate);
+        }
+
+        PyThreadState_Swap(mainstate);
+        print_subinterp();
+        PyGILState_Release(gilstate);
+
+        PyEval_RestoreThread(mainstate);
+        Py_Finalize();
+    }
+    return 0;
+}

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list