blob: 7975ea0ef5e17d01b1e1f2c01982d22a32a52074 [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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069>>> def optimize_away():
70... 'doc string'
71... 'not a docstring'
72... 53
Guido van Rossume2a383d2007-01-15 16:59:06 +000073... 0x53
Thomas Wouters0e3f5912006-08-11 14:57:12 +000074
Neal Norwitz221085d2007-02-25 20:55:47 +000075>>> dump(optimize_away.__code__)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076name: optimize_away
77argcount: 0
Guido van Rossum4f72a782006-10-27 23:31:49 +000078kwonlyargcount: 0
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079names: ()
80varnames: ()
81cellvars: ()
82freevars: ()
83nlocals: 0
84flags: 67
85consts: ("'doc string'", 'None')
86
Guido van Rossum4f72a782006-10-27 23:31:49 +000087>>> def keywordonly_args(a,b,*,k1):
88... return a,b,k1
89...
90
Neal Norwitz221085d2007-02-25 20:55:47 +000091>>> dump(keywordonly_args.__code__)
Guido van Rossum4f72a782006-10-27 23:31:49 +000092name: keywordonly_args
93argcount: 2
94kwonlyargcount: 1
95names: ()
96varnames: ('a', 'b', 'k1')
97cellvars: ()
98freevars: ()
99nlocals: 3
100flags: 67
101consts: ('None',)
102
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000103"""
104
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300105import sys
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000106import unittest
Collin Winter4222e9c2010-03-18 22:46:40 +0000107import weakref
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200108from test.support import run_doctest, run_unittest, cpython_only
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000109
Collin Winter4222e9c2010-03-18 22:46:40 +0000110
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000111def consts(t):
112 """Yield a doctest-safe sequence of object reprs."""
113 for elt in t:
114 r = repr(elt)
115 if r.startswith("<code object"):
116 yield "<code object %s>" % elt.co_name
117 else:
118 yield r
119
120def dump(co):
121 """Print out a text representation of a code object."""
Guido van Rossum4f72a782006-10-27 23:31:49 +0000122 for attr in ["name", "argcount", "kwonlyargcount", "names", "varnames",
123 "cellvars", "freevars", "nlocals", "flags"]:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000124 print("%s: %s" % (attr, getattr(co, "co_" + attr)))
125 print("consts:", tuple(consts(co.co_consts)))
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000126
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000127
128class CodeTest(unittest.TestCase):
129
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200130 @cpython_only
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000131 def test_newempty(self):
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200132 import _testcapi
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000133 co = _testcapi.code_newempty("filename", "funcname", 15)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000134 self.assertEqual(co.co_filename, "filename")
135 self.assertEqual(co.co_name, "funcname")
136 self.assertEqual(co.co_firstlineno, 15)
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000137
Serhiy Storchaka09f3d082016-10-04 18:17:22 +0300138
139def isinterned(s):
140 return s is sys.intern(('_' + s + '_')[1:-1])
141
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300142class CodeConstsTest(unittest.TestCase):
143
144 def find_const(self, consts, value):
145 for v in consts:
146 if v == value:
147 return v
Serhiy Storchaka09f3d082016-10-04 18:17:22 +0300148 self.assertIn(value, consts) # raises an exception
149 self.fail('Should never be reached')
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300150
151 def assertIsInterned(self, s):
Serhiy Storchaka09f3d082016-10-04 18:17:22 +0300152 if not isinterned(s):
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300153 self.fail('String %r is not interned' % (s,))
154
Serhiy Storchaka09f3d082016-10-04 18:17:22 +0300155 def assertIsNotInterned(self, s):
156 if isinterned(s):
157 self.fail('String %r is interned' % (s,))
158
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300159 @cpython_only
160 def test_interned_string(self):
161 co = compile('res = "str_value"', '?', 'exec')
162 v = self.find_const(co.co_consts, 'str_value')
163 self.assertIsInterned(v)
164
165 @cpython_only
166 def test_interned_string_in_tuple(self):
167 co = compile('res = ("str_value",)', '?', 'exec')
168 v = self.find_const(co.co_consts, ('str_value',))
169 self.assertIsInterned(v[0])
170
171 @cpython_only
172 def test_interned_string_in_frozenset(self):
173 co = compile('res = a in {"str_value"}', '?', 'exec')
174 v = self.find_const(co.co_consts, frozenset(('str_value',)))
175 self.assertIsInterned(tuple(v)[0])
176
177 @cpython_only
178 def test_interned_string_default(self):
179 def f(a='str_value'):
180 return a
181 self.assertIsInterned(f())
182
Serhiy Storchaka09f3d082016-10-04 18:17:22 +0300183 @cpython_only
184 def test_interned_string_with_null(self):
185 co = compile(r'res = "str\0value!"', '?', 'exec')
186 v = self.find_const(co.co_consts, 'str\0value!')
187 self.assertIsNotInterned(v)
188
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000189
Collin Winter4222e9c2010-03-18 22:46:40 +0000190class CodeWeakRefTest(unittest.TestCase):
191
192 def test_basic(self):
193 # Create a code object in a clean environment so that we know we have
194 # the only reference to it left.
195 namespace = {}
196 exec("def f(): pass", globals(), namespace)
197 f = namespace["f"]
198 del namespace
199
200 self.called = False
201 def callback(code):
202 self.called = True
203
204 # f is now the last reference to the function, and through it, the code
205 # object. While we hold it, check that we can create a weakref and
206 # deref it. Then delete it, and check that the callback gets called and
207 # the reference dies.
208 coderef = weakref.ref(f.__code__, callback)
209 self.assertTrue(bool(coderef()))
210 del f
211 self.assertFalse(bool(coderef()))
212 self.assertTrue(self.called)
213
214
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000215def test_main(verbose=None):
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000216 from test import test_code
217 run_doctest(test_code, verbose)
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300218 run_unittest(CodeTest, CodeConstsTest, CodeWeakRefTest)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000219
220
Collin Winter4222e9c2010-03-18 22:46:40 +0000221if __name__ == "__main__":
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000222 test_main()