]> granicus.if.org Git - python/commitdiff
Merged revisions 67066 via svnmerge from
authorBenjamin Peterson <benjamin@python.org>
Fri, 31 Oct 2008 02:26:20 +0000 (02:26 +0000)
committerBenjamin Peterson <benjamin@python.org>
Fri, 31 Oct 2008 02:26:20 +0000 (02:26 +0000)
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
........

Lib/test/test_future.py
Lib/test/test_parser.py
Misc/NEWS
Modules/parsermodule.c
Python/pythonrun.c

index 1432e749006df4f4a9fc08b46e8c10be23cde45c..81d0a3ed2a092646c0a14c021debdf6d28d58003 100644 (file)
@@ -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)
index ba77bb806f38b79cd7228ee8490963520d5fdff6..9ecca51a36060e7ba729ee3130190e6e9c8b37c4 100644 (file)
@@ -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)
 
index f2ca0e0b021ce100a8bd2817bc52bb4c9e9dffb9..c47620a936868216cbb0fcaa49adfbfb91c4b306 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.
 
index 915bbdc7b2e29db3bef9fa94166803ef02508c9c..423a0b350062daeab95dbdac187bc2bc241e9e5c 100644 (file)
  */
 
 #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);
 }
index bdd9bd7d881919ebb0e989ca7c185f436fc0998f..4ff70d8543022f0292dd7fb4607160a8e5da5bf7 100644 (file)
@@ -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;