[Python-checkins] r67067 - in python/branches/release26-maint: Lib/test/test_future.py Lib/test/test_parser.py Misc/NEWS Modules/parsermodule.c Python/pythonrun.c

benjamin.peterson python-checkins at python.org
Fri Oct 31 03:26:20 CET 2008


Author: benjamin.peterson
Date: Fri Oct 31 03:26:20 2008
New Revision: 67067
Log:
Merged revisions 67066 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk
........
 r67066 | benjamin.peterson | 2008年10月30日 21:16:05 -0500 (2008年10月30日) | 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
........
Modified:
 python/branches/release26-maint/ (props changed)
 python/branches/release26-maint/Lib/test/test_future.py
 python/branches/release26-maint/Lib/test/test_parser.py
 python/branches/release26-maint/Misc/NEWS
 python/branches/release26-maint/Modules/parsermodule.c
 python/branches/release26-maint/Python/pythonrun.c
Modified: python/branches/release26-maint/Lib/test/test_future.py
==============================================================================
--- python/branches/release26-maint/Lib/test/test_future.py	(original)
+++ python/branches/release26-maint/Lib/test/test_future.py	Fri Oct 31 03:26:20 2008
@@ -106,6 +106,11 @@
 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)
Modified: python/branches/release26-maint/Lib/test/test_parser.py
==============================================================================
--- python/branches/release26-maint/Lib/test/test_parser.py	(original)
+++ python/branches/release26-maint/Lib/test/test_parser.py	Fri Oct 31 03:26:20 2008
@@ -25,6 +25,15 @@
 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)
 
Modified: python/branches/release26-maint/Misc/NEWS
==============================================================================
--- python/branches/release26-maint/Misc/NEWS	(original)
+++ python/branches/release26-maint/Misc/NEWS	Fri Oct 31 03:26:20 2008
@@ -12,6 +12,9 @@
 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.
 
Modified: python/branches/release26-maint/Modules/parsermodule.c
==============================================================================
--- python/branches/release26-maint/Modules/parsermodule.c	(original)
+++ python/branches/release26-maint/Modules/parsermodule.c	Fri Oct 31 03:26:20 2008
@@ -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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 {
 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);
 }
Modified: python/branches/release26-maint/Python/pythonrun.c
==============================================================================
--- python/branches/release26-maint/Python/pythonrun.c	(original)
+++ python/branches/release26-maint/Python/pythonrun.c	Fri Oct 31 03:26:20 2008
@@ -1417,16 +1417,19 @@
 		 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 @@
 		 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;


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /