diff options
author | Benjamin Peterson <benjamin@python.org> | 2008-10-31 02:26:20 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2008-10-31 02:26:20 (GMT) |
commit | 084ce7a5dcadc2d1bac565a363ae54bbcb09abd0 (patch) | |
tree | becfcca3c908631d560cc08376d5747a79618168 | |
parent | f4d016f38a48e15823021b969aa66cabd0f679a8 (diff) | |
download | cpython-084ce7a5dcadc2d1bac565a363ae54bbcb09abd0.zip cpython-084ce7a5dcadc2d1bac565a363ae54bbcb09abd0.tar.gz cpython-084ce7a5dcadc2d1bac565a363ae54bbcb09abd0.tar.bz2 |
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
........
-rw-r--r-- | Lib/test/test_future.py | 5 | ||||
-rw-r--r-- | Lib/test/test_parser.py | 9 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/parsermodule.c | 43 | ||||
-rw-r--r-- | Python/pythonrun.c | 18 |
5 files changed, 65 insertions, 13 deletions
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index 1432e74..81d0a3e 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -106,6 +106,11 @@ class FutureTest(unittest.TestCase): test_support.unload("test.test_future5") from test import test_future5 + def test_unicode_literals_exec(self): + scope = {} + exec "from __future__ import unicode_literals; x = ''" in scope + self.assertTrue(isinstance(scope["x"], unicode)) + def test_main(): test_support.run_unittest(FutureTest) diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index ba77bb8..9ecca51 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -25,6 +25,15 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): def check_expr(self, 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 in scope + self.assertTrue(isinstance(scope["x"], unicode)) + def check_suite(self, s): self.roundtrip(parser.suite, s) @@ -12,6 +12,9 @@ What's New in Python 2.6.1 alpha 1 Core and Builtins ----------------- +- Issue #4225: ``from __future__ import unicode_literals`` didn't work in an + exec statement. + - Issue #4176: Fixed a crash when pickling an object which ``__reduce__`` method does not return iterators for the 4th and 5th items. diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 915bbdc..423a0b3 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -26,12 +26,20 @@ */ #include "Python.h" /* general Python API */ +#include "Python-ast.h" /* mod_ty */ #include "graminit.h" /* symbols defined in the grammar */ #include "node.h" /* internal parser structure */ #include "errcode.h" /* error codes for PyNode_*() */ #include "token.h" /* token definitions */ +#include "grammar.h" +#include "parsetok.h" /* 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 #include <note.h> @@ -156,6 +164,7 @@ typedef struct { PyObject_HEAD /* standard object header */ node* st_node; /* the node* returned by the parser */ int st_type; /* EXPR or SUITE ? */ + PyCompilerFlags st_flags; /* Parser and compiler flags */ } PyST_Object; @@ -260,6 +269,7 @@ parser_newstobject(node *st, int type) if (o != 0) { o->st_node = st; o->st_type = type; + o->st_flags.cf_flags = 0; } else { PyNode_Free(st); @@ -394,6 +404,8 @@ static PyObject* parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject* res = 0; + PyArena* arena; + mod_ty mod; char* str = "<syntax-tree>"; int ok; @@ -406,8 +418,16 @@ parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], &str); - if (ok) - res = (PyObject *)PyNode_Compile(self->st_node, str); + if (ok) { + 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); } @@ -523,16 +543,25 @@ parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type) { char* string = 0; PyObject* res = 0; + int flags = 0; + perrdetail err; static char *keywords[] = {"source", NULL}; if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { - node* n = PyParser_SimpleParseString(string, - (type == PyST_EXPR) - ? eval_input : file_input); + node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL, + &_PyParser_Grammar, + (type == PyST_EXPR) + ? eval_input : file_input, + &err, &flags); - if (n) + if (n) { res = parser_newstobject(n, type); + if (res) + ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK; + } + else + PyParser_SetError(&err); } return (res); } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index bdd9bd7..4ff70d8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1417,16 +1417,19 @@ PyParser_ASTFromString(const char *s, const char *filename, int start, PyCompilerFlags *flags, PyArena *arena) { mod_ty mod; + PyCompilerFlags localflags; perrdetail err; int iflags = PARSER_FLAGS(flags); node *n = PyParser_ParseStringFlagsFilenameEx(s, filename, &_PyParser_Grammar, start, &err, &iflags); + if (flags == NULL) { + localflags.cf_flags = 0; + flags = &localflags; + } if (n) { - if (flags) { - flags->cf_flags |= iflags & PyCF_MASK; - } + flags->cf_flags |= iflags & PyCF_MASK; mod = PyAST_FromNode(n, flags, filename, arena); PyNode_Free(n); return mod; @@ -1443,15 +1446,18 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, PyArena *arena) { mod_ty mod; + PyCompilerFlags localflags; perrdetail err; int iflags = PARSER_FLAGS(flags); node *n = PyParser_ParseFileFlagsEx(fp, filename, &_PyParser_Grammar, start, ps1, ps2, &err, &iflags); + if (flags == NULL) { + localflags.cf_flags = 0; + flags = &localflags; + } if (n) { - if (flags) { - flags->cf_flags |= iflags & PyCF_MASK; - } + flags->cf_flags |= iflags & PyCF_MASK; mod = PyAST_FromNode(n, flags, filename, arena); PyNode_Free(n); return mod; |