mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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 execution");
 | |
|         Py_DECREF(result);
 | |
|         fclose(fp);
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     if (!closeit && !_Py_IsValidFD(fd)) {
 | |
|         PyErr_SetString(PyExc_AssertionError, "Bad file descriptor after execution");
 | |
|         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;
 | |
| }
 | 
