Skip to content

Commit e437ad6

Browse files
author
benjamin.peterson
committed
Merged revisions 67066 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r67066 | benjamin.peterson | 2008-10-30 21:16:05 -0500 (Thu, 30 Oct 2008) | 5 lines make sure the parser flags and passed onto the compiler This fixes "from __future__ import unicode_literals" in an exec statment See #4225 ........ git-svn-id: http://svn.python.org/projects/python/branches/py3k@67068 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent b4e9789 commit e437ad6

4 files changed

Lines changed: 62 additions & 13 deletions

File tree

Lib/test/test_future.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ def test_multiple_features(self):
106106
support.unload("test.test_future5")
107107
from test import test_future5
108108

109+
def test_unicode_literals_exec(self):
110+
scope = {}
111+
exec("from __future__ import unicode_literals; x = ''", {}, scope)
112+
self.assertTrue(isinstance(scope["x"], str))
113+
109114

110115
def test_main():
111116
support.run_unittest(FutureTest)

Lib/test/test_parser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ def roundtrip(self, f, s):
2525
def check_expr(self, s):
2626
self.roundtrip(parser.expr, s)
2727

28+
def test_flags_passed(self):
29+
# The unicode literals flags has to be passed from the paser to AST
30+
# generation.
31+
suite = parser.suite("from __future__ import unicode_literals; x = ''")
32+
code = suite.compile()
33+
scope = {}
34+
exec(code, {}, scope)
35+
self.assertTrue(isinstance(scope["x"], str))
36+
2837
def check_suite(self, s):
2938
self.roundtrip(parser.suite, s)
3039

Modules/parsermodule.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@
2626
*/
2727

2828
#include "Python.h" /* general Python API */
29+
#include "Python-ast.h" /* mod_ty */
2930
#include "graminit.h" /* symbols defined in the grammar */
3031
#include "node.h" /* internal parser structure */
3132
#include "errcode.h" /* error codes for PyNode_*() */
3233
#include "token.h" /* token definitions */
34+
#include "grammar.h"
35+
#include "parsetok.h"
3336
/* ISTERMINAL() / ISNONTERMINAL() */
34-
#include "compile.h" /* PyNode_Compile() */
37+
#include "compile.h"
38+
#undef Yield
39+
#include "ast.h"
40+
#include "pyarena.h"
41+
42+
extern grammar _PyParser_Grammar; /* From graminit.c */
3543

3644
#ifdef lint
3745
#include <note.h>
@@ -156,6 +164,7 @@ typedef struct {
156164
PyObject_HEAD /* standard object header */
157165
node* st_node; /* the node* returned by the parser */
158166
int st_type; /* EXPR or SUITE ? */
167+
PyCompilerFlags st_flags; /* Parser and compiler flags */
159168
} PyST_Object;
160169

161170

@@ -287,6 +296,7 @@ parser_newstobject(node *st, int type)
287296
if (o != 0) {
288297
o->st_node = st;
289298
o->st_type = type;
299+
o->st_flags.cf_flags = 0;
290300
}
291301
else {
292302
PyNode_Free(st);
@@ -405,6 +415,8 @@ static PyObject*
405415
parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
406416
{
407417
PyObject* res = 0;
418+
PyArena* arena;
419+
mod_ty mod;
408420
char* str = "<syntax-tree>";
409421
int ok;
410422

@@ -417,8 +429,16 @@ parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
417429
ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
418430
&str);
419431

420-
if (ok)
421-
res = (PyObject *)PyNode_Compile(self->st_node, str);
432+
if (ok) {
433+
arena = PyArena_New();
434+
if (arena) {
435+
mod = PyAST_FromNode(self->st_node, &(self->st_flags), str, arena);
436+
if (mod) {
437+
res = (PyObject *)PyAST_Compile(mod, str, &(self->st_flags), arena);
438+
}
439+
PyArena_Free(arena);
440+
}
441+
}
422442

423443
return (res);
424444
}
@@ -500,16 +520,25 @@ parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
500520
{
501521
char* string = 0;
502522
PyObject* res = 0;
523+
int flags = 0;
524+
perrdetail err;
503525

504526
static char *keywords[] = {"source", NULL};
505527

506528
if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
507-
node* n = PyParser_SimpleParseString(string,
508-
(type == PyST_EXPR)
509-
? eval_input : file_input);
529+
node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL,
530+
&_PyParser_Grammar,
531+
(type == PyST_EXPR)
532+
? eval_input : file_input,
533+
&err, &flags);
510534

511-
if (n)
535+
if (n) {
512536
res = parser_newstobject(n, type);
537+
if (res)
538+
((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK;
539+
}
540+
else
541+
PyParser_SetError(&err);
513542
}
514543
return (res);
515544
}

Python/pythonrun.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,16 +1688,19 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
16881688
PyCompilerFlags *flags, PyArena *arena)
16891689
{
16901690
mod_ty mod;
1691+
PyCompilerFlags localflags;
16911692
perrdetail err;
16921693
int iflags = PARSER_FLAGS(flags);
16931694

16941695
node *n = PyParser_ParseStringFlagsFilenameEx(s, filename,
16951696
&_PyParser_Grammar, start, &err,
16961697
&iflags);
1698+
if (flags == NULL) {
1699+
localflags.cf_flags = 0;
1700+
flags = &localflags;
1701+
}
16971702
if (n) {
1698-
if (flags) {
1699-
flags->cf_flags |= iflags & PyCF_MASK;
1700-
}
1703+
flags->cf_flags |= iflags & PyCF_MASK;
17011704
mod = PyAST_FromNode(n, flags, filename, arena);
17021705
PyNode_Free(n);
17031706
return mod;
@@ -1715,16 +1718,19 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
17151718
PyArena *arena)
17161719
{
17171720
mod_ty mod;
1721+
PyCompilerFlags localflags;
17181722
perrdetail err;
17191723
int iflags = PARSER_FLAGS(flags);
17201724

17211725
node *n = PyParser_ParseFileFlagsEx(fp, filename, enc,
17221726
&_PyParser_Grammar,
17231727
start, ps1, ps2, &err, &iflags);
1728+
if (flags == NULL) {
1729+
localflags.cf_flags = 0;
1730+
flags = &localflags;
1731+
}
17241732
if (n) {
1725-
if (flags) {
1726-
flags->cf_flags |= iflags & PyCF_MASK;
1727-
}
1733+
flags->cf_flags |= iflags & PyCF_MASK;
17281734
mod = PyAST_FromNode(n, flags, filename, arena);
17291735
PyNode_Free(n);
17301736
return mod;

0 commit comments

Comments
 (0)