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
........
This commit is contained in:
Benjamin Peterson 2008-10-31 02:28:05 +00:00
parent dd8059f078
commit f216c9427d
4 changed files with 62 additions and 13 deletions

View File

@ -106,6 +106,11 @@ class FutureTest(unittest.TestCase):
support.unload("test.test_future5") support.unload("test.test_future5")
from test import test_future5 from test import test_future5
def test_unicode_literals_exec(self):
scope = {}
exec("from __future__ import unicode_literals; x = ''", {}, scope)
self.assertTrue(isinstance(scope["x"], str))
def test_main(): def test_main():
support.run_unittest(FutureTest) support.run_unittest(FutureTest)

View File

@ -25,6 +25,15 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
def check_expr(self, s): def check_expr(self, s):
self.roundtrip(parser.expr, s) self.roundtrip(parser.expr, s)
def test_flags_passed(self):
# The unicode literals flags has to be passed from the paser to AST
# generation.
suite = parser.suite("from __future__ import unicode_literals; x = ''")
code = suite.compile()
scope = {}
exec(code, {}, scope)
self.assertTrue(isinstance(scope["x"], str))
def check_suite(self, s): def check_suite(self, s):
self.roundtrip(parser.suite, s) self.roundtrip(parser.suite, s)

View File

@ -26,12 +26,20 @@
*/ */
#include "Python.h" /* general Python API */ #include "Python.h" /* general Python API */
#include "Python-ast.h" /* mod_ty */
#include "graminit.h" /* symbols defined in the grammar */ #include "graminit.h" /* symbols defined in the grammar */
#include "node.h" /* internal parser structure */ #include "node.h" /* internal parser structure */
#include "errcode.h" /* error codes for PyNode_*() */ #include "errcode.h" /* error codes for PyNode_*() */
#include "token.h" /* token definitions */ #include "token.h" /* token definitions */
#include "grammar.h"
#include "parsetok.h"
/* ISTERMINAL() / ISNONTERMINAL() */ /* ISTERMINAL() / ISNONTERMINAL() */
#include "compile.h" /* PyNode_Compile() */ #include "compile.h"
#undef Yield
#include "ast.h"
#include "pyarena.h"
extern grammar _PyParser_Grammar; /* From graminit.c */
#ifdef lint #ifdef lint
#include <note.h> #include <note.h>
@ -156,6 +164,7 @@ typedef struct {
PyObject_HEAD /* standard object header */ PyObject_HEAD /* standard object header */
node* st_node; /* the node* returned by the parser */ node* st_node; /* the node* returned by the parser */
int st_type; /* EXPR or SUITE ? */ int st_type; /* EXPR or SUITE ? */
PyCompilerFlags st_flags; /* Parser and compiler flags */
} PyST_Object; } PyST_Object;
@ -287,6 +296,7 @@ parser_newstobject(node *st, int type)
if (o != 0) { if (o != 0) {
o->st_node = st; o->st_node = st;
o->st_type = type; o->st_type = type;
o->st_flags.cf_flags = 0;
} }
else { else {
PyNode_Free(st); PyNode_Free(st);
@ -405,6 +415,8 @@ static PyObject*
parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
{ {
PyObject* res = 0; PyObject* res = 0;
PyArena* arena;
mod_ty mod;
char* str = "<syntax-tree>"; char* str = "<syntax-tree>";
int ok; int ok;
@ -417,8 +429,16 @@ parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
&str); &str);
if (ok) if (ok) {
res = (PyObject *)PyNode_Compile(self->st_node, str); arena = PyArena_New();
if (arena) {
mod = PyAST_FromNode(self->st_node, &(self->st_flags), str, arena);
if (mod) {
res = (PyObject *)PyAST_Compile(mod, str, &(self->st_flags), arena);
}
PyArena_Free(arena);
}
}
return (res); return (res);
} }
@ -500,16 +520,25 @@ parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
{ {
char* string = 0; char* string = 0;
PyObject* res = 0; PyObject* res = 0;
int flags = 0;
perrdetail err;
static char *keywords[] = {"source", NULL}; static char *keywords[] = {"source", NULL};
if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
node* n = PyParser_SimpleParseString(string, node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL,
(type == PyST_EXPR) &_PyParser_Grammar,
? eval_input : file_input); (type == PyST_EXPR)
? eval_input : file_input,
&err, &flags);
if (n) if (n) {
res = parser_newstobject(n, type); res = parser_newstobject(n, type);
if (res)
((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK;
}
else
PyParser_SetError(&err);
} }
return (res); return (res);
} }

View File

@ -1688,16 +1688,19 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
PyCompilerFlags *flags, PyArena *arena) PyCompilerFlags *flags, PyArena *arena)
{ {
mod_ty mod; mod_ty mod;
PyCompilerFlags localflags;
perrdetail err; perrdetail err;
int iflags = PARSER_FLAGS(flags); int iflags = PARSER_FLAGS(flags);
node *n = PyParser_ParseStringFlagsFilenameEx(s, filename, node *n = PyParser_ParseStringFlagsFilenameEx(s, filename,
&_PyParser_Grammar, start, &err, &_PyParser_Grammar, start, &err,
&iflags); &iflags);
if (flags == NULL) {
localflags.cf_flags = 0;
flags = &localflags;
}
if (n) { if (n) {
if (flags) { flags->cf_flags |= iflags & PyCF_MASK;
flags->cf_flags |= iflags & PyCF_MASK;
}
mod = PyAST_FromNode(n, flags, filename, arena); mod = PyAST_FromNode(n, flags, filename, arena);
PyNode_Free(n); PyNode_Free(n);
return mod; return mod;
@ -1715,16 +1718,19 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
PyArena *arena) PyArena *arena)
{ {
mod_ty mod; mod_ty mod;
PyCompilerFlags localflags;
perrdetail err; perrdetail err;
int iflags = PARSER_FLAGS(flags); int iflags = PARSER_FLAGS(flags);
node *n = PyParser_ParseFileFlagsEx(fp, filename, enc, node *n = PyParser_ParseFileFlagsEx(fp, filename, enc,
&_PyParser_Grammar, &_PyParser_Grammar,
start, ps1, ps2, &err, &iflags); start, ps1, ps2, &err, &iflags);
if (flags == NULL) {
localflags.cf_flags = 0;
flags = &localflags;
}
if (n) { if (n) {
if (flags) { flags->cf_flags |= iflags & PyCF_MASK;
flags->cf_flags |= iflags & PyCF_MASK;
}
mod = PyAST_FromNode(n, flags, filename, arena); mod = PyAST_FromNode(n, flags, filename, arena);
PyNode_Free(n); PyNode_Free(n);
return mod; return mod;