]> granicus.if.org Git - python/commitdiff
Extend support for from __future__ import nested_scopes
authorJeremy Hylton <jeremy@alum.mit.edu>
Thu, 22 Mar 2001 02:47:58 +0000 (02:47 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Thu, 22 Mar 2001 02:47:58 +0000 (02:47 +0000)
If a module has a future statement enabling nested scopes, they are
also enable for the exec statement and the functions compile() and
execfile() if they occur in the module.

If Python is run with the -i option, which enters interactive mode
after executing a script, and the script it runs enables nested
scopes, they are also enabled in interactive mode.

XXX The use of -i with -c "from __future__ import nested_scopes" is
not supported.  What's the point?

To support these changes, many function variants have been added to
pythonrun.c.  All the variants names end with Flags and they take an
extra PyCompilerFlags * argument.  It is possible that this complexity
will be eliminated in a future version of the interpreter in which
nested scopes are not optional.

Include/pythonrun.h
Modules/main.c
Python/bltinmodule.c
Python/ceval.c
Python/pythonrun.c

index 3f9f70b947b417a89e9a261a23100b4718599c48..c2aa2073c738174c353cec4f05f6c3db7478de5d 100644 (file)
@@ -26,12 +26,17 @@ DL_IMPORT(void) Py_EndInterpreter(PyThreadState *);
 DL_IMPORT(int) PyRun_AnyFile(FILE *, char *);
 DL_IMPORT(int) PyRun_AnyFileEx(FILE *, char *, int);
 
+DL_IMPORT(int) PyRun_AnyFileFlags(FILE *, char *, PyCompilerFlags *);
+DL_IMPORT(int) PyRun_AnyFileExFlags(FILE *, char *, int, PyCompilerFlags *);
+
 DL_IMPORT(int) PyRun_SimpleString(char *);
 DL_IMPORT(int) PyRun_SimpleFile(FILE *, char *);
 DL_IMPORT(int) PyRun_SimpleFileEx(FILE *, char *, int);
+DL_IMPORT(int) PyRun_SimpleFileExFlags(FILE *, char *, int, PyCompilerFlags *);
 DL_IMPORT(int) PyRun_InteractiveOne(FILE *, char *);
 DL_IMPORT(int) PyRun_InteractiveOneFlags(FILE *, char *, PyCompilerFlags *);
 DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *);
+DL_IMPORT(int) PyRun_InteractiveLoopFlags(FILE *, char *, PyCompilerFlags *);
 
 DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int);
 DL_IMPORT(struct _node *) PyParser_SimpleParseFile(FILE *, char *, int);
@@ -40,8 +45,16 @@ DL_IMPORT(PyObject *) PyRun_String(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 *) PyRun_StringFlags(char *, int, PyObject *, PyObject *,
+                                       PyCompilerFlags *);
+DL_IMPORT(PyObject *) PyRun_FileFlags(FILE *, char *, int, PyObject *, 
+                                     PyObject *, PyCompilerFlags *);
+DL_IMPORT(PyObject *) PyRun_FileExFlags(FILE *, char *, int, PyObject *, 
+                                       PyObject *, int, PyCompilerFlags *);
 
 DL_IMPORT(PyObject *) Py_CompileString(char *, char *, int);
+DL_IMPORT(PyObject *) Py_CompileStringFlags(char *, char *, int,
+                                           PyCompilerFlags *);
 DL_IMPORT(struct symtable *) Py_SymtableString(char *, char *, int);
 
 DL_IMPORT(void) PyErr_Print(void);
index 03dff1888f6b790c3777b7c2db834a3dc6201da6..b4566c94af69ecb0dcdef086d1d0bb7bc77c9313 100644 (file)
@@ -99,6 +99,7 @@ Py_Main(int argc, char **argv)
        int stdin_is_interactive = 0;
        int help = 0;
        int version = 0;
+       PyCompilerFlags cf;
 
        orig_argc = argc;       /* For Py_GetArgcArgv() */
        orig_argv = argv;
@@ -293,6 +294,8 @@ Py_Main(int argc, char **argv)
                        Py_DECREF(v);
        }
 
+       cf.cf_nested_scopes = 0;
+
        if (command) {
                sts = PyRun_SimpleString(command) != 0;
                free(command);
@@ -309,15 +312,17 @@ Py_Main(int argc, char **argv)
                                }
                        }
                }
-               sts = PyRun_AnyFileEx(
+               /* XXX */
+               sts = PyRun_AnyFileExFlags(
                        fp,
                        filename == NULL ? "<stdin>" : filename,
-                       filename != NULL) != 0;
+                       filename != NULL, &cf) != 0;
        }
 
        if (inspect && stdin_is_interactive &&
            (filename != NULL || command != NULL))
-               sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
+               /* XXX */
+               sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
 
        Py_Finalize();
 #ifdef RISCOS
