]> granicus.if.org Git - python/commitdiff
Warn about assigning to Py3k keywords (True and False)
authorBenjamin Peterson <benjamin@python.org>
Sun, 8 Jun 2008 22:52:37 +0000 (22:52 +0000)
committerBenjamin Peterson <benjamin@python.org>
Sun, 8 Jun 2008 22:52:37 +0000 (22:52 +0000)
Lib/test/test_py3kwarn.py
Python/ast.c

index 617d996f218b3f050979ec4cc3fffb39824c64b2..18298fef3d1bf0ab6b06989cd7863cc5c89b5786 100644 (file)
@@ -16,6 +16,55 @@ class TestPy3KWarnings(unittest.TestCase):
             exec "`2`" in {}
         self.assertWarning(None, w, expected)
 
+    def test_bool_assign(self):
+        # So we don't screw up our globals
+        def safe_exec(expr):
+            def f(**kwargs): pass
+            exec expr in {'f' : f}
+
+        expected = "assignment to True or False is forbidden in 3.x"
+        with catch_warning() as w:
+            safe_exec("True = False")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("False = True")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            try:
+                safe_exec("obj.False = True")
+            except NameError: pass
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            try:
+                safe_exec("obj.True = False")
+            except NameError: pass
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("def False(): pass")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("def True(): pass")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("class False: pass")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("class True: pass")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("def f(True=43): pass")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("def f(False=None): pass")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("f(False=True)")
+            self.assertWarning(None, w, expected)
+        with catch_warning() as w:
+            safe_exec("f(True=1)")
+            self.assertWarning(None, w, expected)
+
+
     def test_type_inequality_comparisons(self):
         expected = 'type inequality comparisons not supported in 3.x'
         with catch_warning() as w:
index ad78840c056ecd0cb55ffda104e684898991129a..ab166e816ab8306dcf60c4f530ab6460d1c3595b 100644 (file)
@@ -126,6 +126,17 @@ ast_warn(struct compiling *c, const node *n, char *msg)
     return 1;
 }
 
+static int
+forbidden_check(struct compiling *c, const node *n, const char *x)
+{
+    if (!strcmp(x, "None"))
+        return ast_error(n, "assignment to None");
+    if (Py_Py3kWarningFlag && !(strcmp(x, "True") && strcmp(x, "False")) &&
+        !ast_warn(c, n, "assignment to True or False is forbidden in 3.x"))
+        return 0;
+    return 1;
+}
+
 /* num_stmts() returns number of contained statements.
 
    Use this routine to determine how big a sequence is needed for
@@ -364,20 +375,18 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
 
     switch (e->kind) {
         case Attribute_kind:
-            if (ctx == Store &&
-                !strcmp(PyBytes_AS_STRING(e->v.Attribute.attr), "None")) {
-                return ast_error(n, "assignment to None");
-            }
+            if (ctx == Store && !forbidden_check(c, n,
+                                PyBytes_AS_STRING(e->v.Attribute.attr)))
+                    return 0;
             e->v.Attribute.ctx = ctx;
             break;
         case Subscript_kind:
             e->v.Subscript.ctx = ctx;
             break;
         case Name_kind:
-            if (ctx == Store &&
-                !strcmp(PyBytes_AS_STRING(e->v.Name.id), "None")) {
-                    return ast_error(n, "assignment to None");
-            }
+            if (ctx == Store && !forbidden_check(c, n,
+                                PyBytes_AS_STRING(e->v.Name.id)))
+                    return 0;
             e->v.Name.ctx = ctx;
             break;
         case List_kind:
@@ -595,10 +604,8 @@ set_name:
         /* fpdef_node is either a NAME or an fplist */
         child = CHILD(fpdef_node, 0);
         if (TYPE(child) == NAME) {
-            if (!strcmp(STR(child), "None")) {
-                ast_error(child, "assignment to None");
-                return NULL;
-            }   
+            if (!forbidden_check(c, n, STR(child)))
+                return NULL;  
             arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
                        child->n_col_offset, c->c_arena);
         }
@@ -708,10 +715,8 @@ ast_for_arguments(struct compiling *c, const node *n)
                 }
                 if (TYPE(CHILD(ch, 0)) == NAME) {
                     expr_ty name;
-                    if (!strcmp(STR(CHILD(ch, 0)), "None")) {
-                        ast_error(CHILD(ch, 0), "assignment to None");
+                    if (!forbidden_check(c, n, STR(CHILD(ch, 0))))
                         goto error;
-                    }
                     name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
                                 Param, LINENO(ch), ch->n_col_offset,
                                 c->c_arena);
@@ -723,18 +728,14 @@ ast_for_arguments(struct compiling *c, const node *n)
                 i += 2; /* the name and the comma */
                 break;
             case STAR:
-                if (!strcmp(STR(CHILD(n, i+1)), "None")) {
-                    ast_error(CHILD(n, i+1), "assignment to None");
+                if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
                     goto error;
-                }
                 vararg = NEW_IDENTIFIER(CHILD(n, i+1));
                 i += 3;
                 break;
             case DOUBLESTAR:
-                if (!strcmp(STR(CHILD(n, i+1)), "None")) {
-                    ast_error(CHILD(n, i+1), "assignment to None");
+                if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
                     goto error;
-                }
                 kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
                 i += 3;
                 break;
@@ -857,10 +858,8 @@ ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
     name = NEW_IDENTIFIER(CHILD(n, name_i));
     if (!name)
         return NULL;
-    else if (!strcmp(STR(CHILD(n, name_i)), "None")) {
-        ast_error(CHILD(n, name_i), "assignment to None");
+    else if (!forbidden_check(c, CHILD(n, name_i), STR(CHILD(n, name_i))))
         return NULL;
-    }
     args = ast_for_arguments(c, CHILD(n, name_i + 1));
     if (!args)
         return NULL;
@@ -1929,10 +1928,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
                     return NULL;
                 }
                 key = e->v.Name.id;
-                if (!strcmp(PyBytes_AS_STRING(key), "None")) {
-                    ast_error(CHILD(ch, 0), "assignment to None");
+                if (!forbidden_check(c, CHILD(ch, 0), PyBytes_AS_STRING(key)))
                     return NULL;
-                }
                 e = ast_for_expr(c, CHILD(ch, 2));
                 if (!e)
                     return NULL;
@@ -2059,10 +2056,9 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
                 return NULL;
             case Name_kind: {
                 const char *var_name = PyBytes_AS_STRING(expr1->v.Name.id);
-                if (var_name[0] == 'N' && !strcmp(var_name, "None")) {
-                    ast_error(ch, "assignment to None");
+                if ((var_name[0] == 'N' || var_name[0] == 'T' || var_name[0] == 'F') &&
+                    !forbidden_check(c, ch, var_name))
                     return NULL;
-                }
                 break;
             }
             case Attribute_kind:
@@ -3005,10 +3001,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
     
     REQ(n, classdef);
 
-    if (!strcmp(STR(CHILD(n, 1)), "None")) {
-            ast_error(n, "assignment to None");
+    if (!forbidden_check(c, n, STR(CHILD(n, 1))))
             return NULL;
-    }
 
     if (NCH(n) == 4) {
         s = ast_for_suite(c, CHILD(n, 3));