mirror of https://github.com/python/cpython
Warn about assigning to Py3k keywords (True and False)
This commit is contained in:
parent
cbd78133fa
commit
d5efd20406
|
@ -16,6 +16,55 @@ class TestPy3KWarnings(unittest.TestCase):
|
||||||
exec "`2`" in {}
|
exec "`2`" in {}
|
||||||
self.assertWarning(None, w, expected)
|
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):
|
def test_type_inequality_comparisons(self):
|
||||||
expected = 'type inequality comparisons not supported in 3.x'
|
expected = 'type inequality comparisons not supported in 3.x'
|
||||||
with catch_warning() as w:
|
with catch_warning() as w:
|
||||||
|
|
60
Python/ast.c
60
Python/ast.c
|
@ -126,6 +126,17 @@ ast_warn(struct compiling *c, const node *n, char *msg)
|
||||||
return 1;
|
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.
|
/* num_stmts() returns number of contained statements.
|
||||||
|
|
||||||
Use this routine to determine how big a sequence is needed for
|
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) {
|
switch (e->kind) {
|
||||||
case Attribute_kind:
|
case Attribute_kind:
|
||||||
if (ctx == Store &&
|
if (ctx == Store && !forbidden_check(c, n,
|
||||||
!strcmp(PyBytes_AS_STRING(e->v.Attribute.attr), "None")) {
|
PyBytes_AS_STRING(e->v.Attribute.attr)))
|
||||||
return ast_error(n, "assignment to None");
|
return 0;
|
||||||
}
|
|
||||||
e->v.Attribute.ctx = ctx;
|
e->v.Attribute.ctx = ctx;
|
||||||
break;
|
break;
|
||||||
case Subscript_kind:
|
case Subscript_kind:
|
||||||
e->v.Subscript.ctx = ctx;
|
e->v.Subscript.ctx = ctx;
|
||||||
break;
|
break;
|
||||||
case Name_kind:
|
case Name_kind:
|
||||||
if (ctx == Store &&
|
if (ctx == Store && !forbidden_check(c, n,
|
||||||
!strcmp(PyBytes_AS_STRING(e->v.Name.id), "None")) {
|
PyBytes_AS_STRING(e->v.Name.id)))
|
||||||
return ast_error(n, "assignment to None");
|
return 0;
|
||||||
}
|
|
||||||
e->v.Name.ctx = ctx;
|
e->v.Name.ctx = ctx;
|
||||||
break;
|
break;
|
||||||
case List_kind:
|
case List_kind:
|
||||||
|
@ -595,10 +604,8 @@ set_name:
|
||||||
/* fpdef_node is either a NAME or an fplist */
|
/* fpdef_node is either a NAME or an fplist */
|
||||||
child = CHILD(fpdef_node, 0);
|
child = CHILD(fpdef_node, 0);
|
||||||
if (TYPE(child) == NAME) {
|
if (TYPE(child) == NAME) {
|
||||||
if (!strcmp(STR(child), "None")) {
|
if (!forbidden_check(c, n, STR(child)))
|
||||||
ast_error(child, "assignment to None");
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
|
arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
|
||||||
child->n_col_offset, c->c_arena);
|
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) {
|
if (TYPE(CHILD(ch, 0)) == NAME) {
|
||||||
expr_ty name;
|
expr_ty name;
|
||||||
if (!strcmp(STR(CHILD(ch, 0)), "None")) {
|
if (!forbidden_check(c, n, STR(CHILD(ch, 0))))
|
||||||
ast_error(CHILD(ch, 0), "assignment to None");
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
|
name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
|
||||||
Param, LINENO(ch), ch->n_col_offset,
|
Param, LINENO(ch), ch->n_col_offset,
|
||||||
c->c_arena);
|
c->c_arena);
|
||||||
|
@ -723,18 +728,14 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
i += 2; /* the name and the comma */
|
i += 2; /* the name and the comma */
|
||||||
break;
|
break;
|
||||||
case STAR:
|
case STAR:
|
||||||
if (!strcmp(STR(CHILD(n, i+1)), "None")) {
|
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
|
||||||
ast_error(CHILD(n, i+1), "assignment to None");
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
vararg = NEW_IDENTIFIER(CHILD(n, i+1));
|
vararg = NEW_IDENTIFIER(CHILD(n, i+1));
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
break;
|
||||||
case DOUBLESTAR:
|
case DOUBLESTAR:
|
||||||
if (!strcmp(STR(CHILD(n, i+1)), "None")) {
|
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
|
||||||
ast_error(CHILD(n, i+1), "assignment to None");
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
|
kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
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));
|
name = NEW_IDENTIFIER(CHILD(n, name_i));
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (!strcmp(STR(CHILD(n, name_i)), "None")) {
|
else if (!forbidden_check(c, CHILD(n, name_i), STR(CHILD(n, name_i))))
|
||||||
ast_error(CHILD(n, name_i), "assignment to None");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
args = ast_for_arguments(c, CHILD(n, name_i + 1));
|
args = ast_for_arguments(c, CHILD(n, name_i + 1));
|
||||||
if (!args)
|
if (!args)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1929,10 +1928,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
key = e->v.Name.id;
|
key = e->v.Name.id;
|
||||||
if (!strcmp(PyBytes_AS_STRING(key), "None")) {
|
if (!forbidden_check(c, CHILD(ch, 0), PyBytes_AS_STRING(key)))
|
||||||
ast_error(CHILD(ch, 0), "assignment to None");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
e = ast_for_expr(c, CHILD(ch, 2));
|
e = ast_for_expr(c, CHILD(ch, 2));
|
||||||
if (!e)
|
if (!e)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2059,10 +2056,9 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
|
||||||
return NULL;
|
return NULL;
|
||||||
case Name_kind: {
|
case Name_kind: {
|
||||||
const char *var_name = PyBytes_AS_STRING(expr1->v.Name.id);
|
const char *var_name = PyBytes_AS_STRING(expr1->v.Name.id);
|
||||||
if (var_name[0] == 'N' && !strcmp(var_name, "None")) {
|
if ((var_name[0] == 'N' || var_name[0] == 'T' || var_name[0] == 'F') &&
|
||||||
ast_error(ch, "assignment to None");
|
!forbidden_check(c, ch, var_name))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Attribute_kind:
|
case Attribute_kind:
|
||||||
|
@ -3005,10 +3001,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
||||||
|
|
||||||
REQ(n, classdef);
|
REQ(n, classdef);
|
||||||
|
|
||||||
if (!strcmp(STR(CHILD(n, 1)), "None")) {
|
if (!forbidden_check(c, n, STR(CHILD(n, 1))))
|
||||||
ast_error(n, "assignment to None");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (NCH(n) == 4) {
|
if (NCH(n) == 4) {
|
||||||
s = ast_for_suite(c, CHILD(n, 3));
|
s = ast_for_suite(c, CHILD(n, 3));
|
||||||
|
|
Loading…
Reference in New Issue