/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

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