mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Issue #10914: Add a minimal embedding test to test_capi.
This commit is contained in:
		
							parent
							
								
									b32321aed9
								
							
						
					
					
						commit
						8e60577693
					
				
					 4 changed files with 89 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -64,3 +64,4 @@ PCbuild/*.ncb
 | 
			
		|||
PCbuild/*.bsc
 | 
			
		||||
PCbuild/Win32-temp-*
 | 
			
		||||
__pycache__
 | 
			
		||||
Modules/_testembed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 @@ class Test6012(unittest.TestCase):
 | 
			
		|||
    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 @@ def callback():
 | 
			
		|||
        t.start()
 | 
			
		||||
        t.join()
 | 
			
		||||
 | 
			
		||||
    support.run_unittest(TestPendingCalls, Test6012)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    test_main()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -394,7 +394,7 @@ LIBRARY_OBJS=	\
 | 
			
		|||
 | 
			
		||||
# 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 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist
 | 
			
		|||
		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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										52
									
								
								Modules/_testembed.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								Modules/_testembed.c
									
										
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue