Issue #10914: Add a minimal embedding test to test_capi.

This commit is contained in:
Antoine Pitrou 2011-04-25 21:23:26 +02:00
commit eec60603a8
5 changed files with 91 additions and 4 deletions

View File

@ -69,3 +69,4 @@ PCbuild/*.suo
PCbuild/Win32-temp-* PCbuild/Win32-temp-*
PCbuild/x64-temp-* PCbuild/x64-temp-*
__pycache__ __pycache__
Modules/_testembed

View File

@ -2,6 +2,7 @@
# these are all functions _testcapi exports whose name begins with 'test_'. # these are all functions _testcapi exports whose name begins with 'test_'.
from __future__ import with_statement from __future__ import with_statement
import os
import random import random
import subprocess import subprocess
import sys import sys
@ -141,8 +142,38 @@ class Test6012(unittest.TestCase):
def test(self): def test(self):
self.assertEqual(_testcapi.argparsing("Hello", "World"), 1) 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(): def test_main():
support.run_unittest(CAPITest) support.run_unittest(CAPITest, TestPendingCalls, Test6012, EmbeddingTest)
for name in dir(_testcapi): for name in dir(_testcapi):
if name.startswith('test_'): if name.startswith('test_'):
@ -177,8 +208,6 @@ def test_main():
t.start() t.start()
t.join() t.join()
support.run_unittest(TestPendingCalls, Test6012)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()

View File

@ -394,7 +394,7 @@ LIBRARY_OBJS= \
# Default target # Default target
all: build_all 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. # Compile a binary with gcc profile guided optimization.
profile-opt: profile-opt:
@ -539,6 +539,9 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist
echo "-----------------------------------------------"; \ echo "-----------------------------------------------"; \
fi 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 # Special rules for object files

View File

@ -504,6 +504,8 @@ Extensions
Tests Tests
----- -----
- Issue #10914: Add a minimal embedding test to test_capi.
- Issue #11223: Skip test_lock_acquire_interruption() and - Issue #11223: Skip test_lock_acquire_interruption() and
test_rlock_acquire_interruption() of test_threadsignals if a thread lock is test_rlock_acquire_interruption() of test_threadsignals if a thread lock is
implemented using a POSIX mutex and a POSIX condition variable. A POSIX implemented using a POSIX mutex and a POSIX condition variable. A POSIX

52
Modules/_testembed.c Normal file
View File

@ -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;
}