test_code.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. """This module includes tests of the code object representation.
  2. >>> def f(x):
  3. ... def g(y):
  4. ... return x + y
  5. ... return g
  6. ...
  7. >>> dump(f.func_code)
  8. name: f
  9. argcount: 1
  10. names: ()
  11. varnames: ('x', 'g')
  12. cellvars: ('x',)
  13. freevars: ()
  14. nlocals: 2
  15. flags: 3
  16. consts: ('None', '<code object g>')
  17. >>> dump(f(4).func_code)
  18. name: g
  19. argcount: 1
  20. names: ()
  21. varnames: ('y',)
  22. cellvars: ()
  23. freevars: ('x',)
  24. nlocals: 1
  25. flags: 19
  26. consts: ('None',)
  27. >>> def h(x, y):
  28. ... a = x + y
  29. ... b = x - y
  30. ... c = a * b
  31. ... return c
  32. ...
  33. >>> dump(h.func_code)
  34. name: h
  35. argcount: 2
  36. names: ()
  37. varnames: ('x', 'y', 'a', 'b', 'c')
  38. cellvars: ()
  39. freevars: ()
  40. nlocals: 5
  41. flags: 67
  42. consts: ('None',)
  43. >>> def attrs(obj):
  44. ... print obj.attr1
  45. ... print obj.attr2
  46. ... print obj.attr3
  47. >>> dump(attrs.func_code)
  48. name: attrs
  49. argcount: 1
  50. names: ('attr1', 'attr2', 'attr3')
  51. varnames: ('obj',)
  52. cellvars: ()
  53. freevars: ()
  54. nlocals: 1
  55. flags: 67
  56. consts: ('None',)
  57. >>> def optimize_away():
  58. ... 'doc string'
  59. ... 'not a docstring'
  60. ... 53
  61. ... 53L
  62. >>> dump(optimize_away.func_code)
  63. name: optimize_away
  64. argcount: 0
  65. names: ()
  66. varnames: ()
  67. cellvars: ()
  68. freevars: ()
  69. nlocals: 0
  70. flags: 67
  71. consts: ("'doc string'", 'None')
  72. """
  73. import unittest
  74. import weakref
  75. from test.test_support import run_doctest, run_unittest, cpython_only
  76. def consts(t):
  77. """Yield a doctest-safe sequence of object reprs."""
  78. for elt in t:
  79. r = repr(elt)
  80. if r.startswith("<code object"):
  81. yield "<code object %s>" % elt.co_name
  82. else:
  83. yield r
  84. def dump(co):
  85. """Print out a text representation of a code object."""
  86. for attr in ["name", "argcount", "names", "varnames", "cellvars",
  87. "freevars", "nlocals", "flags"]:
  88. print "%s: %s" % (attr, getattr(co, "co_" + attr))
  89. print "consts:", tuple(consts(co.co_consts))
  90. class CodeTest(unittest.TestCase):
  91. @cpython_only
  92. def test_newempty(self):
  93. import _testcapi
  94. co = _testcapi.code_newempty("filename", "funcname", 15)
  95. self.assertEqual(co.co_filename, "filename")
  96. self.assertEqual(co.co_name, "funcname")
  97. self.assertEqual(co.co_firstlineno, 15)
  98. class CodeWeakRefTest(unittest.TestCase):
  99. def test_basic(self):
  100. # Create a code object in a clean environment so that we know we have
  101. # the only reference to it left.
  102. namespace = {}
  103. exec "def f(): pass" in globals(), namespace
  104. f = namespace["f"]
  105. del namespace
  106. self.called = False
  107. def callback(code):
  108. self.called = True
  109. # f is now the last reference to the function, and through it, the code
  110. # object. While we hold it, check that we can create a weakref and
  111. # deref it. Then delete it, and check that the callback gets called and
  112. # the reference dies.
  113. coderef = weakref.ref(f.__code__, callback)
  114. self.assertTrue(bool(coderef()))
  115. del f
  116. self.assertFalse(bool(coderef()))
  117. self.assertTrue(self.called)
  118. def test_main(verbose=None):
  119. from test import test_code
  120. run_doctest(test_code, verbose)
  121. run_unittest(CodeTest, CodeWeakRefTest)
  122. if __name__ == "__main__":
  123. test_main()