1 #define PYTESTCAPI_NEED_INTERNAL_API
2 #include "parts.h"
3 #include "util.h"
4 #include "pycore_fileutils.h" // _Py_IsValidFD()
5
6 #include <stdio.h>
7 #include <errno.h>
8
9
10 static PyObject *
run_stringflags(PyObject * mod,PyObject * pos_args)11 run_stringflags(PyObject *mod, PyObject *pos_args)
12 {
13 const char *str;
14 Py_ssize_t size;
15 int start;
16 PyObject *globals = NULL;
17 PyObject *locals = NULL;
18 PyCompilerFlags flags = _PyCompilerFlags_INIT;
19 PyCompilerFlags *pflags = NULL;
20 int cf_flags = 0;
21 int cf_feature_version = 0;
22
23 if (!PyArg_ParseTuple(pos_args, "z#iO|Oii",
24 &str, &size, &start, &globals, &locals,
25 &cf_flags, &cf_feature_version)) {
26 return NULL;
27 }
28
29 NULLABLE(globals);
30 NULLABLE(locals);
31 if (cf_flags || cf_feature_version) {
32 flags.cf_flags = cf_flags;
33 flags.cf_feature_version = cf_feature_version;
34 pflags = &flags;
35 }
36
37 return PyRun_StringFlags(str, start, globals, locals, pflags);
38 }
39
40 static PyObject *
run_fileexflags(PyObject * mod,PyObject * pos_args)41 run_fileexflags(PyObject *mod, PyObject *pos_args)
42 {
43 PyObject *result = NULL;
44 const char *filename = NULL;
45 Py_ssize_t filename_size;
46 int start;
47 PyObject *globals = NULL;
48 PyObject *locals = NULL;
49 int closeit = 0;
50 PyCompilerFlags flags = _PyCompilerFlags_INIT;
51 PyCompilerFlags *pflags = NULL;
52 int cf_flags = 0;
53 int cf_feature_version = 0;
54
55 FILE *fp = NULL;
56
57 if (!PyArg_ParseTuple(pos_args, "z#iO|Oiii",
58 &filename, &filename_size, &start, &globals, &locals,
59 &closeit, &cf_flags, &cf_feature_version)) {
60 return NULL;
61 }
62
63 NULLABLE(globals);
64 NULLABLE(locals);
65 if (cf_flags || cf_feature_version) {
66 flags.cf_flags = cf_flags;
67 flags.cf_feature_version = cf_feature_version;
68 pflags = &flags;
69 }
70
71 fp = fopen(filename, "r");
72 if (fp == NULL) {
73 PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
74 return NULL;
75 }
76 int fd = fileno(fp);
77
78 result = PyRun_FileExFlags(fp, filename, start, globals, locals, closeit, pflags);
79
80 if (closeit && result && _Py_IsValidFD(fd)) {
81 PyErr_SetString(PyExc_AssertionError, "File was not closed after excution");
82 Py_DECREF(result);
83 fclose(fp);
84 return NULL;
85 }
86
87 if (!closeit && !_Py_IsValidFD(fd)) {
88 PyErr_SetString(PyExc_AssertionError, "Bad file descriptor after excution");
89 Py_XDECREF(result);
90 return NULL;
91 }
92
93 if (!closeit) {
94 fclose(fp); /* don't need open file any more*/
95 }
96
97 return result;
98 }
99
100 static PyMethodDef test_methods[] = {
101 {"run_stringflags", run_stringflags, METH_VARARGS},
102 {"run_fileexflags", run_fileexflags, METH_VARARGS},
103 {NULL},
104 };
105
106 int
_PyTestCapi_Init_Run(PyObject * mod)107 _PyTestCapi_Init_Run(PyObject *mod)
108 {
109 if (PyModule_AddFunctions(mod, test_methods) < 0) {
110 return -1;
111 }
112 return 0;
113 }
114