[Python-checkins] cpython: Issue #19512: Add PyRun_InteractiveOneObject() function

victor.stinner python-checkins at python.org
Wed Nov 6 18:45:54 CET 2013


http://hg.python.org/cpython/rev/af822a6c9faf
changeset:   86966:af822a6c9faf
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Wed Nov 06 18:41:07 2013 +0100
summary:
  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.

files:
  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
--- a/Include/pythonrun.h
+++ b/Include/pythonrun.h
@@ -63,6 +63,10 @@
     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
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -73,7 +73,7 @@
 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 @@
 }
 
 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 @@
         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 @@
 #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 @@
         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 @@
         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 @@
     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 @@
 {
     PyObject *ret = NULL;
     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)
         return NULL;
 
-    mod = PyParser_ASTFromString(str, "<string>", start, flags, arena);
+    mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
     if (mod != NULL)
-        ret = run_mod(mod, "<string>", 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 @@
 }
 
 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);

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list