index ec680d1d2f281b6e8b7817fba6cc7555c2b3ad7a..9a09c8c4367c1c37652d083b06e5f1986aafa4a0 100644 (file)
@@ -373,7 +373,12 @@ builtin_compile(PyObject *self, PyObject *args)
                   "compile() arg 3 must be 'exec' or 'eval' or 'single'");
                return NULL;
        }
-       return Py_CompileString(str, filename, start);
+       if (PyEval_GetNestedScopes()) {
+               PyCompilerFlags cf;
+               cf.cf_nested_scopes = 1;
+               return Py_CompileStringFlags(str, filename, start, &cf);
+       } else
+               return Py_CompileString(str, filename, start);
 }
 
 static char compile_doc[] =
@@ -808,7 +813,14 @@ builtin_execfile(PyObject *self, PyObject *args)
                PyErr_SetFromErrno(PyExc_IOError);
                return NULL;
        }
-       res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1);
+       if (PyEval_GetNestedScopes()) {
+               PyCompilerFlags cf;
+               cf.cf_nested_scopes = 1;
+               res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, 
+                                  locals, 1, &cf);
+       } else 
+               res = PyRun_FileEx(fp, filename, Py_file_input, globals, 
+                                  locals, 1);
        return res;
 }
 
index 658ccb2a0e2ca09aaacc9adc59913cb3a632ca36..09055723474987c126e0a524b189f1ab426daea7 100644 (file)
@@ -3456,13 +3456,27 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
        else if (PyFile_Check(prog)) {
                FILE *fp = PyFile_AsFile(prog);
                char *name = PyString_AsString(PyFile_Name(prog));
-               v = PyRun_File(fp, name, Py_file_input, globals, locals); 
+               if (PyEval_GetNestedScopes()) {
+                       PyCompilerFlags cf;
+                       cf.cf_nested_scopes = 1;
+                       v = PyRun_FileFlags(fp, name, Py_file_input, globals,
+                                           locals, &cf); 
+               } else {
+                       v = PyRun_File(fp, name, Py_file_input, globals,
+                                      locals); 
+               }
        }
        else {
                char *str;
                if (PyString_AsStringAndSize(prog, &str, NULL))
                        return -1;
-               v = PyRun_String(str, Py_file_input, globals, locals);
+               if (PyEval_GetNestedScopes()) {
+                       PyCompilerFlags cf;
+                       cf.cf_nested_scopes = 1;
+                       v = PyRun_StringFlags(str, Py_file_input, globals, 
+                                             locals, &cf);
+               } else
+                       v = PyRun_String(str, Py_file_input, globals, locals);
        }
        if (plain)
                PyFrame_LocalsToFast(f, 0);
index f7c282089d0d5361a5ff33f06da62f17a2876f82..edb8a1102aa09f6ddbcbf0de3320eb4244f642cf 100644 (file)
@@ -40,7 +40,8 @@ static PyObject *run_err_node(node *, char *, PyObject *, PyObject *,
                              PyCompilerFlags *);
 static PyObject *run_node(node *, char *, PyObject *, PyObject *,
                          PyCompilerFlags *);
-static PyObject *run_pyc_file(FILE *, char *, PyObject *, PyObject *);
+static PyObject *run_pyc_file(FILE *, char *, PyObject *, PyObject *,
+                             PyCompilerFlags *);
 static void err_input(perrdetail *);
 static void initsigs(void);
 static void call_sys_exitfunc(void);
@@ -447,32 +448,54 @@ initsite(void)
 int
 PyRun_AnyFile(FILE *fp, char *filename)
 {
-       return PyRun_AnyFileEx(fp, filename, 0);
+       return PyRun_AnyFileExFlags(fp, filename, 0, NULL);
+}
+
+int
+PyRun_AnyFileFlags(FILE *fp, char *filename, PyCompilerFlags *flags)
+{
+       return PyRun_AnyFileExFlags(fp, filename, 0, flags);
 }
 
 int
 PyRun_AnyFileEx(FILE *fp, char *filename, int closeit)
+{
+       return PyRun_AnyFileExFlags(fp, filename, closeit, NULL);
+}
+
+int
+PyRun_AnyFileExFlags(FILE *fp, char *filename, int closeit, 
+                    PyCompilerFlags *flags)
 {
        if (filename == NULL)
                filename = "???";
        if (Py_FdIsInteractive(fp, filename)) {
-               int err = PyRun_InteractiveLoop(fp, filename);
+               int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
                if (closeit)
                        fclose(fp);
                return err;
        }
        else
-               return PyRun_SimpleFileEx(fp, filename, closeit);
+               return PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
 }
 
 int
 PyRun_InteractiveLoop(FILE *fp, char *filename)
