ยปCore Development>Code coverage>Programs/_testembed.c

Python code coverage for Programs/_testembed.c

#countcontent
1n/a#include <Python.h>
2n/a#include <stdio.h>
3n/a
4n/a/*********************************************************
5n/a * Embedded interpreter tests that need a custom exe
6n/a *
7n/a * Executed via 'EmbeddingTests' in Lib/test/test_capi.py
8n/a *********************************************************/
9n/a
10n/astatic void _testembed_Py_Initialize(void)
11n/a{
12n/a /* HACK: the "./" at front avoids a search along the PATH in
13n/a Modules/getpath.c */
14n/a Py_SetProgramName(L"./_testembed");
15n/a Py_Initialize();
16n/a}
17n/a
18n/a
19n/a/*****************************************************
20n/a * Test repeated initialisation and subinterpreters
21n/a *****************************************************/
22n/a
23n/astatic void print_subinterp(void)
24n/a{
25n/a /* Just output some debug stuff */
26n/a PyThreadState *ts = PyThreadState_Get();
27n/a printf("interp %p, thread state %p: ", ts->interp, ts);
28n/a fflush(stdout);
29n/a PyRun_SimpleString(
30n/a "import sys;"
31n/a "print('id(modules) =', id(sys.modules));"
32n/a "sys.stdout.flush()"
33n/a );
34n/a}
35n/a
36n/astatic int test_repeated_init_and_subinterpreters(void)
37n/a{
38n/a PyThreadState *mainstate, *substate;
39n/a#ifdef WITH_THREAD
40n/a PyGILState_STATE gilstate;
41n/a#endif
42n/a int i, j;
43n/a
44n/a for (i=0; i<15; i++) {
45n/a printf("--- Pass %d ---\n", i);
46n/a _testembed_Py_Initialize();
47n/a mainstate = PyThreadState_Get();
48n/a
49n/a#ifdef WITH_THREAD
50n/a PyEval_InitThreads();
51n/a PyEval_ReleaseThread(mainstate);
52n/a
53n/a gilstate = PyGILState_Ensure();
54n/a#endif
55n/a print_subinterp();
56n/a PyThreadState_Swap(NULL);
57n/a
58n/a for (j=0; j<3; j++) {
59n/a substate = Py_NewInterpreter();
60n/a print_subinterp();
61n/a Py_EndInterpreter(substate);
62n/a }
63n/a
64n/a PyThreadState_Swap(mainstate);
65n/a print_subinterp();
66n/a#ifdef WITH_THREAD
67n/a PyGILState_Release(gilstate);
68n/a#endif
69n/a
70n/a PyEval_RestoreThread(mainstate);
71n/a Py_Finalize();
72n/a }
73n/a return 0;
74n/a}
75n/a
76n/a/*****************************************************
77n/a * Test forcing a particular IO encoding
78n/a *****************************************************/
79n/a
80n/astatic void check_stdio_details(const char *encoding, const char * errors)
81n/a{
82n/a /* Output info for the test case to check */
83n/a if (encoding) {
84n/a printf("Expected encoding: %s\n", encoding);
85n/a } else {
86n/a printf("Expected encoding: default\n");
87n/a }
88n/a if (errors) {
89n/a printf("Expected errors: %s\n", errors);
90n/a } else {
91n/a printf("Expected errors: default\n");
92n/a }
93n/a fflush(stdout);
94n/a /* Force the given IO encoding */
95n/a Py_SetStandardStreamEncoding(encoding, errors);
96n/a _testembed_Py_Initialize();
97n/a PyRun_SimpleString(
98n/a "import sys;"
99n/a "print('stdin: {0.encoding}:{0.errors}'.format(sys.stdin));"
100n/a "print('stdout: {0.encoding}:{0.errors}'.format(sys.stdout));"
101n/a "print('stderr: {0.encoding}:{0.errors}'.format(sys.stderr));"
102n/a "sys.stdout.flush()"
103n/a );
104n/a Py_Finalize();
105n/a}
106n/a
107n/astatic int test_forced_io_encoding(void)
108n/a{
109n/a /* Check various combinations */
110n/a printf("--- Use defaults ---\n");
111n/a check_stdio_details(NULL, NULL);
112n/a printf("--- Set errors only ---\n");
113n/a check_stdio_details(NULL, "ignore");
114n/a printf("--- Set encoding only ---\n");
115n/a check_stdio_details("latin-1", NULL);
116n/a printf("--- Set encoding and errors ---\n");
117n/a check_stdio_details("latin-1", "replace");
118n/a
119n/a /* Check calling after initialization fails */
120n/a Py_Initialize();
121n/a
122n/a if (Py_SetStandardStreamEncoding(NULL, NULL) == 0) {
123n/a printf("Unexpected success calling Py_SetStandardStreamEncoding");
124n/a }
125n/a Py_Finalize();
126n/a return 0;
127n/a}
128n/a
129n/a/* *********************************************************
130n/a * List of test cases and the function that implements it.
131n/a *
132n/a * Names are compared case-sensitively with the first
133n/a * argument. If no match is found, or no first argument was
134n/a * provided, the names of all test cases are printed and
135n/a * the exit code will be -1.
136n/a *
137n/a * The int returned from test functions is used as the exit
138n/a * code, and test_capi treats all non-zero exit codes as a
139n/a * failed test.
140n/a *********************************************************/
141n/astruct TestCase
142n/a{
143n/a const char *name;
144n/a int (*func)(void);
145n/a};
146n/a
147n/astatic struct TestCase TestCases[] = {
148n/a { "forced_io_encoding", test_forced_io_encoding },
149n/a { "repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters },
150n/a { NULL, NULL }
151n/a};
152n/a
153n/aint main(int argc, char *argv[])
154n/a{
155n/a if (argc > 1) {
156n/a for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
157n/a if (strcmp(argv[1], tc->name) == 0)
158n/a return (*tc->func)();
159n/a }
160n/a }
161n/a
162n/a /* No match found, or no test name provided, so display usage */
163n/a printf("Python " PY_VERSION " _testembed executable for embedded interpreter tests\n"
164n/a "Normally executed via 'EmbeddingTests' in Lib/test/test_capi.py\n\n"
165n/a "Usage: %s TESTNAME\n\nAll available tests:\n", argv[0]);
166n/a for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
167n/a printf(" %s\n", tc->name);
168n/a }
169n/a
170n/a /* Non-zero exit code will cause test_capi.py tests to fail.
171n/a This is intentional. */
172n/a return -1;
173n/a}