14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""This module includes tests of the code object representation.
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> def f(x):
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     def g(y):
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...         return x + y
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     return g
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> dump(f.func_code)
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoname: f
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoargcount: 1
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonames: ()
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaovarnames: ('x', 'g')
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaocellvars: ('x',)
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofreevars: ()
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonlocals: 2
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoflags: 3
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoconsts: ('None', '<code object g>')
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> dump(f(4).func_code)
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoname: g
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoargcount: 1
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonames: ()
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaovarnames: ('y',)
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaocellvars: ()
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofreevars: ('x',)
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonlocals: 1
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoflags: 19
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoconsts: ('None',)
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> def h(x, y):
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     a = x + y
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     b = x - y
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     c = a * b
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     return c
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> dump(h.func_code)
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoname: h
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoargcount: 2
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonames: ()
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaovarnames: ('x', 'y', 'a', 'b', 'c')
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaocellvars: ()
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofreevars: ()
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonlocals: 5
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoflags: 67
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoconsts: ('None',)
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> def attrs(obj):
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     print obj.attr1
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     print obj.attr2
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     print obj.attr3
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> dump(attrs.func_code)
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoname: attrs
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoargcount: 1
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonames: ('attr1', 'attr2', 'attr3')
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaovarnames: ('obj',)
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaocellvars: ()
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofreevars: ()
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonlocals: 1
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoflags: 67
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoconsts: ('None',)
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> def optimize_away():
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     'doc string'
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     'not a docstring'
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     53
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao...     53L
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao>>> dump(optimize_away.func_code)
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoname: optimize_away
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoargcount: 0
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonames: ()
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaovarnames: ()
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaocellvars: ()
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofreevars: ()
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonlocals: 0
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoflags: 67
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoconsts: ("'doc string'", 'None')
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport weakref
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport _testcapi
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef consts(t):
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Yield a doctest-safe sequence of object reprs."""
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for elt in t:
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        r = repr(elt)
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if r.startswith("<code object"):
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            yield "<code object %s>" % elt.co_name
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            yield r
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef dump(co):
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Print out a text representation of a code object."""
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for attr in ["name", "argcount", "names", "varnames", "cellvars",
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                 "freevars", "nlocals", "flags"]:
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        print "%s: %s" % (attr, getattr(co, "co_" + attr))
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print "consts:", tuple(consts(co.co_consts))
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass CodeTest(unittest.TestCase):
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_newempty(self):
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        co = _testcapi.code_newempty("filename", "funcname", 15)
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(co.co_filename, "filename")
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(co.co_name, "funcname")
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(co.co_firstlineno, 15)
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass CodeWeakRefTest(unittest.TestCase):
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_basic(self):
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Create a code object in a clean environment so that we know we have
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # the only reference to it left.
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        namespace = {}
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        exec "def f(): pass" in globals(), namespace
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = namespace["f"]
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        del namespace
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.called = False
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def callback(code):
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.called = True
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # f is now the last reference to the function, and through it, the code
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # object.  While we hold it, check that we can create a weakref and
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # deref it.  Then delete it, and check that the callback gets called and
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # the reference dies.
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        coderef = weakref.ref(f.__code__, callback)
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(bool(coderef()))
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        del f
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertFalse(bool(coderef()))
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(self.called)
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main(verbose=None):
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from test.test_support import run_doctest, run_unittest
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from test import test_code
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_doctest(test_code, verbose)
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_unittest(CodeTest, CodeWeakRefTest)
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == "__main__":
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    test_main()
148