]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
prevent import statements from assigning to None
authorBenjamin Peterson <benjamin@python.org>
Sat, 13 Jun 2009 03:46:30 +0000 (03:46 +0000)
committerBenjamin Peterson <benjamin@python.org>
Sat, 13 Jun 2009 03:46:30 +0000 (03:46 +0000)
Lib/test/test_compile.py
Misc/NEWS
Python/ast.c

index 78215d2b63a6fc066ef4d84f44130c7e03a87991..4e15d8c65765af2f9ce9bf4674e1f2aa870cb98f 100644 (file)
@@ -270,11 +270,17 @@ if 1:
             '(a, None) = 0, 0',
             'for None in range(10): pass',
             'def f(None): pass',
+            'import None',
+            'import x as None',
+            'from x import None',
+            'from x import y as None'
         ]
         for stmt in stmts:
             stmt += "\n"
             self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
             self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
+        # This is ok.
+        compile("from None import x", "tmp", "exec")
 
     def test_import(self):
         succeed = [
index 11926185d638338d7be9db1a0a6bd1106ad6ed02..18976c03be1d9995ac21f12a86787182795059a2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.7 alpha 1
 Core and Builtins
 -----------------
 
+- Assignment to None using import statements now raises a SyntaxError.
+
 - In the slice AST type, the step field will always be None if a step expression
   is not specified.
 
index 772047fc4b069a5fd93ccd4039c8590fe85b32b7..9639350bc7f7b2513c84bfbb0db3168eb0158c72 100644 (file)
@@ -2294,7 +2294,7 @@ ast_for_flow_stmt(struct compiling *c, const node *n)
 }
 
 static alias_ty
-alias_for_import_name(struct compiling *c, const node *n)
+alias_for_import_name(struct compiling *c, const node *n, int store)
 {
     /*
       import_as_name: NAME ['as' NAME]
@@ -2305,28 +2305,38 @@ alias_for_import_name(struct compiling *c, const node *n)
 
  loop:
     switch (TYPE(n)) {
-        case import_as_name:
+         case import_as_name: {
+            node *name_node = CHILD(n, 0);
             str = NULL;
             if (NCH(n) == 3) {
-                str = NEW_IDENTIFIER(CHILD(n, 2));
+                node *str_node = CHILD(n, 2);
+                if (store && !forbidden_check(c, str_node, STR(str_node)))
+                    return NULL;
+                str = NEW_IDENTIFIER(str_node);
                 if (!str)
                     return NULL;
             }
-            name = NEW_IDENTIFIER(CHILD(n, 0));
+            if (!forbidden_check(c, name_node, STR(name_node)))
+                return NULL;
+            name = NEW_IDENTIFIER(name_node);
             if (!name)
                 return NULL;
             return alias(name, str, c->c_arena);
+        }
         case dotted_as_name:
             if (NCH(n) == 1) {
                 n = CHILD(n, 0);
                 goto loop;
             }
             else {
-                alias_ty a = alias_for_import_name(c, CHILD(n, 0));
+                node *asname_node = CHILD(n, 2);
+                alias_ty a = alias_for_import_name(c, CHILD(n, 0), store);
                 if (!a)
                     return NULL;
                 assert(!a->asname);
-                a->asname = NEW_IDENTIFIER(CHILD(n, 2));
+                if (store && !forbidden_check(c, asname_node, STR(asname_node)))
+                    return NULL;
+                a->asname = NEW_IDENTIFIER(asname_node);
                 if (!a->asname)
                     return NULL;
                 return a;
@@ -2334,7 +2344,10 @@ alias_for_import_name(struct compiling *c, const node *n)
             break;
         case dotted_name:
             if (NCH(n) == 1) {
-                name = NEW_IDENTIFIER(CHILD(n, 0));
+                node *name_node = CHILD(n, 0);
+                if (store && !forbidden_check(c, name_node, STR(name_node)))
+                    return NULL;
+                name = NEW_IDENTIFIER(name_node);
                 if (!name)
                     return NULL;
                 return alias(name, NULL, c->c_arena);
@@ -2408,7 +2421,7 @@ ast_for_import_stmt(struct compiling *c, const node *n)
         if (!aliases)
             return NULL;
         for (i = 0; i < NCH(n); i += 2) {
-            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1);
             if (!import_alias)
                 return NULL;
             asdl_seq_SET(aliases, i / 2, import_alias);
@@ -2425,7 +2438,9 @@ ast_for_import_stmt(struct compiling *c, const node *n)
           optional module name */
         for (idx = 1; idx < NCH(n); idx++) {
             if (TYPE(CHILD(n, idx)) == dotted_name) {
-                mod = alias_for_import_name(c, CHILD(n, idx));
+                mod = alias_for_import_name(c, CHILD(n, idx), 0);
+                if (!mod)
+                    return NULL;
                 idx++;
                 break;
             } else if (TYPE(CHILD(n, idx)) != DOT) {
@@ -2466,14 +2481,14 @@ ast_for_import_stmt(struct compiling *c, const node *n)
 
         /* handle "from ... import *" special b/c there's no children */
         if (TYPE(n) == STAR) {
-            alias_ty import_alias = alias_for_import_name(c, n);
+            alias_ty import_alias = alias_for_import_name(c, n, 1);
             if (!import_alias)
                 return NULL;
                 asdl_seq_SET(aliases, 0, import_alias);
         }
         else {
             for (i = 0; i < NCH(n); i += 2) {
-                alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
+                alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1);
                 if (!import_alias)
                     return NULL;
                     asdl_seq_SET(aliases, i / 2, import_alias);