[Python-Dev] __future__ and the interactive interpreter prompt
Jeremy Hylton
jeremy@alum.mit.edu
Thu, 1 Mar 2001 13:16:03 -0500 (EST)
from __future__ import nested_scopes is accepted at the interactive
interpreter prompt but has no effect beyond the line on which it was
entered. You could use it with lambdas entered following a
semicolon, I guess.
I would rather see the future statement take effect for the remained
of the interactive interpreter session. I have included a first-cut
patch below that makes this possible, using an object called
PySessionState. (I don't like the name, but don't have a better one;
PyCompilerFlags?)
The idea of the session state is to record information about the state
of an interactive session that may affect compilation. The
state object is created in PyRun_InteractiveLoop() and passed all the
way through to PyNode_Compile().
Does this seem a reasonable approach? Should I include it in the
beta? Any name suggestions.
Jeremy
Index: Include/compile.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/compile.h,v
retrieving revision 2.27
diff -c -r2.27 compile.h
*** Include/compile.h 2001/02/28 01:58:08 2.27
--- Include/compile.h 2001/03/01 18:18:27
***************
*** 41,47 ****
/* Public interface */
struct _node; /* Declare the existence of this type */
! DL_IMPORT(PyCodeObject *) PyNode_Compile(struct _node *, char *);
DL_IMPORT(PyCodeObject *) PyCode_New(
int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *);
--- 41,48 ----
/* Public interface */
struct _node; /* Declare the existence of this type */
! DL_IMPORT(PyCodeObject *) PyNode_Compile(struct _node *, char *,
! PySessionState *);
DL_IMPORT(PyCodeObject *) PyCode_New(
int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *);
Index: Include/pythonrun.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v
retrieving revision 2.38
diff -c -r2.38 pythonrun.h
*** Include/pythonrun.h 2001/02/02 18:19:15 2.38
--- Include/pythonrun.h 2001/03/01 18:18:27
***************
*** 7,12 ****
--- 7,16 ----
extern "C" {
#endif
+ typedef struct {
+ int ss_nested_scopes;
+ } PySessionState;
+
DL_IMPORT(void) Py_SetProgramName(char *);
DL_IMPORT(char *) Py_GetProgramName(void);
***************
*** 25,31 ****
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_InteractiveLoop(FILE *, char *);
DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int);
--- 29,35 ----
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 *, PySessionState *);
DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *);
DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int);
Index: Python/compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.184
diff -c -r2.184 compile.c
*** Python/compile.c 2001/03/01 06:09:34 2.184
--- Python/compile.c 2001/03/01 18:18:28
***************
*** 471,477 ****
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 PyObject *parsestrplus(node *);
static PyObject *parsestr(char *);
static node *get_rawdocstring(node *);
--- 471,478 ----
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 *,
! PySessionState *);
static PyObject *parsestrplus(node *);
static PyObject *parsestr(char *);
static node *get_rawdocstring(node *);
***************
*** 3814,3822 ****
}
PyCodeObject *
! PyNode_Compile(node *n, char *filename)
{
! return jcompile(n, filename, NULL);
}
struct symtable *
--- 3815,3823 ----
}
PyCodeObject *
! PyNode_Compile(node *n, char *filename, PySessionState *sess)
{
! return jcompile(n, filename, NULL, sess);
}
struct symtable *
***************
*** 3844,3854 ****
static PyCodeObject *
icompile(node *n, struct compiling *base)
{
! return jcompile(n, base->c_filename, base);
}
static PyCodeObject *
! jcompile(node *n, char *filename, struct compiling *base)
{
struct compiling sc;
PyCodeObject *co;
--- 3845,3856 ----
static PyCodeObject *
icompile(node *n, struct compiling *base)
{
! return jcompile(n, base->c_filename, base, NULL);
}
static PyCodeObject *
! jcompile(node *n, char *filename, struct compiling *base,
! PySessionState *sess)
{
struct compiling sc;
PyCodeObject *co;
***************
*** 3864,3870 ****
} else {
sc.c_private = NULL;
sc.c_future = PyNode_Future(n, filename);
! if (sc.c_future == NULL || symtable_build(&sc, n) < 0) {
com_free(&sc);
return NULL;
}
--- 3866,3882 ----
} else {
sc.c_private = NULL;
sc.c_future = PyNode_Future(n, filename);
! if (sc.c_future == NULL) {
! com_free(&sc);
! return NULL;
! }
! if (sess) {
! if (sess->ss_nested_scopes)
! sc.c_future->ff_nested_scopes = 1;
! else if (sc.c_future->ff_nested_scopes)
! sess->ss_nested_scopes = 1;
! }
! if (symtable_build(&sc, n) < 0) {
com_free(&sc);
return NULL;
}
Index: Python/import.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/import.c,v
retrieving revision 2.169
diff -c -r2.169 import.c
*** Python/import.c 2001/03/01 08:47:29 2.169
--- Python/import.c 2001/03/01 18:18:28
***************
*** 608,614 ****
n = PyParser_SimpleParseFile(fp, pathname, Py_file_input);
if (n == NULL)
return NULL;
! co = PyNode_Compile(n, pathname);
PyNode_Free(n);
return co;
--- 608,614 ----
n = PyParser_SimpleParseFile(fp, pathname, Py_file_input);
if (n == NULL)
return NULL;
! co = PyNode_Compile(n, pathname, NULL);
PyNode_Free(n);
return co;
Index: Python/pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.125
diff -c -r2.125 pythonrun.c
*** Python/pythonrun.c 2001/02/28 20:58:04 2.125
--- Python/pythonrun.c 2001/03/01 18:18:28
***************
*** 37,45 ****
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 void err_input(perrdetail *);
--- 37,47 ----
static void initmain(void);
static void initsite(void);
static PyObject *run_err_node(node *n, char *filename,
! PyObject *globals, PyObject *locals,
! PySessionState *sess);
static PyObject *run_node(node *n, char *filename,
! PyObject *globals, PyObject *locals,
! PySessionState *sess);
static PyObject *run_pyc_file(FILE *fp, char *filename,
PyObject *globals, PyObject *locals);
static void err_input(perrdetail *);
***************
*** 56,62 ****
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 */
--- 58,63 ----
***************
*** 472,477 ****
--- 473,481 ----
{
PyObject *v;
int ret;
+ PySessionState sess;
+
+ sess.ss_nested_scopes = 0;
v = PySys_GetObject("ps1");
if (v == NULL) {
PySys_SetObject("ps1", v = PyString_FromString(">>> "));
***************
*** 483,489 ****
Py_XDECREF(v);
}
for (;;) {
! ret = PyRun_InteractiveOne(fp, filename);
#ifdef Py_REF_DEBUG
fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
#endif
--- 487,493 ----
Py_XDECREF(v);
}
for (;;) {
! ret = PyRun_InteractiveOne(fp, filename, &sess);
#ifdef Py_REF_DEBUG
fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
#endif
***************
*** 497,503 ****
}
int
! PyRun_InteractiveOne(FILE *fp, char *filename)
{
PyObject *m, *d, *v, *w;
node *n;
--- 501,507 ----
}
int
! PyRun_InteractiveOne(FILE *fp, char *filename, PySessionState *sess)
{
PyObject *m, *d, *v, *w;
node *n;
***************
*** 537,543 ****
if (m == NULL)
return -1;
d = PyModule_GetDict(m);
! v = run_node(n, filename, d, d);
if (v == NULL) {
PyErr_Print();
return -1;
--- 541,547 ----
if (m == NULL)
return -1;
d = PyModule_GetDict(m);
! v = run_node(n, filename, d, d, sess);
if (v == NULL) {
PyErr_Print();
return -1;
***************
*** 907,913 ****
PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
{
return run_err_node(PyParser_SimpleParseString(str, start),
! "<string>", globals, locals);
}
PyObject *
--- 911,917 ----
PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
{
return run_err_node(PyParser_SimpleParseString(str, start),
! "<string>", globals, locals, NULL);
}
PyObject *
***************
*** 924,946 ****
node *n = PyParser_SimpleParseFile(fp, filename, start);
if (closeit)
fclose(fp);
! return run_err_node(n, filename, globals, locals);
}
static PyObject *
! run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals)
{
if (n == NULL)
return NULL;
! return run_node(n, filename, globals, locals);
}
static PyObject *
! run_node(node *n, char *filename, PyObject *globals, PyObject *locals)
{
PyCodeObject *co;
PyObject *v;
! co = PyNode_Compile(n, filename);
PyNode_Free(n);
if (co == NULL)
return NULL;
--- 928,957 ----
node *n = PyParser_SimpleParseFile(fp, filename, start);
if (closeit)
fclose(fp);
! return run_err_node(n, filename, globals, locals, NULL);
}
static PyObject *
! run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals,
! PySessionState *sess)
{
if (n == NULL)
return NULL;
! return run_node(n, filename, globals, locals, sess);
}
static PyObject *
! run_node(node *n, char *filename, PyObject *globals, PyObject *locals,
! PySessionState *sess)
{
PyCodeObject *co;
PyObject *v;
! if (sess) {
! fprintf(stderr, "session state: %d\n",
! sess->ss_nested_scopes);
! }
! /* XXX pass sess->ss_nested_scopes to PyNode_Compile */
! co = PyNode_Compile(n, filename, sess);
PyNode_Free(n);
if (co == NULL)
return NULL;
***************
*** 986,992 ****
n = PyParser_SimpleParseString(str, start);
if (n == NULL)
return NULL;
! co = PyNode_Compile(n, filename);
PyNode_Free(n);
return (PyObject *)co;
}
--- 997,1003 ----
n = PyParser_SimpleParseString(str, start);
if (n == NULL)
return NULL;
! co = PyNode_Compile(n, filename, NULL);
PyNode_Free(n);
return (PyObject *)co;
}