Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0df002c

Browse files
committed
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)
1 parent 2f15b25 commit 0df002c

4 files changed

Lines changed: 41 additions & 15 deletions

File tree

Include/pythonrun.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ DL_IMPORT(PyThreadState *) Py_NewInterpreter(void);
2929
DL_IMPORT(void) Py_EndInterpreter(PyThreadState *);
3030

3131
DL_IMPORT(int) PyRun_AnyFile(FILE *, char *);
32+
DL_IMPORT(int) PyRun_AnyFileEx(FILE *, char *, int);
3233

3334
DL_IMPORT(int) PyRun_SimpleString(char *);
3435
DL_IMPORT(int) PyRun_SimpleFile(FILE *, char *);
36+
DL_IMPORT(int) PyRun_SimpleFileEx(FILE *, char *, int);
3537
DL_IMPORT(int) PyRun_InteractiveOne(FILE *, char *);
3638
DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *);
3739

@@ -40,6 +42,8 @@ DL_IMPORT(struct _node *) PyParser_SimpleParseFile(FILE *, char *, int);
4042

4143
DL_IMPORT(PyObject *) PyRun_String(char *, int, PyObject *, PyObject *);
4244
DL_IMPORT(PyObject *) PyRun_File(FILE *, char *, int, PyObject *, PyObject *);
45+
DL_IMPORT(PyObject *) PyRun_FileEx(FILE *, char *, int,
46+
PyObject *, PyObject *, int);
4347

4448
DL_IMPORT(PyObject *) Py_CompileString(char *, char *, int);
4549

Modules/main.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,10 @@ Py_Main(int argc, char **argv)
268268
}
269269
}
270270
}
271-
sts = PyRun_AnyFile(
271+
sts = PyRun_AnyFileEx(
272272
fp,
273-
filename == NULL ? "<stdin>" : filename) != 0;
274-
if (filename != NULL)
275-
fclose(fp);
273+
filename == NULL ? "<stdin>" : filename,
274+
filename != NULL) != 0;
276275
}
277276

278277
if (inspect && stdin_is_interactive &&

Python/bltinmodule.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -815,10 +815,7 @@ builtin_execfile(PyObject *self, PyObject *args)
815815
PyErr_SetFromErrno(PyExc_IOError);
816816
return NULL;
817817
}
818-
res = PyRun_File(fp, filename, Py_file_input, globals, locals);
819-
Py_BEGIN_ALLOW_THREADS
820-
fclose(fp);
821-
Py_END_ALLOW_THREADS
818+
res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1);
822819
return res;
823820
}
824821

Python/pythonrun.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,23 @@ initsite(void)
449449

450450
int
451451
PyRun_AnyFile(FILE *fp, char *filename)
452+
{
453+
return PyRun_AnyFileEx(fp, filename, 0);
454+
}
455+
456+
int
457+
PyRun_AnyFileEx(FILE *fp, char *filename, int closeit)
452458
{
453459
if (filename == NULL)
454460
filename = "???";
455-
if (Py_FdIsInteractive(fp, filename))
456-
return PyRun_InteractiveLoop(fp, filename);
461+
if (Py_FdIsInteractive(fp, filename)) {
462+
int err = PyRun_InteractiveLoop(fp, filename);
463+
if (closeit)
464+
fclose(fp);
465+
return err;
466+
}
457467
else
458-
return PyRun_SimpleFile(fp, filename);
468+
return PyRun_SimpleFileEx(fp, filename, closeit);
459469
}
460470

461471
int
@@ -541,6 +551,12 @@ PyRun_InteractiveOne(FILE *fp, char *filename)
541551

542552
int
543553
PyRun_SimpleFile(FILE *fp, char *filename)
554+
{
555+
return PyRun_SimpleFileEx(fp, filename, 0);
556+
}
557+
558+
int
559+
PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit)
544560
{
545561
PyObject *m, *d, *v;
546562
char *ext;
@@ -558,7 +574,8 @@ PyRun_SimpleFile(FILE *fp, char *filename)
558574
#endif /* macintosh */
559575
) {
560576
/* Try to run a pyc file. First, re-open in binary */
561-
/* Don't close, done in main: fclose(fp); */
577+
if (closeit)
578+
fclose(fp);
562579
if( (fp = fopen(filename, "rb")) == NULL ) {
563580
fprintf(stderr, "python: Can't reopen .pyc file\n");
564581
return -1;
@@ -568,7 +585,7 @@ PyRun_SimpleFile(FILE *fp, char *filename)
568585
Py_OptimizeFlag = 1;
569586
v = run_pyc_file(fp, filename, d, d);
570587
} else {
571-
v = PyRun_File(fp, filename, Py_file_input, d, d);
588+
v = PyRun_FileEx(fp, filename, Py_file_input, d, d, closeit);
572589
}
573590
if (v == NULL) {
574591
PyErr_Print();
@@ -845,8 +862,17 @@ PyObject *
845862
PyRun_File(FILE *fp, char *filename, int start, PyObject *globals,
846863
PyObject *locals)
847864
{
848-
return run_err_node(PyParser_SimpleParseFile(fp, filename, start),
849-
filename, globals, locals);
865+
PyRun_FileEx(fp, filename, start, globals, locals, 0);
866+
}
867+
868+
PyObject *
869+
PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals,
870+
PyObject *locals, int closeit)
871+
{
872+
node *n = PyParser_SimpleParseFile(fp, filename, start);
873+
if (closeit)
874+
fclose(fp);
875+
return run_err_node(n, filename, globals, locals);
850876
}
851877

852878
static PyObject *

0 commit comments

Comments
 (0)