]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Useful future statement support for the interactive interpreter
authorJeremy Hylton <jeremy@alum.mit.edu>
Thu, 1 Mar 2001 22:59:14 +0000 (22:59 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Thu, 1 Mar 2001 22:59:14 +0000 (22:59 +0000)
(Also remove warning about module-level global decl, because we can't
distinguish from code passed to exec.)

Define PyCompilerFlags type contains a single element,
cf_nested_scopes, that is true if a nested scopes future statement has
been entered at the interactive prompt.

New API functions:
    PyNode_CompileFlags()
    PyRun_InteractiveOneFlags()
    -- same as their non Flags counterparts except that the take an
       optional PyCompilerFlags pointer

compile.c: In jcompile() use PyCompilerFlags argument.  If
    cf_nested_scopes is true, compile code with nested scopes.  If it
    is false, but the code has a valid future nested scopes statement,
    set it to true.

pythonrun.c: Create a new PyCompilerFlags object in
    PyRun_InteractiveLoop() and thread it through to
    PyRun_InteractiveOneFlags().

Include/compile.h
Include/pythonrun.h
Python/compile.c
Python/pythonrun.c

index 45854e9cd290f0b72b129f6788ed4953fc644d8f..deb8ee8a980c61c3737476c2b3b3fe1acf20b761 100644 (file)
@@ -57,6 +57,8 @@ typedef struct {
 } PyFutureFeatures;
 
 DL_IMPORT(PyFutureFeatures *) PyNode_Future(struct _node *, char *);
+DL_IMPORT(PyCodeObject *) PyNode_CompileFlags(struct _node *, char *,
+                                             PyCompilerFlags *);
 
 #define NESTED_SCOPES_DEFAULT 0
 #define FUTURE_NESTED_SCOPES "nested_scopes"
index 13ed4715e79312e807a809f586484e2b4c4bcc45..3f9f70b947b417a89e9a261a23100b4718599c48 100644 (file)
@@ -7,6 +7,10 @@
 extern "C" {
 #endif
 
+typedef struct {
+       int cf_nested_scopes;
+} PyCompilerFlags;
+
 DL_IMPORT(void) Py_SetProgramName(char *);
 DL_IMPORT(char *) Py_GetProgramName(void);
 
@@ -26,6 +30,7 @@ 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_InteractiveOne(FILE *, char *);
+DL_IMPORT(int) PyRun_InteractiveOneFlags(FILE *, char *, PyCompilerFlags *);
 DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *);
 
 DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int);
index efef05b25a9265c3a58b61bc9b59b787d331d5e3..fe4d05ef0efe5cd410ea17fcb76e82861474ea7d 100644 (file)
@@ -471,7 +471,8 @@ static int com_argdefs(struct compiling *, node *);
 static void com_assign(struct compiling *, node *, int, node *);
 static void com_assign_name(struct compiling *, node *, int);
 static PyCodeObject *icompile(node *, struct compiling *);
-static PyCodeObject *jcompile(node *, char *, struct compiling *);
+static PyCodeObject *jcompile(node *, char *, struct compiling *,
+                             PyCompilerFlags *);
 static PyObject *parsestrplus(node *);
 static PyObject *parsestr(char *);
 static node *get_rawdocstring(node *);
@@ -3816,7 +3817,13 @@ dict_keys_inorder(PyObject *dict, int offset)
 PyCodeObject *
 PyNode_Compile(node *n, char *filename)
 {
-       return jcompile(n, filename, NULL);
+       return PyNode_CompileFlags(n, filename, NULL);
+}
+
+PyCodeObject *
+PyNode_CompileFlags(node *n, char *filename, PyCompilerFlags *flags)
+{
+       return jcompile(n, filename, NULL, flags);
 }
 
 struct symtable *
@@ -3844,11 +3851,12 @@ PyNode_CompileSymtable(node *n, char *filename)
 static PyCodeObject *
 icompile(node *n, struct compiling *base)
 {
-       return jcompile(n, base->c_filename, base);
+       return jcompile(n, base->c_filename, base, NULL);
 }
 
 static PyCodeObject *
