mirror of
https://github.com/python/cpython.git
synced 2025-11-01 10:45:30 +00:00
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:
parent
7b7d1c8282
commit
759410b372
3 changed files with 113 additions and 19 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue