From 399b1fe8dff3be012a49390cf971f850cf4f41aa Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 25 Oct 2008 02:53:28 +0000 Subject: give a py3k warning when 'nonlocal' is used as a variable name --- Lib/test/test_py3kwarn.py | 64 +++++++++++++++++------------------------------ Misc/NEWS | 3 +++ Python/ast.c | 11 +++++--- 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/Lib/test/test_py3kwarn.py b/Lib/test/test_py3kwarn.py index 0afa8e7..c695daa 100644 --- a/Lib/test/test_py3kwarn.py +++ b/Lib/test/test_py3kwarn.py @@ -28,53 +28,35 @@ class TestPy3KWarnings(unittest.TestCase): exec "`2`" in {} self.assertWarning(None, w, expected) - def test_bool_assign(self): + def test_forbidden_names(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" + tests = [("True", "assignment to True or False is forbidden in 3.x"), + ("False", "assignment to True or False is forbidden in 3.x"), + ("nonlocal", "nonlocal is a keyword in 3.x")] with check_warnings() as w: - safe_exec("True = False") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("False = True") - self.assertWarning(None, w, expected) - w.reset() - try: - safe_exec("obj.False = True") - except NameError: pass - self.assertWarning(None, w, expected) - w.reset() - try: - safe_exec("obj.True = False") - except NameError: pass - self.assertWarning(None, w, expected) - w.reset() - safe_exec("def False(): pass") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("def True(): pass") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("class False: pass") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("class True: pass") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("def f(True=43): pass") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("def f(False=None): pass") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("f(False=True)") - self.assertWarning(None, w, expected) - w.reset() - safe_exec("f(True=1)") - self.assertWarning(None, w, expected) + for keyword, expected in tests: + safe_exec("{0} = False".format(keyword)) + self.assertWarning(None, w, expected) + w.reset() + try: + safe_exec("obj.{0} = True".format(keyword)) + except NameError: + pass + self.assertWarning(None, w, expected) + w.reset() + safe_exec("def {0}(): pass".format(keyword)) + self.assertWarning(None, w, expected) + w.reset() + safe_exec("class {0}: pass".format(keyword)) + self.assertWarning(None, w, expected) + w.reset() + safe_exec("def f({0}=43): pass".format(keyword)) + self.assertWarning(None, w, expected) + w.reset() def test_type_inequality_comparisons(self): diff --git a/Misc/NEWS b/Misc/NEWS index 0e726ea..dd5dffe 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1 Core and Builtins ----------------- +- Using ``nonlocal`` as a variable name will now raise a Py3k SyntaxWarning + because it is a reserved work in 3.x. + - On windows, os.chdir given unicode was not working if GetCurrentDirectoryW returned a path longer than MAX_PATH. (But It's doubtful this code path is really executed because I cannot move to such directory on win2k) diff --git a/Python/ast.c b/Python/ast.c index 8414c74..29b0e82 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -131,9 +131,14 @@ 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; + if (Py_Py3kWarningFlag) { + if (!(strcmp(x, "True") && strcmp(x, "False")) && + !ast_warn(c, n, "assignment to True or False is forbidden in 3.x")) + return 0; + if (!strcmp(x, "nonlocal") && + !ast_warn(c, n, "nonlocal is a keyword in 3.x")) + return 0; + } return 1; } -- cgit v0.12