Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9f324e9

Browse files
committed
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().
1 parent 0f6b383 commit 9f324e9

4 files changed

Lines changed: 59 additions & 26 deletions

File tree

Include/compile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ typedef struct {
5757
} PyFutureFeatures;
5858

5959
DL_IMPORT(PyFutureFeatures *) PyNode_Future(struct _node *, char *);
60+
DL_IMPORT(PyCodeObject *) PyNode_CompileFlags(struct _node *, char *,
61+
PyCompilerFlags *);
6062

6163
#define NESTED_SCOPES_DEFAULT 0
6264
#define FUTURE_NESTED_SCOPES "nested_scopes"

Include/pythonrun.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
extern "C" {
88
#endif
99

10+
typedef struct {
11+
int cf_nested_scopes;
12+
} PyCompilerFlags;
13+
1014
DL_IMPORT(void) Py_SetProgramName(char *);
1115
DL_IMPORT(char *) Py_GetProgramName(void);
1216

@@ -26,6 +30,7 @@ DL_IMPORT(int) PyRun_SimpleString(char *);
2630
DL_IMPORT(int) PyRun_SimpleFile(FILE *, char *);
2731
DL_IMPORT(int) PyRun_SimpleFileEx(FILE *, char *, int);
2832
DL_IMPORT(int) PyRun_InteractiveOne(FILE *, char *);
33+
DL_IMPORT(int) PyRun_InteractiveOneFlags(FILE *, char *, PyCompilerFlags *);
2934
DL_IMPORT(int) PyRun_InteractiveLoop(FILE *, char *);
3035

3136
DL_IMPORT(struct _node *) PyParser_SimpleParseString(char *, int);

Python/compile.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,8 @@ static int com_argdefs(struct compiling *, node *);
471471
static void com_assign(struct compiling *, node *, int, node *);
472472
static void com_assign_name(struct compiling *, node *, int);
473473
static PyCodeObject *icompile(node *, struct compiling *);
474-
static PyCodeObject *jcompile(node *, char *, struct compiling *);
474+
static PyCodeObject *jcompile(node *, char *, struct compiling *,
475+
PyCompilerFlags *);
475476
static PyObject *parsestrplus(node *);
476477
static PyObject *parsestr(char *);
477478
static node *get_rawdocstring(node *);
@@ -3816,7 +3817,13 @@ dict_keys_inorder(PyObject *dict, int offset)
38163817
PyCodeObject *
38173818
PyNode_Compile(node *n, char *filename)
38183819
{
3819-
return jcompile(n, filename, NULL);
3820+
return PyNode_CompileFlags(n, filename, NULL);
3821+
}
3822+
3823+
PyCodeObject *
3824+
PyNode_CompileFlags(node *n, char *filename, PyCompilerFlags *flags)
3825+
{
3826+
return jcompile(n, filename, NULL, flags);
38203827
}
38213828

38223829
struct symtable *
@@ -3844,11 +3851,12 @@ PyNode_CompileSymtable(node *n, char *filename)
38443851
static PyCodeObject *
38453852
icompile(node *n, struct compiling *base)
38463853
{
3847-
return jcompile(n, base->c_filename, base);
3854+
return jcompile(n, base->c_filename, base, NULL);
38483855
}
38493856

38503857
static PyCodeObject *
3851-
jcompile(node *n, char *filename, struct compiling *base)
3858+
jcompile(node *n, char *filename, struct compiling *base,
3859+
PyCompilerFlags *flags)
38523860
{
38533861
struct compiling sc;
38543862
PyCodeObject *co;
@@ -3864,7 +3872,17 @@ jcompile(node *n, char *filename, struct compiling *base)
38643872
} else {
38653873
sc.c_private = NULL;
38663874
sc.c_future = PyNode_Future(n, filename);
3867-
if (sc.c_future == NULL || symtable_build(&sc, n) < 0) {
3875+
if (sc.c_future == NULL) {
3876+
com_free(&sc);
3877+
return NULL;
3878+
}
3879+
if (flags) {
3880+
if (flags->cf_nested_scopes)
3881+
sc.c_future->ff_nested_scopes = 1;
3882+
else if (sc.c_future->ff_nested_scopes)
3883+
flags->cf_nested_scopes = 1;
3884+
}
3885+
if (symtable_build(&sc, n) < 0) {
38683886
com_free(&sc);
38693887
return NULL;
38703888
}
@@ -4952,12 +4970,10 @@ symtable_global(struct symtable *st, node *n)
49524970
{
49534971
int i;
49544972

4955-
if (st->st_nscopes == 1) {
4956-
/* XXX must check that we are compiling file_input */
4957-
if (symtable_warn(st,
4958-
"global statement has no meaning at module level") < 0)
4959-
return;
4960-
}
4973+
/* XXX It might be helpful to warn about module-level global
4974+
statements, but it's hard to tell the difference between
4975+
module-level and a string passed to exec.
4976+
*/
49614977

49624978
for (i = 1; i < NCH(n); i += 2) {
49634979
char *name = STR(CHILD(n, i));

Python/pythonrun.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,11 @@ extern grammar _PyParser_Grammar; /* From graminit.c */
3636
/* Forward */
3737
static void initmain(void);
3838
static void initsite(void);
39-
static PyObject *run_err_node(node *n, char *filename,
40-
PyObject *globals, PyObject *locals);
41-
static PyObject *run_node(node *n, char *filename,
42-
PyObject *globals, PyObject *locals);
43-
static PyObject *run_pyc_file(FILE *fp, char *filename,
44-
PyObject *globals, PyObject *locals);
39+
static PyObject *run_err_node(node *, char *, PyObject *, PyObject *,
40+
PyCompilerFlags *);
41+
static PyObject *run_node(node *, char *, PyObject *, PyObject *,
42+
PyCompilerFlags *);
43+
static PyObject *run_pyc_file(FILE *, char *, PyObject *, PyObject *);
4544
static void err_input(perrdetail *);
4645
static void initsigs(void);
4746
static void call_sys_exitfunc(void);
@@ -56,7 +55,6 @@ extern void _PyUnicode_Fini(void);
5655
extern void _PyCodecRegistry_Init(void);
5756
extern void _PyCodecRegistry_Fini(void);
5857

59-
6058
int Py_DebugFlag; /* Needed by parser.c */
6159
int Py_VerboseFlag; /* Needed by import.c */
6260
int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
@@ -472,6 +470,9 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
472470
{
473471
PyObject *v;
474472
int ret;
473+
PyCompilerFlags flags;
474+
475+
flags.cf_nested_scopes = 0;
475476
v = PySys_GetObject("ps1");
476477
if (v == NULL) {
477478
PySys_SetObject("ps1", v = PyString_FromString(">>> "));
@@ -483,7 +484,7 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
483484
Py_XDECREF(v);
484485
}
485486
for (;;) {
486-
ret = PyRun_InteractiveOne(fp, filename);
487+
ret = PyRun_InteractiveOneFlags(fp, filename, &flags);
487488
#ifdef Py_REF_DEBUG
488489
fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
489490
#endif
@@ -498,6 +499,12 @@ PyRun_InteractiveLoop(FILE *fp, char *filename)
498499

499500
int
500501
PyRun_InteractiveOne(FILE *fp, char *filename)
502+
{
503+
return PyRun_InteractiveOneFlags(fp, filename, NULL);
504+
}
505+
506+
int
507+
PyRun_InteractiveOneFlags(FILE *fp, char *filename, PyCompilerFlags *flags)
501508
{
502509
PyObject *m, *d, *v, *w;
503510
node *n;
@@ -537,7 +544,7 @@ PyRun_InteractiveOne(FILE *fp, char *filename)
537544
if (m == NULL)
538545
return -1;
539546
d = PyModule_GetDict(m);
540-
v = run_node(n, filename, d, d);
547+
v = run_node(n, filename, d, d, flags);
541548
if (v == NULL) {
542549
PyErr_Print();
543550
return -1;
@@ -907,7 +914,7 @@ PyObject *
907914
PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
908915
{
909916
return run_err_node(PyParser_SimpleParseString(str, start),
910-
"<string>", globals, locals);
917+
"<string>", globals, locals, NULL);
911918
}
912919

913920
PyObject *
@@ -924,23 +931,26 @@ PyRun_FileEx(FILE *fp, char *filename, int start, PyObject *globals,
924931
node *n = PyParser_SimpleParseFile(fp, filename, start);
925932
if (closeit)
926933
fclose(fp);
927-
return run_err_node(n, filename, globals, locals);
934+
return run_err_node(n, filename, globals, locals, NULL);
928935
}
929936

930937
static PyObject *
931-
run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals)
938+
run_err_node(node *n, char *filename, PyObject *globals, PyObject *locals,
939+
PyCompilerFlags *flags)
932940
{
933941
if (n == NULL)
934942
return NULL;
935-
return run_node(n, filename, globals, locals);
943+
return run_node(n, filename, globals, locals, flags);
936944
}
937945

938946
static PyObject *
939-
run_node(node *n, char *filename, PyObject *globals, PyObject *locals)
947+
run_node(node *n, char *filename, PyObject *globals, PyObject *locals,
948+
PyCompilerFlags *flags)
940949
{
941950
PyCodeObject *co;
942951
PyObject *v;
943-
co = PyNode_Compile(n, filename);
952+
/* XXX pass sess->ss_nested_scopes to PyNode_Compile */
953+
co = PyNode_CompileFlags(n, filename, flags);
944954
PyNode_Free(n);
945955
if (co == NULL)
946956
return NULL;

0 commit comments

Comments
 (0)