Kaydet (Commit) 95701bdf authored tarafından Victor Stinner's avatar Victor Stinner

Issue #19512: Add PyRun_InteractiveOneObject() function

Only decode the filename once. PyRun_InteractiveOneObject() uses an identifier
for "<string>" string, so the byte string is only decoded once.
üst 4ee41c58
...@@ -63,6 +63,10 @@ PyAPI_FUNC(int) PyRun_InteractiveOneFlags( ...@@ -63,6 +63,10 @@ PyAPI_FUNC(int) PyRun_InteractiveOneFlags(
FILE *fp, FILE *fp,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
PyCompilerFlags *flags); PyCompilerFlags *flags);
PyAPI_FUNC(int) PyRun_InteractiveOneObject(
FILE *fp,
PyObject *filename,
PyCompilerFlags *flags);
PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(
FILE *fp, FILE *fp,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
......
...@@ -73,7 +73,7 @@ static int initfsencoding(PyInterpreterState *interp); ...@@ -73,7 +73,7 @@ static int initfsencoding(PyInterpreterState *interp);
static void initsite(void); static void initsite(void);
static int initstdio(void); static int initstdio(void);
static void flush_io(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 *); PyCompilerFlags *, PyArena *);
static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
PyCompilerFlags *); PyCompilerFlags *);
...@@ -1265,12 +1265,18 @@ PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, ...@@ -1265,12 +1265,18 @@ PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
} }
int int
PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
{ {
PyObject *v; PyObject *filename, *v;
int ret; int ret, err;
PyCompilerFlags local_flags; PyCompilerFlags local_flags;
filename = PyUnicode_DecodeFSDefault(filename_str);
if (filename == NULL) {
PyErr_Print();
return -1;
}
if (flags == NULL) { if (flags == NULL) {
flags = &local_flags; flags = &local_flags;
local_flags.cf_flags = 0; local_flags.cf_flags = 0;
...@@ -1285,16 +1291,21 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag ...@@ -1285,16 +1291,21 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag
PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); PySys_SetObject("ps2", v = PyUnicode_FromString("... "));
Py_XDECREF(v); Py_XDECREF(v);
} }
err = -1;
for (;;) { for (;;) {
ret = PyRun_InteractiveOneFlags(fp, filename, flags); ret = PyRun_InteractiveOneObject(fp, filename, flags);
PRINT_TOTAL_REFS(); PRINT_TOTAL_REFS();
if (ret == E_EOF) if (ret == E_EOF) {
return 0; err = 0;
break;
}
/* /*
if (ret == E_NOMEM) if (ret == E_NOMEM)
return -1; break;
*/ */
} }
Py_DECREF(filename);
return err;
} }
/* compute parser flags based on compiler flags */ /* compute parser flags based on compiler flags */
...@@ -1322,14 +1333,21 @@ static int PARSER_FLAGS(PyCompilerFlags *flags) ...@@ -1322,14 +1333,21 @@ static int PARSER_FLAGS(PyCompilerFlags *flags)
#endif #endif
int 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; mod_ty mod;
PyArena *arena; PyArena *arena;
char *ps1 = "", *ps2 = "", *enc = NULL; char *ps1 = "", *ps2 = "", *enc = NULL;
int errcode = 0; int errcode = 0;
_Py_IDENTIFIER(encoding); _Py_IDENTIFIER(encoding);
_Py_IDENTIFIER(__main__);
mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */
if (mod_name == NULL) {
PyErr_Print();
return -1;
}
if (fp == stdin) { if (fp == stdin) {
/* Fetch encoding from sys.stdin if possible. */ /* Fetch encoding from sys.stdin if possible. */
...@@ -1375,9 +1393,9 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags ...@@ -1375,9 +1393,9 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags
Py_XDECREF(oenc); Py_XDECREF(oenc);
return -1; return -1;
} }
mod = PyParser_ASTFromFile(fp, filename, enc, mod = PyParser_ASTFromFileObject(fp, filename, enc,
Py_single_input, ps1, ps2, Py_single_input, ps1, ps2,
flags, &errcode, arena); flags, &errcode, arena);
Py_XDECREF(v); Py_XDECREF(v);
Py_XDECREF(w); Py_XDECREF(w);
Py_XDECREF(oenc); Py_XDECREF(oenc);
...@@ -1390,7 +1408,7 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags ...@@ -1390,7 +1408,7 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags
PyErr_Print(); PyErr_Print();
return -1; return -1;
} }
m = PyImport_AddModule("__main__"); m = PyImport_AddModuleObject(mod_name);
if (m == NULL) { if (m == NULL) {
PyArena_Free(arena); PyArena_Free(arena);
return -1; return -1;
...@@ -1407,6 +1425,23 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags ...@@ -1407,6 +1425,23 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags
return 0; 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, /* 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. */ 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, ...@@ -2010,37 +2045,55 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals,
{ {
PyObject *ret = NULL; PyObject *ret = NULL;
mod_ty mod; mod_ty mod;
PyArena *arena = PyArena_New(); PyArena *arena;
_Py_static_string(PyId_string, "<string>");
PyObject *filename;
filename = _PyUnicode_FromId(&PyId_string); /* borrowed */
if (filename == NULL)
return NULL;
arena = PyArena_New();
if (arena == NULL) if (arena == NULL)
return NULL; return NULL;
mod = PyParser_ASTFromString(str, "<string>", start, flags, arena); mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
if (mod != NULL) if (mod != NULL)
ret = run_mod(mod, "<string>", globals, locals, flags, arena); ret = run_mod(mod, filename, globals, locals, flags, arena);
PyArena_Free(arena); PyArena_Free(arena);
return ret; return ret;
} }
PyObject * 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 *locals, int closeit, PyCompilerFlags *flags)
{ {
PyObject *ret; PyObject *ret = NULL;
mod_ty mod; 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) if (arena == NULL)
return NULL; goto exit;
mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0, mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0,
flags, NULL, arena); flags, NULL, arena);
if (closeit) if (closeit)
fclose(fp); fclose(fp);
if (mod == NULL) { if (mod == NULL) {
PyArena_Free(arena); goto exit;
return NULL;
} }
ret = run_mod(mod, filename, globals, locals, flags, arena); ret = run_mod(mod, filename, globals, locals, flags, arena);
PyArena_Free(arena);
exit:
Py_XDECREF(filename);
if (arena != NULL)
PyArena_Free(arena);
return ret; return ret;
} }
...@@ -2075,12 +2128,12 @@ flush_io(void) ...@@ -2075,12 +2128,12 @@ flush_io(void)
} }
static PyObject * static PyObject *
run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
PyCompilerFlags *flags, PyArena *arena) PyCompilerFlags *flags, PyArena *arena)
{ {
PyCodeObject *co; PyCodeObject *co;
PyObject *v; PyObject *v;
co = PyAST_Compile(mod, filename, flags, arena); co = PyAST_CompileObject(mod, filename, flags, -1, arena);
if (co == NULL) if (co == NULL)
return NULL; return NULL;
v = PyEval_EvalCode((PyObject*)co, globals, locals); v = PyEval_EvalCode((PyObject*)co, globals, locals);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment