PageRenderTime 385ms CodeModel.GetById 151ms app.highlight 13ms RepoModel.GetById 108ms app.codeStats 0ms

/Lib/test/test_dynamic.py

http://unladen-swallow.googlecode.com/
Python | 147 lines | 91 code | 33 blank | 23 comment | 3 complexity | f99a4594a393adff7eadfcc988195989 MD5 | raw file
  1# Test the most dynamic corner cases of Python's runtime semantics.
  2
  3# Import this so we can run this test under Python 2.5 (useful for
  4# finding regressions).
  5from __future__ import with_statement
  6
  7import __builtin__
  8import contextlib
  9import unittest
 10
 11from test.test_support import run_unittest, swap_item, swap_attr
 12
 13
 14class RebindBuiltinsTests(unittest.TestCase):
 15
 16    """Test all the ways that we can change/shadow globals/builtins."""
 17
 18    def configure_func(self, func, *args):
 19        """Perform TestCase-specific configuration on a function before testing.
 20
 21        By default, this does nothing. Example usage: spinning a function so
 22        that LLVM will optimize it. Subclasses should override this as needed.
 23
 24        Args:
 25            func: function to configure.
 26            *args: any arguments that should be passed to func, if calling it.
 27
 28        Returns:
 29            Nothing. Work will be performed on func in-place.
 30        """
 31        pass
 32
 33    def test_globals_shadow_builtins(self):
 34        # Modify globals() to shadow an entry in builtins.
 35        def foo():
 36            return len([1, 2, 3])
 37        self.configure_func(foo)
 38
 39        self.assertEqual(foo(), 3)
 40        with swap_item(globals(), "len", lambda x: 7):
 41            self.assertEqual(foo(), 7)
 42
 43    def test_modify_builtins(self):
 44        # Modify the __builtin__ module directly.
 45        def foo():
 46            return len([1, 2, 3])
 47        self.configure_func(foo)
 48
 49        self.assertEqual(foo(), 3)
 50        with swap_attr(__builtin__, "len", lambda x: 7):
 51            self.assertEqual(foo(), 7)
 52
 53    def test_modify_builtins_while_generator_active(self):
 54        # Modify the builtins out from under a live generator.
 55        def foo():
 56            x = range(3)
 57            yield len(x)
 58            yield len(x)
 59        self.configure_func(foo)
 60
 61        g = foo()
 62        self.assertEqual(g.next(), 3)
 63        with swap_attr(__builtin__, "len", lambda x: 7):
 64            self.assertEqual(g.next(), 7)
 65
 66    def test_modify_builtins_from_leaf_function(self):
 67        # Verify that modifications made by leaf functions percolate up the
 68        # callstack.
 69        with swap_attr(__builtin__, "len", len):
 70            def bar():
 71                __builtin__.len = lambda x: 4
 72
 73            def foo(modifier):
 74                l = []
 75                l.append(len(range(7)))
 76                modifier()
 77                l.append(len(range(7)))
 78                return l
 79            self.configure_func(foo, lambda: None)
 80
 81            self.assertEqual(foo(bar), [7, 4])
 82
 83    def test_cannot_change_globals_or_builtins_with_eval(self):
 84        def foo():
 85            return len([1, 2, 3])
 86        self.configure_func(foo)
 87
 88        # Note that this *doesn't* change the definition of len() seen by foo().
 89        builtins_dict = {"len": lambda x: 7}
 90        globals_dict = {"foo": foo, "__builtins__": builtins_dict,
 91                        "len": lambda x: 8}
 92        self.assertEqual(eval("foo()", globals_dict), 3)
 93
 94        self.assertEqual(eval("foo()", {"foo": foo}), 3)
 95
 96    def test_cannot_change_globals_or_builtins_with_exec(self):
 97        def foo():
 98            return len([1, 2, 3])
 99        self.configure_func(foo)
100
101        globals_dict = {"foo": foo}
102        exec "x = foo()" in globals_dict
103        self.assertEqual(globals_dict["x"], 3)
104
105        # Note that this *doesn't* change the definition of len() seen by foo().
106        builtins_dict = {"len": lambda x: 7}
107        globals_dict = {"foo": foo, "__builtins__": builtins_dict,
108                        "len": lambda x: 8}
109
110        exec "x = foo()" in globals_dict
111        self.assertEqual(globals_dict["x"], 3)
112
113    def test_cannot_replace_builtins_dict_while_active(self):
114        def foo():
115            x = range(3)
116            yield len(x)
117            yield len(x)
118        self.configure_func(foo)
119
120        g = foo()
121        self.assertEqual(g.next(), 3)
122        with swap_item(globals(), "__builtins__", {"len": lambda x: 7}):
123            self.assertEqual(g.next(), 3)
124
125    def test_cannot_replace_builtins_dict_between_calls(self):
126        def foo():
127            return len([1, 2, 3])
128        self.configure_func(foo)
129
130        self.assertEqual(foo(), 3)
131        with swap_item(globals(), "__builtins__", {"len": lambda x: 7}):
132            self.assertEqual(foo(), 3)
133
134    def test_eval_gives_lambda_custom_globals(self):
135        globals_dict = {"len": lambda x: 7}
136        foo = eval("lambda: len([])", globals_dict)
137        self.configure_func(foo)
138
139        self.assertEqual(foo(), 7)
140
141
142def test_main():
143    run_unittest(RebindBuiltinsTests)
144
145
146if __name__ == "__main__":
147    test_main()