summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2012-03-22 12:19:04 (GMT)
committerBenjamin Peterson <benjamin@python.org>2012-03-22 12:19:04 (GMT)
commiteff19a13ed4ca04e5be8c93a044952bad7de2054 (patch)
tree6f269bbd8a46c7ed9ba3c86577215fab030038dd
parent0e3c1075495dfc1ed481f65091d1f9241868324a (diff)
downloadcpython-eff19a13ed4ca04e5be8c93a044952bad7de2054.zip
cpython-eff19a13ed4ca04e5be8c93a044952bad7de2054.tar.gz
cpython-eff19a13ed4ca04e5be8c93a044952bad7de2054.tar.bz2
check by equality for __future__ not identity (closes #14378)
-rw-r--r--Lib/test/test_ast.py6
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/future.c11
3 files changed, 12 insertions, 8 deletions
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index e3aa5b1..4f80197 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -231,6 +231,12 @@ class AST_Tests(unittest.TestCase):
im = ast.parse("from . import y").body[0]
self.assertIsNone(im.module)
+ def test_non_interned_future_from_ast(self):
+ mod = ast.parse("from __future__ import division")
+ self.assertIsInstance(mod.body[0], ast.ImportFrom)
+ mod.body[0].module = " __future__ ".strip()
+ compile(mod, "<test>", "exec")
+
def test_base_classes(self):
self.assertTrue(issubclass(ast.For, ast.stmt))
self.assertTrue(issubclass(ast.Name, ast.expr))
diff --git a/Misc/NEWS b/Misc/NEWS
index 0e12494..310d0fd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -9,6 +9,9 @@ What's New in Python 2.7.4
Core and Builtins
-----------------
+- Issue #14378: Fix compiling ast.ImportFrom nodes with a "__future__" string as
+ the module name that was not interned.
+
- Issue #14331: Use significantly less stack space when importing modules by
allocating path buffers on the heap instead of the stack.
diff --git a/Python/future.c b/Python/future.c
index 96be757..1ab7a1a 100644
--- a/Python/future.c
+++ b/Python/future.c
@@ -59,13 +59,6 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
{
int i, found_docstring = 0, done = 0, prev_line = 0;
- static PyObject *future;
- if (!future) {
- future = PyString_InternFromString("__future__");
- if (!future)
- return 0;
- }
-
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
return 1;
@@ -92,7 +85,9 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
*/
if (s->kind == ImportFrom_kind) {
- if (s->v.ImportFrom.module == future) {
+ PyObject *modname = s->v.ImportFrom.module;
+ if (PyString_GET_SIZE(modname) == 10 &&
+ !strcmp(PyString_AS_STRING(modname), "__future__")) {
if (done) {
PyErr_SetString(PyExc_SyntaxError,
ERR_LATE_FUTURE);