import inspect import sys import unittest def save_locals(frame): import ctypes ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), ctypes.c_int(0)) #Comment this one to see it working def save_locals(frame): pass def use_save_locals(name, value): """ Attempt to set the local of the given name to value, using locals_to_fast. """ frame = inspect.currentframe().f_back locals_dict = frame.f_locals locals_dict[name] = value save_locals(frame) def test_method(fn): """ A harness for testing methods that attempt to modify the values of locals on the stack. """ x = 1 # The method 'fn' should attempt to set x = 2 in the current frame. fn('x', 2) return x class TestSetLocals(unittest.TestCase): """ Test setting locals in one function from another function using several approaches. """ def test_set_locals_using_save_locals(self): x = test_method(use_save_locals) self.assertEqual(x, 2) # Expected to succeed def test_frame_simple_change(self): frame = sys._getframe() a = 20 frame.f_locals['a'] = 50 save_locals(frame) self.assertEquals(50, a) def test_frame_co_freevars(self): outer_var = 20 def func(): frame = sys._getframe() frame.f_locals['outer_var'] = 50 save_locals(frame) self.assertEquals(50, outer_var) func() def test_frame_co_cellvars(self): def check_co_vars(a): frame = sys._getframe() def function2(): print a assert 'a' in frame.f_code.co_cellvars frame = sys._getframe() frame.f_locals['a'] = 50 save_locals(frame) self.assertEquals(50, a) check_co_vars(1) def test_frame_change_in_inner_frame(self): def change(f): self.assert_(f is not sys._getframe()) f.f_locals['a'] = 50 save_locals(f) frame = sys._getframe() a = 20 change(frame) self.assertEquals(50, a) if __name__ == '__main__': unittest.main()