diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_scope.py | 84 | ||||
-rw-r--r-- | Lib/test/test_syntax.py | 40 |
2 files changed, 124 insertions, 0 deletions
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py index b9dc711..5fe1bc7 100644 --- a/Lib/test/test_scope.py +++ b/Lib/test/test_scope.py @@ -555,6 +555,90 @@ self.assert_(X.passed) f(4)() + def testNonLocalFunction(self): + + def f(x): + def inc(): + nonlocal x + x += 1 + return x + def dec(): + nonlocal x + x -= 1 + return x + return inc, dec + + inc, dec = f(0) + self.assertEqual(inc(), 1) + self.assertEqual(inc(), 2) + self.assertEqual(dec(), 1) + self.assertEqual(dec(), 0) + + def testNonLocalMethod(self): + + def f(x): + class c: + def inc(self): + nonlocal x + x += 1 + return x + def dec(self): + nonlocal x + x -= 1 + return x + return c() + + c = f(0) + self.assertEqual(c.inc(), 1) + self.assertEqual(c.inc(), 2) + self.assertEqual(c.dec(), 1) + self.assertEqual(c.dec(), 0) + + def testNonLocalClass(self): + + def f(x): + class c: + nonlocal x + x += 1 + def get(self): + return x + return c() + + c = f(0) + self.assertEqual(c.get(), 1) + self.assert_("x" not in c.__class__.__dict__) + + + def testNonLocalGenerator(self): + + def f(x): + def g(y): + nonlocal x + for i in range(y): + x += 1 + yield x + return g + + g = f(0) + self.assertEqual(list(g(5)), [1, 2, 3, 4, 5]) + + def testNestedNonLocal(self): + + def f(x): + def g(): + nonlocal x + x -= 2 + def h(): + nonlocal x + x += 4 + return x + return h + return g + + g = f(1) + h = g() + self.assertEqual(h(), 3) + def test_main(): run_unittest(ScopeTests) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 8999e3a..f37b666 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -367,6 +367,46 @@ build. The number of blocks must be greater than CO_MAXBLOCKS. SF #1565514 ... SystemError: too many statically nested blocks +Misuse of the nonlocal statement can lead to a few unique syntax errors. + + >>> def f(x): + ... nonlocal x + Traceback (most recent call last): + ... + SyntaxError: name 'x' is local and nonlocal + + >>> def f(): + ... global x + ... nonlocal x + Traceback (most recent call last): + ... + SyntaxError: name 'x' is nonlocal and global + + >>> def f(): + ... nonlocal x + Traceback (most recent call last): + ... + SyntaxError: no binding for nonlocal 'x' found + +TODO(jhylton): Figure out how to test SyntaxWarning with doctest. + +## >>> def f(x): +## ... def f(): +## ... print(x) +## ... nonlocal x +## Traceback (most recent call last): +## ... +## SyntaxWarning: name 'x' is assigned to before nonlocal declaration + +## >>> def f(): +## ... x = 1 +## ... nonlocal x +## Traceback (most recent call last): +## ... +## SyntaxWarning: name 'x' is assigned to before nonlocal declaration + + + """ import re |