Add three new APIs: PyRun_AnyFileEx(), PyRun_SimpleFileEx(),

PyRun_FileEx().  These are the same as their non-Ex counterparts but
have an extra argument, a flag telling them to close the file when
done.

Then this is used by Py_Main() and execfile() to close the file after
it is parsed but before it is executed.

Adding APIs seems strange given the feature freeze but it's the only
way I see to close the bug report without incompatible changes.

[ Bug #110616 ] source file stays open after parsing is done (PR#209)
This commit is contained in:
Guido van Rossum 2000-08-27 19:21:52 +00:00
parent 2f15b25da2
commit 0df002c45b
4 changed files with 41 additions and 15 deletions

View File

@ -29,9 +29,11 @@ DL_IMPORT(PyThreadState *) Py_NewInterpreter(void);
DL_IMPORT(void) Py_EndInterpreter(PyThreadState *); DL_IMPORT(void) Py_EndInterpreter(PyThreadState *);
DL_IMPORT(int) PyRun_AnyFile(FILE *, char *); DL_IMPORT(int) PyRun_AnyFile(FILE *, char *);
DL_IMPORT(int) PyRun_AnyFileEx(FILE *, char *, int);
DL_IMPORT(int) PyRun_SimpleString(char *); DL_IMPORT(int) PyRun_SimpleString(char *);
DL_IMPORT(int) PyRun_SimpleFile(FILE *, char *); DL_IMPORT(int) PyRun_SimpleFile(FILE *, char *);
DL_IMPORT(int) PyRun_SimpleFileEx(FILE *, char *, int);
DL_IMPORT(int) PyRun_InteractiveOne(FILE *, char *); DL_IMPORT(int) PyRun_InteractiveOne(FILE *, char *);
DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *); DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *);
@ -40,6 +42,8 @@ DL_IMPORT(struct _node *) PyParser_SimpleParseFile(FILE *, char *, int);
DL_IMPORT(PyObject *) PyRun_String(char *, int, PyObject *, PyObject *); DL_IMPORT(PyObject *) PyRun_String(char *, int, PyObject *, PyObject *);
DL_IMPORT(PyObject *) PyRun_File(FILE *, char *, int, PyObject *, PyObject *); DL_IMPORT(PyObject *) PyRun_File(FILE *, char *, int, PyObject *, PyObject *);
DL_IMPORT(PyObject *) PyRun_FileEx(FILE *, char *, int,
PyObject *, PyObject *, int);
DL_IMPORT(PyObject *) Py_CompileString(char *, char *, int); DL_IMPORT(PyObject *) Py_CompileString(char *, char *, int);

View File

@ -268,11 +268,10 @@ Py_Main(int argc, char **argv)
} }
} }
} }
sts = PyRun_AnyFile( sts = PyRun_AnyFileEx(
fp, fp,
filename == NULL ? "<stdin>" : filename) != 0; filename == NULL ? "<stdin>" : filename,
if (filename != NULL) filename != NULL) != 0;
fclose(fp);
} }
if (inspect && stdin_is_interactive && if (inspect && stdin_is_interactive &&

View File

@ -815,10 +815,7 @@ builtin_execfile(PyObject *self, PyObject *args)
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
return NULL; return NULL;
} }
res = PyRun_File(fp, filename, Py_file_input, globals, locals); res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1);
Py_BEGIN_ALLOW_THREADS
fclose(fp);
Py_END_ALLOW_THREADS
return res; return res;
} }

View File

@ -449,13 +449,23 @@ initsite(void)
int int
PyRun_AnyFile(FILE *fp, char *filename) PyRun_AnyFile(FILE *fp, char *filename)
{
return PyRun_AnyFileEx(fp, filename, 0);
}
int
PyRun_AnyFileEx(FILE *fp, char *filename, int closeit)
{ {
if (filename == NULL) if (filename == NULL)
filename = "???"; filename = "???";
if (Py_FdIsInteractive(fp, filename)) if (Py_FdIsInteractive(fp, filename)) {
return PyRun_InteractiveLoop(fp, filename); int err = PyRun_InteractiveLoop(fp, filename);
if (closeit)
fclose(fp);
return err;
}
else else
return PyRun_SimpleFile(fp, filename); return PyRun_SimpleFileEx(fp, filename, closeit);
} }
int int
@ -541,6 +551,12 @@ PyRun_InteractiveOne(FILE *fp, char *filename)
int int
PyRun_SimpleFile(FILE *fp, char *filename) PyRun_SimpleFile(FILE *fp, char *filename)
{
return PyRun_SimpleFileEx(fp, filename, 0);
}
int
PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit)
{ {
PyObject *m, *d, *v; PyObject *m, *d, *v;
char *ext; char *ext;
@ -558,7 +574,8 @@ PyRun_SimpleFile(FILE *fp, char *filename)
#endif /* macintosh */ #endif /* macintosh */
) { ) {
/* Try to run a pyc file. First, re-open in binary */ /* Try to run a pyc file. First, re-open in binary */
/* Don't close, done in main: fclose(fp); */ if (closeit)
fclose(fp);
if( (fp = fopen(filename, "rb")) == NULL ) { if( (fp = fopen(filename, "rb")) == NULL ) {
fprintf(stderr, "python: Can't reopen .pyc file\n"); fprintf(stderr, "python: Can't reopen .pyc file\n");
return -1; return -1;
@ -568,7 +585,7 @@ PyRun_SimpleFile(FILE *fp, char *filename)
Py_OptimizeFlag = 1; Py_OptimizeFlag = 1;
v = run_pyc_file(fp, filename, d, d); v = run_pyc_file(fp, filename, d, d);
} else { } else {
v = PyRun_File(fp, filename, Py_file_input, d, d); v = PyRun_FileEx(fp, filename, Py_file_input, d, d, closeit);
} }
if (v == NULL) { if (v == NULL) {
PyErr_Print(); PyErr_Print();
@ -845,8 +862,17 @@ PyObject *
PyRun_File(FILE *fp, char *filename, int start, PyObject *globals, PyRun_File(FILE *fp, char *filename, int start, PyObject *globals,
PyObject *locals) PyObject *locals)
{ {
return run_err_node(PyParser_SimpleParseFile(fp, filename, start), PyRun_FileEx(fp, filename, start, globals, locals, 0);
filename, globals, locals); }
PyObject *
PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals,
PyObject *locals, int closeit)
{
node *n = PyParser_SimpleParseFile(fp, filename, start);
if (closeit)
fclose(fp);
return run_err_node(n, filename, globals, locals);
} }
static PyObject * static PyObject *