1 #include <Python.h> 2 #include <stdio.h> 3 4 /********************************************************* 5 * Embedded interpreter tests that need a custom exe 6 * 7 * Executed via 'EmbeddingTests' in Lib/test/test_capi.py 8 *********************************************************/ 9 10 static void _testembed_Py_Initialize(void) 11 { 12 /* HACK: the "./" at front avoids a search along the PATH in 13 Modules/getpath.c */ 14 Py_SetProgramName(L"./_testembed"); 15 Py_Initialize(); 16 } 17 18 19 /***************************************************** 20 * Test repeated initialisation and subinterpreters 21 *****************************************************/ 22 23 static void print_subinterp(void) 24 { 25 /* Just output some debug stuff */ 26 PyThreadState *ts = PyThreadState_Get(); 27 printf("interp %p, thread state %p: ", ts->interp, ts); 28 fflush(stdout); 29 PyRun_SimpleString( 30 "import sys;" 31 "print('id(modules) =', id(sys.modules));" 32 "sys.stdout.flush()" 33 ); 34 } 35 36 static void test_repeated_init_and_subinterpreters(void) 37 { 38 PyThreadState *mainstate, *substate; 39 #ifdef WITH_THREAD 40 PyGILState_STATE gilstate; 41 #endif 42 int i, j; 43 44 for (i=0; i<15; i++) { 45 printf("--- Pass %d ---\n", i); 46 _testembed_Py_Initialize(); 47 mainstate = PyThreadState_Get(); 48 49 #ifdef WITH_THREAD 50 PyEval_InitThreads(); 51 PyEval_ReleaseThread(mainstate); 52 53 gilstate = PyGILState_Ensure(); 54 #endif 55 print_subinterp(); 56 PyThreadState_Swap(NULL); 57 58 for (j=0; j<3; j++) { 59 substate = Py_NewInterpreter(); 60 print_subinterp(); 61 Py_EndInterpreter(substate); 62 } 63 64 PyThreadState_Swap(mainstate); 65 print_subinterp(); 66 #ifdef WITH_THREAD 67 PyGILState_Release(gilstate); 68 #endif 69 70 PyEval_RestoreThread(mainstate); 71 Py_Finalize(); 72 } 73 } 74 75 /***************************************************** 76 * Test forcing a particular IO encoding 77 *****************************************************/ 78 79 static void check_stdio_details(const char *encoding, const char * errors) 80 { 81 /* Output info for the test case to check */ 82 if (encoding) { 83 printf("Expected encoding: %s\n", encoding); 84 } else { 85 printf("Expected encoding: default\n"); 86 } 87 if (errors) { 88 printf("Expected errors: %s\n", errors); 89 } else { 90 printf("Expected errors: default\n"); 91 } 92 fflush(stdout); 93 /* Force the given IO encoding */ 94 Py_SetStandardStreamEncoding(encoding, errors); 95 _testembed_Py_Initialize(); 96 PyRun_SimpleString( 97 "import sys;" 98 "print('stdin: {0.encoding}:{0.errors}'.format(sys.stdin));" 99 "print('stdout: {0.encoding}:{0.errors}'.format(sys.stdout));" 100 "print('stderr: {0.encoding}:{0.errors}'.format(sys.stderr));" 101 "sys.stdout.flush()" 102 ); 103 Py_Finalize(); 104 } 105 106 static void test_forced_io_encoding(void) 107 { 108 /* Check various combinations */ 109 printf("--- Use defaults ---\n"); 110 check_stdio_details(NULL, NULL); 111 printf("--- Set errors only ---\n"); 112 check_stdio_details(NULL, "ignore"); 113 printf("--- Set encoding only ---\n"); 114 check_stdio_details("latin-1", NULL); 115 printf("--- Set encoding and errors ---\n"); 116 check_stdio_details("latin-1", "replace"); 117 118 /* Check calling after initialization fails */ 119 Py_Initialize(); 120 121 if (Py_SetStandardStreamEncoding(NULL, NULL) == 0) { 122 printf("Unexpected success calling Py_SetStandardStreamEncoding"); 123 } 124 Py_Finalize(); 125 } 126 127 /* Different embedding tests */ 128 int main(int argc, char *argv[]) 129 { 130 131 /* TODO: Check the argument string to allow for more test cases */ 132 if (argc > 1) { 133 /* For now: assume "forced_io_encoding */ 134 test_forced_io_encoding(); 135 } else { 136 /* Run the original embedding test case by default */ 137 test_repeated_init_and_subinterpreters(); 138 } 139 return 0; 140 } 141