Index: Python/ast.c =================================================================== --- Python/ast.c (revision 61629) +++ Python/ast.c (working copy) @@ -349,9 +349,17 @@ switch (e->kind) { case Attribute_kind: - if (ctx == Store && - !strcmp(PyString_AS_STRING(e->v.Attribute.attr), "None")) { - return ast_error(n, "assignment to None"); + if (ctx == Store) { + char *attr = PyString_AS_STRING(e->v.Attribute.attr); + if (!strcmp(attr, "None")) { + return ast_error(n, "assignment to None"); + } + if (Py_Py3kWarningFlag && + !(strcmp(attr, "True") && strcmp(attr, "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + return 0; + } } e->v.Attribute.ctx = ctx; break; @@ -359,9 +367,17 @@ e->v.Subscript.ctx = ctx; break; case Name_kind: - if (ctx == Store && - !strcmp(PyString_AS_STRING(e->v.Name.id), "None")) { + if (ctx == Store) { + char *id = PyString_AS_STRING(e->v.Name.id); + if (!strcmp(id, "None")) { return ast_error(n, "assignment to None"); + } + if (Py_Py3kWarningFlag && + !(strcmp(id, "True") && strcmp(id, "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + return 0; + } } e->v.Name.ctx = ctx; break; @@ -583,7 +599,13 @@ if (!strcmp(STR(child), "None")) { ast_error(child, "assignment to None"); return NULL; - } + } + if (Py_Py3kWarningFlag && + !(strcmp(STR(child), "True") && strcmp(STR(child), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + return NULL; + } arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child), child->n_col_offset, c->c_arena); } @@ -697,6 +719,13 @@ ast_error(CHILD(ch, 0), "assignment to None"); goto error; } + if (Py_Py3kWarningFlag && + !(strcmp(STR(CHILD(ch, 0)), "True") && + strcmp(STR(CHILD(ch, 0)), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + goto error; + } name = Name(NEW_IDENTIFIER(CHILD(ch, 0)), Param, LINENO(ch), ch->n_col_offset, c->c_arena); @@ -712,6 +741,13 @@ ast_error(CHILD(n, i+1), "assignment to None"); goto error; } + if (Py_Py3kWarningFlag && + !(strcmp(STR(CHILD(n, i+1)), "True") && + strcmp(STR(CHILD(n, i+1)), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + goto error; + } vararg = NEW_IDENTIFIER(CHILD(n, i+1)); i += 3; break; @@ -720,6 +756,13 @@ ast_error(CHILD(n, i+1), "assignment to None"); goto error; } + if (Py_Py3kWarningFlag && + !(strcmp(STR(CHILD(n, i+1)), "True") && + strcmp(STR(CHILD(n, i+1)), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + goto error; + } kwarg = NEW_IDENTIFIER(CHILD(n, i+1)); i += 3; break; @@ -846,6 +889,13 @@ ast_error(CHILD(n, name_i), "assignment to None"); return NULL; } + else if (Py_Py3kWarningFlag && + !(strcmp(STR(CHILD(n, name_i)), "True") && + strcmp(STR(CHILD(n, name_i)), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + return NULL; + } args = ast_for_arguments(c, CHILD(n, name_i + 1)); if (!args) return NULL; @@ -1923,6 +1973,13 @@ ast_error(CHILD(ch, 0), "assignment to None"); return NULL; } + if (Py_Py3kWarningFlag && + !(strcmp(PyString_AS_STRING(key), "True") && + strcmp(PyString_AS_STRING(key), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + return NULL; + } e = ast_for_expr(c, CHILD(ch, 2)); if (!e) return NULL; @@ -2053,6 +2110,15 @@ ast_error(ch, "assignment to None"); return NULL; } + if (Py_Py3kWarningFlag) { + if (!(strcmp(var_name, "True") && + strcmp(var_name, "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", + 2) < 0) { + return NULL; + } + } break; } case Attribute_kind: @@ -2999,6 +3065,13 @@ ast_error(n, "assignment to None"); return NULL; } + if (Py_Py3kWarningFlag && + !(strcmp(STR(CHILD(n, 1)), "True") && + strcmp(STR(CHILD(n, 1)), "False")) && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Assignment to True or False is forbidden in 3.x.", 2) < 0) { + return NULL; + } if (NCH(n) == 4) { s = ast_for_suite(c, CHILD(n, 3)); Index: Lib/test/test_py3kwarn.py =================================================================== --- Lib/test/test_py3kwarn.py (revision 61629) +++ Lib/test/test_py3kwarn.py (working copy) @@ -8,10 +8,44 @@ with catch_warning() as w: callable(int) if w.message is None: - raise TestSkipped('%s must be run with the -3 flag' % __name__) + raise TestSkipped('%s must be run with the -3 flag' % __name__)\ +def safe_exec(exp): + exec exp in {} + class TestPy3KWarnings(unittest.TestCase): + def test_bool_assign(self): + 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) + def test_type_inequality_comparisons(self): expected = 'type inequality comparisons not supported in 3.x.' with catch_warning() as w: