diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2007-02-26 18:41:18 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2007-02-26 18:41:18 (GMT) |
commit | 759410b372915be0de2a225d7fc6b71dcfae6db3 (patch) | |
tree | e0a670017cde5e0b337ff574deae09daa9ff4c92 /Lib | |
parent | 7b7d1c8282fa2599e2f132c401defde3c9b42e3f (diff) | |
download | cpython-759410b372915be0de2a225d7fc6b71dcfae6db3.zip cpython-759410b372915be0de2a225d7fc6b71dcfae6db3.tar.gz cpython-759410b372915be0de2a225d7fc6b71dcfae6db3.tar.bz2 |
Do not copy free variables to locals in class namespaces.
Fixes bug 1569356, but at the cost of a minor incompatibility in
locals(). Add test that verifies that the class namespace is not
polluted. Also clarify the behavior in the library docs.
Along the way, cleaned up the dict_to_map and map_to_dict
implementations and added some comments that explain what they do.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_scope.py | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py index a53b30f..db88dbd 100644 --- a/Lib/test/test_scope.py +++ b/Lib/test/test_scope.py @@ -486,6 +486,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 |