Added limited dynamic scoping.

This commit is contained in:
Jeremy Fincher 2004-12-13 19:31:36 +00:00
parent 7d66c9e6a4
commit 41ad8c13ad
2 changed files with 38 additions and 2 deletions

View File

@ -37,7 +37,8 @@ __revision__ = "$Id$"
__all__ = []
exported = ['ignore', 'window', 'group', 'partition', 'any', 'all', 'rsplit']
exported = ['ignore', 'window', 'group', 'partition',
'any', 'all', 'rsplit', 'dynamic']
import sys
import new
@ -67,6 +68,23 @@ def ignore(*args, **kwargs):
"""Simply ignore the arguments sent to it."""
pass
class DynamicScope(object):
def _getLocals(self, name):
f = sys._getframe().f_back.f_back # _getLocals <- __[gs]etattr__ <- ...
while f:
if name in f.f_locals:
return f.f_locals
f = f.f_back
raise NameError, name
def __getattr__(self, name):
return self._getLocals(name)[name]
def __setattr__(self, name, value):
self._getLocals(name)[name] = value
dynamic = DynamicScope()
if sys.version_info < (2, 4, 0):
def reversed(L):
"""Iterates through a sequence in reverse."""
@ -230,7 +248,6 @@ def _replace_original__init__():
atexit.register(_replace_original__init__)
g = globals()
for name in exported:
__builtins__[name] = g[name]

View File

@ -98,4 +98,23 @@ class FunctionsTest(SupyTestCase):
self.assertEqual(rsplit('foobarbaz', 'bar'), ['foo', 'baz'])
class TestDynamic(SupyTestCase):
def test(self):
def f(x):
i = 2
return g(x)
def g(y):
j = 3
return h(y)
def h(z):
self.assertEqual(dynamic.z, z)
self.assertEqual(dynamic.j, 3)
self.assertEqual(dynamic.i, 2)
self.assertEqual(dynamic.y, z)
self.assertEqual(dynamic.x, z)
self.assertRaises(NameError, getattr, dynamic, 'asdfqwerqewr')
self.assertEqual(dynamic.self, self)
return z
self.assertEqual(f(10), 10)
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: