/Lib/test/test_dynamic.py
http://unladen-swallow.googlecode.com/ · Python · 147 lines · 91 code · 33 blank · 23 comment · 7 complexity · f99a4594a393adff7eadfcc988195989 MD5 · raw file
- # Test the most dynamic corner cases of Python's runtime semantics.
- # Import this so we can run this test under Python 2.5 (useful for
- # finding regressions).
- from __future__ import with_statement
- import __builtin__
- import contextlib
- import unittest
- from test.test_support import run_unittest, swap_item, swap_attr
- class RebindBuiltinsTests(unittest.TestCase):
- """Test all the ways that we can change/shadow globals/builtins."""
- def configure_func(self, func, *args):
- """Perform TestCase-specific configuration on a function before testing.
- By default, this does nothing. Example usage: spinning a function so
- that LLVM will optimize it. Subclasses should override this as needed.
- Args:
- func: function to configure.
- *args: any arguments that should be passed to func, if calling it.
- Returns:
- Nothing. Work will be performed on func in-place.
- """
- pass
- def test_globals_shadow_builtins(self):
- # Modify globals() to shadow an entry in builtins.
- def foo():
- return len([1, 2, 3])
- self.configure_func(foo)
- self.assertEqual(foo(), 3)
- with swap_item(globals(), "len", lambda x: 7):
- self.assertEqual(foo(), 7)
- def test_modify_builtins(self):
- # Modify the __builtin__ module directly.
- def foo():
- return len([1, 2, 3])
- self.configure_func(foo)
- self.assertEqual(foo(), 3)
- with swap_attr(__builtin__, "len", lambda x: 7):
- self.assertEqual(foo(), 7)
- def test_modify_builtins_while_generator_active(self):
- # Modify the builtins out from under a live generator.
- def foo():
- x = range(3)
- yield len(x)
- yield len(x)
- self.configure_func(foo)
- g = foo()
- self.assertEqual(g.next(), 3)
- with swap_attr(__builtin__, "len", lambda x: 7):
- self.assertEqual(g.next(), 7)
- def test_modify_builtins_from_leaf_function(self):
- # Verify that modifications made by leaf functions percolate up the
- # callstack.
- with swap_attr(__builtin__, "len", len):
- def bar():
- __builtin__.len = lambda x: 4
- def foo(modifier):
- l = []
- l.append(len(range(7)))
- modifier()
- l.append(len(range(7)))
- return l
- self.configure_func(foo, lambda: None)
- self.assertEqual(foo(bar), [7, 4])
- def test_cannot_change_globals_or_builtins_with_eval(self):
- def foo():
- return len([1, 2, 3])
- self.configure_func(foo)
- # Note that this *doesn't* change the definition of len() seen by foo().
- builtins_dict = {"len": lambda x: 7}
- globals_dict = {"foo": foo, "__builtins__": builtins_dict,
- "len": lambda x: 8}
- self.assertEqual(eval("foo()", globals_dict), 3)
- self.assertEqual(eval("foo()", {"foo": foo}), 3)
- def test_cannot_change_globals_or_builtins_with_exec(self):
- def foo():
- return len([1, 2, 3])
- self.configure_func(foo)
- globals_dict = {"foo": foo}
- exec "x = foo()" in globals_dict
- self.assertEqual(globals_dict["x"], 3)
- # Note that this *doesn't* change the definition of len() seen by foo().
- builtins_dict = {"len": lambda x: 7}
- globals_dict = {"foo": foo, "__builtins__": builtins_dict,
- "len": lambda x: 8}
- exec "x = foo()" in globals_dict
- self.assertEqual(globals_dict["x"], 3)
- def test_cannot_replace_builtins_dict_while_active(self):
- def foo():
- x = range(3)
- yield len(x)
- yield len(x)
- self.configure_func(foo)
- g = foo()
- self.assertEqual(g.next(), 3)
- with swap_item(globals(), "__builtins__", {"len": lambda x: 7}):
- self.assertEqual(g.next(), 3)
- def test_cannot_replace_builtins_dict_between_calls(self):
- def foo():
- return len([1, 2, 3])
- self.configure_func(foo)
- self.assertEqual(foo(), 3)
- with swap_item(globals(), "__builtins__", {"len": lambda x: 7}):
- self.assertEqual(foo(), 3)
- def test_eval_gives_lambda_custom_globals(self):
- globals_dict = {"len": lambda x: 7}
- foo = eval("lambda: len([])", globals_dict)
- self.configure_func(foo)
- self.assertEqual(foo(), 7)
- def test_main():
- run_unittest(RebindBuiltinsTests)
- if __name__ == "__main__":
- test_main()