Kaydet (Commit) 9f324e96 authored tarafından Jeremy Hylton's avatar Jeremy Hylton

Useful future statement support for the interactive interpreter

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