blob: 2cf088ce3ca93bcd0cdcd68f937c32b1e3cf32e8 [file] [log] [blame]
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00001"""This module includes tests of the code object representation.
2
3>>> def f(x):
4... def g(y):
5... return x + y
6... return g
7...
8
Neal Norwitz221085d2007-02-25 20:55:47 +00009>>> dump(f.__code__)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000010name: f
11argcount: 1
Guido van Rossum4f72a782006-10-27 23:31:49 +000012kwonlyargcount: 0
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000013names: ()
14varnames: ('x', 'g')
15cellvars: ('x',)
16freevars: ()
17nlocals: 2
18flags: 3
Antoine Pitrou86a36b52011-11-25 18:56:07 +010019consts: ('None', '<code object g>', "'f.<locals>.g'")
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000020
Neal Norwitz221085d2007-02-25 20:55:47 +000021>>> dump(f(4).__code__)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000022name: g
23argcount: 1
Guido van Rossum4f72a782006-10-27 23:31:49 +000024kwonlyargcount: 0
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000025names: ()
26varnames: ('y',)
27cellvars: ()
28freevars: ('x',)
29nlocals: 1
30flags: 19
31consts: ('None',)
32
33>>> def h(x, y):
34... a = x + y
35... b = x - y
36... c = a * b
37... return c
Tim Peters536cf992005-12-25 23:18:31 +000038...
Guido van Rossum4f72a782006-10-27 23:31:49 +000039
Neal Norwitz221085d2007-02-25 20:55:47 +000040>>> dump(h.__code__)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000041name: h
42argcount: 2
Guido van Rossum4f72a782006-10-27 23:31:49 +000043kwonlyargcount: 0
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000044names: ()
45varnames: ('x', 'y', 'a', 'b', 'c')
46cellvars: ()
47freevars: ()
48nlocals: 5
49flags: 67
50consts: ('None',)
51
52>>> def attrs(obj):
Guido van Rossum7131f842007-02-09 20:13:25 +000053... print(obj.attr1)
54... print(obj.attr2)
55... print(obj.attr3)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000056
Neal Norwitz221085d2007-02-25 20:55:47 +000057>>> dump(attrs.__code__)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000058name: attrs
59argcount: 1
Guido van Rossum4f72a782006-10-27 23:31:49 +000060kwonlyargcount: 0
Georg Brandl88fc6642007-02-09 21:28:07 +000061names: ('print', 'attr1', 'attr2', 'attr3')
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000062varnames: ('obj',)
63cellvars: ()
64freevars: ()
65nlocals: 1
66flags: 67
67consts: ('None',)
68
Guido van Rossum4f72a782006-10-27 23:31:49 +000069>>> def keywordonly_args(a,b,*,k1):
70... return a,b,k1
71...
72
Neal Norwitz221085d2007-02-25 20:55:47 +000073>>> dump(keywordonly_args.__code__)
Guido van Rossum4f72a782006-10-27 23:31:49 +000074name: keywordonly_args
75argcount: 2
76kwonlyargcount: 1
77names: ()
78varnames: ('a', 'b', 'k1')
79cellvars: ()
80freevars: ()
81nlocals: 3
82flags: 67
83consts: ('None',)
84
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000085"""
86
Victor Stinnera2724092016-02-08 18:17:58 +010087import textwrap
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +000088import unittest
Collin Winter4222e9c2010-03-18 22:46:40 +000089import weakref
Victor Stinnera2724092016-02-08 18:17:58 +010090import warnings
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020091from test.support import run_doctest, run_unittest, cpython_only
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +000092
Collin Winter4222e9c2010-03-18 22:46:40 +000093
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000094def consts(t):
95 """Yield a doctest-safe sequence of object reprs."""
96 for elt in t:
97 r = repr(elt)
98 if r.startswith("<code object"):
99 yield "<code object %s>" % elt.co_name
100 else:
101 yield r
102
103def dump(co):
104 """Print out a text representation of a code object."""
Guido van Rossum4f72a782006-10-27 23:31:49 +0000105 for attr in ["name", "argcount", "kwonlyargcount", "names", "varnames",
106 "cellvars", "freevars", "nlocals", "flags"]:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000107 print("%s: %s" % (attr, getattr(co, "co_" + attr)))
108 print("consts:", tuple(consts(co.co_consts)))
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000109
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000110
111class CodeTest(unittest.TestCase):
112
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200113 @cpython_only
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000114 def test_newempty(self):
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200115 import _testcapi
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000116 co = _testcapi.code_newempty("filename", "funcname", 15)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000117 self.assertEqual(co.co_filename, "filename")
118 self.assertEqual(co.co_name, "funcname")
119 self.assertEqual(co.co_firstlineno, 15)
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000120
Victor Stinnera2724092016-02-08 18:17:58 +0100121 def dump(self, co):
122 dump = {}
123 for attr in ["name", "argcount", "kwonlyargcount", "names", "varnames",
124 "cellvars", "freevars", "nlocals", "flags"]:
125 dump[attr] = getattr(co, "co_" + attr)
126 dump['consts'] = tuple(consts(co.co_consts))
127 return dump
128
129 def test_optimize_away(self):
130 ns = {}
131 with warnings.catch_warnings():
132 warnings.filterwarnings('ignore', category=SyntaxWarning)
133 exec(textwrap.dedent('''
134 def optimize_away():
135 'doc string'
136 'not a docstring'
137 53
138 0x53
139 b'bytes'
140 1.0
141 True
142 False
143 None
144 ...
145 '''), ns)
146
147 self.assertEqual(self.dump(ns['optimize_away'].__code__),
148 {'name': 'optimize_away',
149 'argcount': 0,
150 'kwonlyargcount': 0,
151 'names': (),
152 'varnames': (),
153 'cellvars': (),
154 'freevars': (),
155 'nlocals': 0,
156 'flags': 67,
157 'consts': ("'doc string'", 'None')})
158
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000159
Collin Winter4222e9c2010-03-18 22:46:40 +0000160class CodeWeakRefTest(unittest.TestCase):
161
162 def test_basic(self):
163 # Create a code object in a clean environment so that we know we have
164 # the only reference to it left.
165 namespace = {}
166 exec("def f(): pass", globals(), namespace)
167 f = namespace["f"]
168 del namespace
169
170 self.called = False
171 def callback(code):
172 self.called = True
173
174 # f is now the last reference to the function, and through it, the code
175 # object. While we hold it, check that we can create a weakref and
176 # deref it. Then delete it, and check that the callback gets called and
177 # the reference dies.
178 coderef = weakref.ref(f.__code__, callback)
179 self.assertTrue(bool(coderef()))
180 del f
181 self.assertFalse(bool(coderef()))
182 self.assertTrue(self.called)
183
184
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000185def test_main(verbose=None):
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000186 from test import test_code
187 run_doctest(test_code, verbose)
Collin Winter4222e9c2010-03-18 22:46:40 +0000188 run_unittest(CodeTest, CodeWeakRefTest)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000189
190
Collin Winter4222e9c2010-03-18 22:46:40 +0000191if __name__ == "__main__":
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000192 test_main()