diff --git a/src/fix.py b/src/fix.py index e8288bae6..6cfdd0d44 100644 --- a/src/fix.py +++ b/src/fix.py @@ -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] diff --git a/test/test_fix.py b/test/test_fix.py index f11f9a8be..81b6252f5 100644 --- a/test/test_fix.py +++ b/test/test_fix.py @@ -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: