| #define PYTESTCAPI_NEED_INTERNAL_API | |
| #include "parts.h" | |
| #include "util.h" | |
| #include "pycore_fileutils.h" // _Py_IsValidFD() | |
| #include <stdio.h> | |
| #include <errno.h> | |
| static PyObject * | |
| run_stringflags(PyObject *mod, PyObject *pos_args) | |
| { | |
| const char *str; | |
| Py_ssize_t size; | |
| int start; | |
| PyObject *globals = NULL; | |
| PyObject *locals = NULL; | |
| PyCompilerFlags flags = _PyCompilerFlags_INIT; | |
| PyCompilerFlags *pflags = NULL; | |
| int cf_flags = 0; | |
| int cf_feature_version = 0; | |
| if (!PyArg_ParseTuple(pos_args, "z#iO|Oii", | |
| &str, &size, &start, &globals, &locals, | |
| &cf_flags, &cf_feature_version)) { | |
| return NULL; | |
| } | |
| NULLABLE(globals); | |
| NULLABLE(locals); | |
| if (cf_flags || cf_feature_version) { | |
| flags.cf_flags = cf_flags; | |
| flags.cf_feature_version = cf_feature_version; | |
| pflags = &flags; | |
| } | |
| return PyRun_StringFlags(str, start, globals, locals, pflags); | |
| } | |
| static PyObject * | |
| run_fileexflags(PyObject *mod, PyObject *pos_args) | |
| { | |
| PyObject *result = NULL; | |
| const char *filename = NULL; | |
| Py_ssize_t filename_size; | |
| int start; | |
| PyObject *globals = NULL; | |
| PyObject *locals = NULL; | |
| int closeit = 0; | |
| PyCompilerFlags flags = _PyCompilerFlags_INIT; | |
| PyCompilerFlags *pflags = NULL; | |
| int cf_flags = 0; | |
| int cf_feature_version = 0; | |
| FILE *fp = NULL; | |
| if (!PyArg_ParseTuple(pos_args, "z#iO|Oiii", | |
| &filename, &filename_size, &start, &globals, &locals, | |
| &closeit, &cf_flags, &cf_feature_version)) { | |
| return NULL; | |
| } | |
| NULLABLE(globals); | |
| NULLABLE(locals); | |
| if (cf_flags || cf_feature_version) { | |
| flags.cf_flags = cf_flags; | |
| flags.cf_feature_version = cf_feature_version; | |
| pflags = &flags; | |
| } | |
| fp = fopen(filename, "r"); | |
| if (fp == NULL) { | |
| PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); | |
| return NULL; | |
| } | |
| int fd = fileno(fp); | |
| result = PyRun_FileExFlags(fp, filename, start, globals, locals, closeit, pflags); | |
| if (closeit && result && _Py_IsValidFD(fd)) { | |
| PyErr_SetString(PyExc_AssertionError, "File was not closed after excution"); | |
| Py_DECREF(result); | |
| fclose(fp); | |
| return NULL; | |
| } | |
| if (!closeit && !_Py_IsValidFD(fd)) { | |
| PyErr_SetString(PyExc_AssertionError, "Bad file descriptor after excution"); | |
| Py_XDECREF(result); | |
| return NULL; | |
| } | |
| if (!closeit) { | |
| fclose(fp); /* don't need open file any more*/ | |
| } | |
| return result; | |
| } | |
| static PyMethodDef test_methods[] = { | |
| {"run_stringflags", run_stringflags, METH_VARARGS}, | |
| {"run_fileexflags", run_fileexflags, METH_VARARGS}, | |
| {NULL}, | |
| }; | |
| int | |
| _PyTestCapi_Init_Run(PyObject *mod) | |
| { | |
| if (PyModule_AddFunctions(mod, test_methods) < 0) { | |
| return -1; | |
| } | |
| return 0; | |
| } |