+{
+       return PyRun_InteractiveLoopFlags(fp, filename, NULL);
+}
+
+int
+PyRun_InteractiveLoopFlags(FILE *fp, char *filename, PyCompilerFlags *flags)
 {
        PyObject *v;
        int ret;
-       PyCompilerFlags flags;
+       PyCompilerFlags local_flags;
 
-       flags.cf_nested_scopes = 0;
+       if (flags == NULL) {
+               flags = &local_flags;
+               local_flags.cf_nested_scopes = 0;
+       }
        v = PySys_GetObject("ps1");
        if (v == NULL) {
                PySys_SetObject("ps1", v = PyString_FromString(">>> "));
@@ -484,7 +507,7 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
                Py_XDECREF(v);
        }
        for (;;) {
-               ret = PyRun_InteractiveOneFlags(fp, filename, &flags);
+               ret = PyRun_InteractiveOneFlags(fp, filename, flags);
 #ifdef Py_REF_DEBUG
                fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
 #endif
@@ -610,6 +633,13 @@ maybe_pyc_file(FILE *fp, char* filename, char* ext, int closeit)
 
 int
 PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit)
+{
+       return PyRun_SimpleFileExFlags(fp, filename, closeit, NULL);
+}
+
+int
+PyRun_SimpleFileExFlags(FILE *fp, char *filename, int closeit,
+                       PyCompilerFlags *flags)
 {
        PyObject *m, *d, *v;
        char *ext;
@@ -630,9 +660,10 @@ PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit)
                /* Turn on optimization if a .pyo file is given */
                if (strcmp(ext, ".pyo") == 0)
                        Py_OptimizeFlag = 1;
-               v = run_pyc_file(fp, filename, d, d);
+               v = run_pyc_file(fp, filename, d, d, flags);
        } else {
-               v = PyRun_FileEx(fp, filename, Py_file_input, d, d, closeit);
+               v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d, 
+                                     closeit, flags);
        }
        if (v == NULL) {
                PyErr_Print();
@@ -926,7 +957,7 @@ PyRun_File(FILE *fp, char *filename, int start, PyObject *globals,
 
 PyObject *
 PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals,
-          PyObject *locals, int closeit)
+            PyObject *locals, int closeit)
 {
        node *n = PyParser_SimpleParseFile(fp, filename, start);
        if (closeit)
@@ -934,6 +965,32 @@ PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals,
        return run_err_node(n, filename, globals, locals, NULL);
 }
 
+PyObject *
+PyRun_StringFlags(char *str, int start, PyObject *globals, PyObject *locals,
+                 PyCompilerFlags *flags)
+{
+       return run_err_node(PyParser_SimpleParseString(str, start),
+                           "<string>", globals, locals, flags);
+}
+
+PyObject *
+PyRun_FileFlags(FILE *fp, char *filename, int start, PyObject *globals,
+               PyObject *locals, PyCompilerFlags *flags)
+{
+       return PyRun_FileExFlags(fp, filename, start, globals, locals, 0,
+                                flags); 
+}
+
+PyObject *
+PyRun_FileExFlags(FILE *fp, char *filename, int start, PyObject *globals,
+                 PyObject *locals, int closeit, PyCompilerFlags *flags)
+{
+       node *n = PyParser_SimpleParseFile(fp, filename, start);
+       if (closeit)
+               fclose(fp);
+       return run_err_node(n, filename, globals, locals, flags);
+}
+
 static PyObject *
 run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals,
             PyCompilerFlags *flags)
@@ -949,7 +1006,6 @@ run_node(node *n, char *filename, PyObject *globals, PyObject *locals,
 {
        PyCodeObject *co;
        PyObject *v;
-       /* XXX pass sess->ss_nested_scopes to PyNode_Compile */
        co = PyNode_CompileFlags(n, filename, flags);
        PyNode_Free(n);
        if (co == NULL)
@@ -960,7 +1016,8 @@ run_node(node *n, char *filename, PyObject *globals, PyObject *locals,
 }
 
 static PyObject *
-run_pyc_file(FILE *fp, char *filename, PyObject *globals, PyObject *locals)
+run_pyc_file(FILE *fp, char *filename, PyObject *globals, PyObject *locals,
+            PyCompilerFlags *flags)
 {
        PyCodeObject *co;
        PyObject *v;
@@ -984,12 +1041,25 @@ run_pyc_file(FILE *fp, char *filename, PyObject *globals, PyObject *locals)
        }
        co = (PyCodeObject *)v;
        v = PyEval_EvalCode(co, globals, locals);
+       if (v && flags) {
+               if (co->co_flags & CO_NESTED)
+                       flags->cf_nested_scopes = 1;
+               fprintf(stderr, "run_pyc_file: nested_scopes: %d\n",
+                       flags->cf_nested_scopes);                       
+       }
        Py_DECREF(co);
        return v;
 }
 
 PyObject *
 Py_CompileString(char *str, char *filename, int start)
+{
+       return Py_CompileStringFlags(str, filename, start, NULL);
+}
+
+PyObject *
+Py_CompileStringFlags(char *str, char *filename, int start, 
+                     PyCompilerFlags *flags)
 {
        node *n;
        PyCodeObject *co;