/Lib/test/test_dis.py

http://unladen-swallow.googlecode.com/ · Python · 153 lines · 123 code · 24 blank · 6 comment · 8 complexity · 44ef5c06fbb78ddeed50655d9bc71376 MD5 · raw file

  1. # Minimal tests for dis module
  2. from test.test_support import run_unittest
  3. import unittest
  4. import sys
  5. import dis
  6. import StringIO
  7. def _f(a):
  8. print a
  9. return 1
  10. dis_f = """\
  11. %-4d 0 LOAD_GLOBAL 0 (#@print_stmt)
  12. 3 LOAD_FAST 0 (a)
  13. 6 CALL_FUNCTION 1
  14. 9 POP_TOP
  15. %-4d 10 LOAD_CONST 1 (1)
  16. 13 RETURN_VALUE
  17. """%(_f.func_code.co_firstlineno + 1,
  18. _f.func_code.co_firstlineno + 2)
  19. def bug708901():
  20. for res in range(1,
  21. 10):
  22. pass
  23. dis_bug708901 = """\
  24. %-4d 0 LOAD_GLOBAL 0 (range)
  25. 3 LOAD_CONST 1 (1)
  26. %-4d 6 LOAD_CONST 2 (10)
  27. 9 CALL_FUNCTION 2
  28. 12 GET_ITER
  29. >> 13 FOR_ITER 6 (to 22)
  30. 16 STORE_FAST 0 (res)
  31. %-4d 19 JUMP_ABSOLUTE 13
  32. >> 22 LOAD_CONST 0 (None)
  33. 25 RETURN_VALUE
  34. """%(bug708901.func_code.co_firstlineno + 1,
  35. bug708901.func_code.co_firstlineno + 2,
  36. bug708901.func_code.co_firstlineno + 3)
  37. def bug1333982(x=[]):
  38. assert 0, ([s for s in x] +
  39. 1)
  40. pass
  41. dis_bug1333982 = """\
  42. %-4d 0 LOAD_CONST 1 (0)
  43. 3 POP_JUMP_IF_TRUE 44
  44. 6 LOAD_GLOBAL 0 (AssertionError)
  45. 9 BUILD_LIST 0
  46. 12 DUP_TOP
  47. 13 STORE_FAST 1 (_[1])
  48. 16 LOAD_FAST 0 (x)
  49. 19 GET_ITER
  50. >> 20 FOR_ITER 13 (to 36)
  51. 23 STORE_FAST 2 (s)
  52. 26 LOAD_FAST 1 (_[1])
  53. 29 LOAD_FAST 2 (s)
  54. 32 LIST_APPEND
  55. 33 JUMP_ABSOLUTE 20
  56. >> 36 DELETE_FAST 1 (_[1])
  57. %-4d 39 LOAD_CONST 2 (1)
  58. 42 BINARY_ADD
  59. 43 RAISE_VARARGS_TWO
  60. %-4d >> 44 LOAD_CONST 0 (None)
  61. 47 RETURN_VALUE
  62. """%(bug1333982.func_code.co_firstlineno + 1,
  63. bug1333982.func_code.co_firstlineno + 2,
  64. bug1333982.func_code.co_firstlineno + 3)
  65. _BIG_LINENO_FORMAT = """\
  66. %3d 0 LOAD_GLOBAL 0 (spam)
  67. 3 POP_TOP
  68. 4 LOAD_CONST 0 (None)
  69. 7 RETURN_VALUE
  70. """
  71. class DisTests(unittest.TestCase):
  72. def do_disassembly_test(self, func, expected):
  73. s = StringIO.StringIO()
  74. save_stdout = sys.stdout
  75. sys.stdout = s
  76. dis.dis(func)
  77. sys.stdout = save_stdout
  78. got = s.getvalue()
  79. # Trim trailing blanks (if any).
  80. lines = got.split('\n')
  81. lines = [line.rstrip() for line in lines]
  82. expected = expected.split("\n")
  83. import difflib
  84. if expected != lines:
  85. self.fail(
  86. "events did not match expectation:\n" +
  87. "\n".join(difflib.ndiff(expected,
  88. lines)))
  89. def test_opmap(self):
  90. self.assertEqual(dis.opmap["STOP_CODE"], 0)
  91. self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
  92. self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
  93. def test_opname(self):
  94. self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
  95. def test_boundaries(self):
  96. self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
  97. self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
  98. def test_dis(self):
  99. self.do_disassembly_test(_f, dis_f)
  100. def test_bug_708901(self):
  101. self.do_disassembly_test(bug708901, dis_bug708901)
  102. def test_bug_1333982(self):
  103. # This one is checking bytecodes generated for an `assert` statement,
  104. # so fails if the tests are run with -O. Skip this test then.
  105. if __debug__:
  106. self.do_disassembly_test(bug1333982, dis_bug1333982)
  107. def test_big_linenos(self):
  108. def func(count):
  109. namespace = {}
  110. func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
  111. exec func in namespace
  112. return namespace['foo']
  113. # Test all small ranges
  114. for i in xrange(1, 300):
  115. expected = _BIG_LINENO_FORMAT % (i + 2)
  116. self.do_disassembly_test(func(i), expected)
  117. # Test some larger ranges too
  118. for i in xrange(300, 5000, 10):
  119. expected = _BIG_LINENO_FORMAT % (i + 2)
  120. self.do_disassembly_test(func(i), expected)
  121. def test_main():
  122. run_unittest(DisTests)
  123. if __name__ == "__main__":
  124. test_main()