From 95701bdf40a00b3eb38aa4270b512ebac12fd87b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 6 Nov 2013 18:41:07 +0100 Subject: Issue #19512: Add PyRun_InteractiveOneObject() function Only decode the filename once. PyRun_InteractiveOneObject() uses an identifier for "" string, so the byte string is only decoded once. --- Include/pythonrun.h | 4 ++ Python/pythonrun.c | 111 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 86 insertions(+), 29 deletions(-) diff --git a/Include/pythonrun.h b/Include/pythonrun.h index ec0565e..c364947 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -63,6 +63,10 @@ PyAPI_FUNC(int) PyRun_InteractiveOneFlags( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ diff --git a/Python/pythonrun.c b/Python/pythonrun.c index dcd3664..61d0352 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -73,7 +73,7 @@ static int initfsencoding(PyInterpreterState *interp); static void initsite(void); static int initstdio(void); static void flush_io(void); -static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, +static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, PyCompilerFlags *, PyArena *); static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, PyCompilerFlags *); @@ -1265,12 +1265,18 @@ PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, } int -PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) +PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) { - PyObject *v; - int ret; + PyObject *filename, *v; + int ret, err; PyCompilerFlags local_flags; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + if (flags == NULL) { flags = &local_flags; local_flags.cf_flags = 0; @@ -1285,16 +1291,21 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); Py_XDECREF(v); } + err = -1; for (;;) { - ret = PyRun_InteractiveOneFlags(fp, filename, flags); + ret = PyRun_InteractiveOneObject(fp, filename, flags); PRINT_TOTAL_REFS(); - if (ret == E_EOF) - return 0; + if (ret == E_EOF) { + err = 0; + break; + } /* if (ret == E_NOMEM) - return -1; + break; */ } + Py_DECREF(filename); + return err; } /* compute parser flags based on compiler flags */ @@ -1322,14 +1333,21 @@ static int PARSER_FLAGS(PyCompilerFlags *flags) #endif int -PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) +PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) { - PyObject *m, *d, *v, *w, *oenc = NULL; + PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name; mod_ty mod; PyArena *arena; char *ps1 = "", *ps2 = "", *enc = NULL; int errcode = 0; _Py_IDENTIFIER(encoding); + _Py_IDENTIFIER(__main__); + + mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */ + if (mod_name == NULL) { + PyErr_Print(); + return -1; + } if (fp == stdin) { /* Fetch encoding from sys.stdin if possible. */ @@ -1375,9 +1393,9 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags Py_XDECREF(oenc); return -1; } - mod = PyParser_ASTFromFile(fp, filename, enc, - Py_single_input, ps1, ps2, - flags, &errcode, arena); + mod = PyParser_ASTFromFileObject(fp, filename, enc, + Py_single_input, ps1, ps2, + flags, &errcode, arena); Py_XDECREF(v); Py_XDECREF(w); Py_XDECREF(oenc); @@ -1390,7 +1408,7 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags PyErr_Print(); return -1; } - m = PyImport_AddModule("__main__"); + m = PyImport_AddModuleObject(mod_name); if (m == NULL) { PyArena_Free(arena); return -1; @@ -1407,6 +1425,23 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags return 0; } +int +PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) +{ + PyObject *filename; + int res; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + res = PyRun_InteractiveOneObject(fp, filename, flags); + Py_DECREF(filename); + return res; +} + + /* Check whether a file maybe a pyc file: Look at the extension, the file type, and, if we may close it, at the first few bytes. */ @@ -2010,37 +2045,55 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, { PyObject *ret = NULL; mod_ty mod; - PyArena *arena = PyArena_New(); + PyArena *arena; + _Py_static_string(PyId_string, ""); + PyObject *filename; + + filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ + if (filename == NULL) + return NULL; + + arena = PyArena_New(); if (arena == NULL) return NULL; - mod = PyParser_ASTFromString(str, "", start, flags, arena); + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); if (mod != NULL) - ret = run_mod(mod, "", globals, locals, flags, arena); + ret = run_mod(mod, filename, globals, locals, flags, arena); PyArena_Free(arena); return ret; } PyObject * -PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, +PyRun_FileExFlags(FILE *fp, const char *filename_str, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags) { - PyObject *ret; + PyObject *ret = NULL; mod_ty mod; - PyArena *arena = PyArena_New(); + PyArena *arena = NULL; + PyObject *filename; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + goto exit; + + arena = PyArena_New(); if (arena == NULL) - return NULL; + goto exit; - mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0, - flags, NULL, arena); + mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0, + flags, NULL, arena); if (closeit) fclose(fp); if (mod == NULL) { - PyArena_Free(arena); - return NULL; + goto exit; } ret = run_mod(mod, filename, globals, locals, flags, arena); - PyArena_Free(arena); + +exit: + Py_XDECREF(filename); + if (arena != NULL) + PyArena_Free(arena); return ret; } @@ -2075,12 +2128,12 @@ flush_io(void) } static PyObject * -run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, - PyCompilerFlags *flags, PyArena *arena) +run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, + PyCompilerFlags *flags, PyArena *arena) { PyCodeObject *co; PyObject *v; - co = PyAST_Compile(mod, filename, flags, arena); + co = PyAST_CompileObject(mod, filename, flags, -1, arena); if (co == NULL) return NULL; v = PyEval_EvalCode((PyObject*)co, globals, locals); -- cgit v0.12