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.
This commit is contained in:
Jeremy Hylton 2007-02-26 18:41:18 +00:00
parent 7b7d1c8282
commit 759410b372
3 changed files with 113 additions and 19 deletions

View file

@ -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