-jcompile(node *n, char *filename, struct compiling *base)
+jcompile(node *n, char *filename, struct compiling *base,
+        PyCompilerFlags *flags)
 {
        struct compiling sc;
        PyCodeObject *co;
@@ -3864,7 +3872,17 @@ jcompile(node *n, char *filename, struct compiling *base)
        } else {
                sc.c_private = NULL;
                sc.c_future = PyNode_Future(n, filename);
-               if (sc.c_future == NULL || symtable_build(&sc, n) < 0) {
+               if (sc.c_future == NULL) {
+                       com_free(&sc);
+                       return NULL;
+               }
+               if (flags) {
+                       if (flags->cf_nested_scopes)
+                               sc.c_future->ff_nested_scopes = 1;
+                       else if (sc.c_future->ff_nested_scopes)
+                               flags->cf_nested_scopes = 1;
+               }
+               if (symtable_build(&sc, n) < 0) {
                        com_free(&sc);
                        return NULL;
                }
@@ -4952,12 +4970,10 @@ symtable_global(struct symtable *st, node *n)
 {
        int i;
 
-       if (st->st_nscopes == 1) {
-               /* XXX must check that we are compiling file_input */
-               if (symtable_warn(st, 
-                 "global statement has no meaning at module level") < 0)
-                       return;
-       }
+       /* XXX It might be helpful to warn about module-level global
+          statements, but it's hard to tell the difference between
+          module-level and a string passed to exec.
+       */
 
        for (i = 1; i < NCH(n); i += 2) {
                char *name = STR(CHILD(n, i));
index 7d73395fd0d11a7ef6dc6a8996b5679fa2ee38b0..f7c282089d0d5361a5ff33f06da62f17a2876f82 100644 (file)
@@ -36,12 +36,11 @@ extern grammar _PyParser_Grammar; /* From graminit.c */
 /* Forward */
 static void initmain(void);
 static void initsite(void);
-static PyObject *run_err_node(node *n, char *filename,
-                             PyObject *globals, PyObject *locals);
-static PyObject *run_node(node *n, char *filename,
-                         PyObject *globals, PyObject *locals);
-static PyObject *run_pyc_file(FILE *fp, char *filename,
-                             PyObject *globals, PyObject *locals);
+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 void err_input(perrdetail *);
 static void initsigs(void);
 static void call_sys_exitfunc(void);
@@ -56,7 +55,6 @@ extern void _PyUnicode_Fini(void);
 extern void _PyCodecRegistry_Init(void);
 extern void _PyCodecRegistry_Fini(void);
 
-
 int Py_DebugFlag; /* Needed by parser.c */
 int Py_VerboseFlag; /* Needed by import.c */
 int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
@@ -472,6 +470,9 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
 {
        PyObject *v;
        int ret;
+       PyCompilerFlags flags;
+
+       flags.cf_nested_scopes = 0;
        v = PySys_GetObject("ps1");
        if (v == NULL) {
                PySys_SetObject("ps1", v = PyString_FromString(">>> "));
@@ -483,7 +484,7 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
                Py_XDECREF(v);
        }
        for (;;) {
-               ret = PyRun_InteractiveOne(fp, filename);
+               ret = PyRun_InteractiveOneFlags(fp, filename, &flags);
 #ifdef Py_REF_DEBUG
                fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
 #endif
@@ -498,6 +499,12 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
 
 int
 PyRun_InteractiveOne(FILE *fp, char *filename)
+{
+       return PyRun_InteractiveOneFlags(fp, filename, NULL);
+}
+
+int
+PyRun_InteractiveOneFlags(FILE *fp, char *filename, PyCompilerFlags *flags)
 {
        PyObject *m, *d, *v, *w;
        node *n;
@@ -537,7 +544,7 @@ PyRun_InteractiveOne(FILE *fp, char *filename)
        if (m == NULL)
                return -1;
        d = PyModule_GetDict(m);
-       v = run_node(n, filename, d, d);
+       v = run_node(n, filename, d, d, flags);
        if (v == NULL) {
                PyErr_Print();
                return -1;
@@ -907,7 +914,7 @@ PyObject *
 PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
 {
        return run_err_node(PyParser_SimpleParseString(str, start),
-                           "<string>", globals, locals);
+                           "<string>", globals, locals, NULL);
 }
 
 PyObject *
@@ -924,23 +931,26 @@ PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals,
        node *n = PyParser_SimpleParseFile(fp, filename, start);
        if (closeit)
                fclose(fp);
-       return run_err_node(n, filename, globals, locals);
+       return run_err_node(n, filename, globals, locals, NULL);
 }
 
 static PyObject *
-run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals)
+run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals,
+            PyCompilerFlags *flags)
 {
        if (n == NULL)
                return  NULL;
-       return run_node(n, filename, globals, locals);
+       return run_node(n, filename, globals, locals, flags);
 }
 
 static PyObject *
-run_node(node *n, char *filename, PyObject *globals, PyObject *locals)
+run_node(node *n, char *filename, PyObject *globals, PyObject *locals,
+        PyCompilerFlags *flags)
 {
        PyCodeObject *co;
        PyObject *v;
-       co = PyNode_Compile(n, filename);
+       /* XXX pass sess->ss_nested_scopes to PyNode_Compile */
+       co = PyNode_CompileFlags(n, filename, flags);
        PyNode_Free(n);
        if (co == NULL)
                return NULL;