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
_testembed_Py_Initialize(void)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
print_subinterp(void)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
test_repeated_init_and_subinterpreters(void)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
check_stdio_details(const char * encoding,const char * errors)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
test_forced_io_encoding(void)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 */
main(int argc,char * argv[])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