summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_scope.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_scope.py')
-rw-r--r--Lib/test/test_scope.py35
1 files changed, 34 insertions, 1 deletions
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py
index f52ab91..f5c1462 100644
--- a/Lib/test/test_scope.py
+++ b/Lib/test/test_scope.py
@@ -477,6 +477,39 @@ self.assert_(X.passed)
del d['h']
self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6})
+ def testLocalsClass(self):
+ # This test verifies that calling locals() does not pollute
+ # the local namespace of the class with free variables. Old
+ # versions of Python had a bug, where a free variable being
+ # passed through a class namespace would be inserted into
+ # locals() by locals() or exec or a trace function.
+ #
+ # The real bug lies in frame code that copies variables
+ # between fast locals and the locals dict, e.g. when executing
+ # a trace function.
+
+ def f(x):
+ class C:
+ x = 12
+ def m(self):
+ return x
+ locals()
+ return C
+
+ self.assertEqual(f(1).x, 12)
+
+ def f(x):
+ class C:
+ y = x
+ def m(self):
+ return x
+ z = list(locals())
+ return C
+
+ varnames = f(1).z
+ self.assert_("x" not in varnames)
+ self.assert_("y" in varnames)
+
def testBoundAndFree(self):
# var is bound and free in class
@@ -607,7 +640,7 @@ self.assert_(X.passed)
c = f(0)
self.assertEqual(c.get(), 1)
self.assert_("x" not in c.__class__.__dict__)
-
+
def testNonLocalGenerator(self):