blob: 1b826ee8d9a64d7bbfa35806bdba9afd828f36d5 [file] [log] [blame]
Tim Petersd66595f2001-02-04 03:09:53 +00001# Run the _testcapi module tests (tests for the Python/C API): by defn,
Guido van Rossum361c5352001-04-13 17:03:04 +00002# these are all functions _testcapi exports whose name begins with 'test_'.
Tim Peters9ea17ac2001-02-02 05:57:15 +00003
Eric Snowe3774162017-05-22 19:46:40 -07004from collections import namedtuple
Antoine Pitrou8e605772011-04-25 21:21:07 +02005import os
Antoine Pitrou2f828f22012-01-18 00:21:11 +01006import pickle
Eric Snowe3774162017-05-22 19:46:40 -07007import platform
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +00008import random
Victor Stinnerb3adb1a2016-03-14 17:40:09 +01009import re
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000010import subprocess
Martin v. Löwis6ce7ed22005-03-03 12:26:35 +000011import sys
Victor Stinner34be8072016-03-14 12:04:26 +010012import sysconfig
Victor Stinnerefde1462015-03-21 15:04:43 +010013import textwrap
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020014import threading
Benjamin Petersona54c9092009-01-13 02:11:23 +000015import time
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000016import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000017from test import support
Larry Hastingsfcafe432013-11-23 17:35:48 -080018from test.support import MISSING_C_DOCSTRINGS
xdegaye85f64302017-07-01 14:14:45 +020019from test.support.script_helper import assert_python_failure, assert_python_ok
Victor Stinner45df8202010-04-28 22:31:17 +000020try:
Stefan Krahfd24f9e2012-08-20 11:04:24 +020021 import _posixsubprocess
22except ImportError:
23 _posixsubprocess = None
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020024
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020025# Skip this test if the _testcapi module isn't available.
26_testcapi = support.import_module('_testcapi')
Tim Peters9ea17ac2001-02-02 05:57:15 +000027
Victor Stinnerefde1462015-03-21 15:04:43 +010028# Were we compiled --with-pydebug or with #define Py_DEBUG?
29Py_DEBUG = hasattr(sys, 'gettotalrefcount')
30
Benjamin Petersona54c9092009-01-13 02:11:23 +000031
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000032def testfunction(self):
33 """some doc"""
34 return self
35
36class InstanceMethod:
37 id = _testcapi.instancemethod(id)
38 testfunction = _testcapi.instancemethod(testfunction)
39
40class CAPITest(unittest.TestCase):
41
42 def test_instancemethod(self):
43 inst = InstanceMethod()
44 self.assertEqual(id(inst), inst.id())
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000045 self.assertTrue(inst.testfunction() is inst)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000046 self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__)
47 self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__)
48
49 InstanceMethod.testfunction.attribute = "test"
50 self.assertEqual(testfunction.attribute, "test")
51 self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
52
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000053 def test_no_FatalError_infinite_loop(self):
Antoine Pitrou77e904e2013-10-08 23:04:32 +020054 with support.SuppressCrashReport():
Ezio Melotti25a40452013-03-05 20:26:17 +020055 p = subprocess.Popen([sys.executable, "-c",
Ezio Melottie1857d92013-03-05 20:31:34 +020056 'import _testcapi;'
57 '_testcapi.crash_no_current_thread()'],
58 stdout=subprocess.PIPE,
59 stderr=subprocess.PIPE)
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000060 (out, err) = p.communicate()
61 self.assertEqual(out, b'')
62 # This used to cause an infinite loop.
Vinay Sajip73954042012-05-06 11:34:50 +010063 self.assertTrue(err.rstrip().startswith(
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000064 b'Fatal Python error:'
Vinay Sajip73954042012-05-06 11:34:50 +010065 b' PyThreadState_Get: no current thread'))
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000066
Antoine Pitrou915605c2011-02-24 20:53:48 +000067 def test_memoryview_from_NULL_pointer(self):
68 self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000069
Martin v. Löwisaa2efcb2012-04-19 14:33:43 +020070 def test_exc_info(self):
71 raised_exception = ValueError("5")
72 new_exc = TypeError("TEST")
73 try:
74 raise raised_exception
75 except ValueError as e:
76 tb = e.__traceback__
77 orig_sys_exc_info = sys.exc_info()
78 orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
79 new_sys_exc_info = sys.exc_info()
80 new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
81 reset_sys_exc_info = sys.exc_info()
82
83 self.assertEqual(orig_exc_info[1], e)
84
85 self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
86 self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
87 self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
88 self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
89 self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
90 else:
91 self.assertTrue(False)
92
Stefan Krahfd24f9e2012-08-20 11:04:24 +020093 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
94 def test_seq_bytes_to_charp_array(self):
95 # Issue #15732: crash in _PySequence_BytesToCharpArray()
96 class Z(object):
97 def __len__(self):
98 return 1
99 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300100 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
Stefan Krah7cacd2e2012-08-21 08:16:09 +0200101 # Issue #15736: overflow in _PySequence_BytesToCharpArray()
102 class Z(object):
103 def __len__(self):
104 return sys.maxsize
105 def __getitem__(self, i):
106 return b'x'
107 self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300108 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
Stefan Krahfd24f9e2012-08-20 11:04:24 +0200109
Stefan Krahdb579d72012-08-20 14:36:47 +0200110 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
111 def test_subprocess_fork_exec(self):
112 class Z(object):
113 def __len__(self):
114 return 1
115
116 # Issue #15738: crash in subprocess_fork_exec()
117 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300118 Z(),[b'1'],3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
Stefan Krahdb579d72012-08-20 14:36:47 +0200119
Larry Hastingsfcafe432013-11-23 17:35:48 -0800120 @unittest.skipIf(MISSING_C_DOCSTRINGS,
121 "Signature information for builtins requires docstrings")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800122 def test_docstring_signature_parsing(self):
123
124 self.assertEqual(_testcapi.no_docstring.__doc__, None)
125 self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
126
Zachary Ware8ef887c2015-04-13 18:22:35 -0500127 self.assertEqual(_testcapi.docstring_empty.__doc__, None)
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800128 self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
129
130 self.assertEqual(_testcapi.docstring_no_signature.__doc__,
131 "This docstring has no signature.")
132 self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
133
134 self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800135 "docstring_with_invalid_signature($module, /, boo)\n"
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800136 "\n"
137 "This docstring has an invalid signature."
138 )
139 self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
140
Larry Hastings2623c8c2014-02-08 22:15:29 -0800141 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__,
142 "docstring_with_invalid_signature2($module, /, boo)\n"
143 "\n"
144 "--\n"
145 "\n"
146 "This docstring also has an invalid signature."
147 )
148 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None)
149
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800150 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
151 "This docstring has a valid signature.")
Larry Hastings2623c8c2014-02-08 22:15:29 -0800152 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800153
Zachary Ware8ef887c2015-04-13 18:22:35 -0500154 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None)
155 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__,
156 "($module, /, sig)")
157
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800158 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800159 "\nThis docstring has a valid signature and some extra newlines.")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800160 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800161 "($module, /, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800162
Benjamin Petersond51374e2014-04-09 23:55:56 -0400163 def test_c_type_with_matrix_multiplication(self):
164 M = _testcapi.matmulType
165 m1 = M()
166 m2 = M()
167 self.assertEqual(m1 @ m2, ("matmul", m1, m2))
168 self.assertEqual(m1 @ 42, ("matmul", m1, 42))
169 self.assertEqual(42 @ m1, ("matmul", 42, m1))
170 o = m1
171 o @= m2
172 self.assertEqual(o, ("imatmul", m1, m2))
173 o = m1
174 o @= 42
175 self.assertEqual(o, ("imatmul", m1, 42))
176 o = 42
177 o @= m1
178 self.assertEqual(o, ("matmul", 42, m1))
179
Victor Stinnerefde1462015-03-21 15:04:43 +0100180 def test_return_null_without_error(self):
181 # Issue #23571: A function must not return NULL without setting an
182 # error
183 if Py_DEBUG:
184 code = textwrap.dedent("""
185 import _testcapi
186 from test import support
187
188 with support.SuppressCrashReport():
189 _testcapi.return_null_without_error()
190 """)
191 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100192 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100193 br'Fatal Python error: a function returned NULL '
194 br'without setting an error\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100195 br'SystemError: <built-in function '
196 br'return_null_without_error> returned NULL '
197 br'without setting an error\n'
198 br'\n'
199 br'Current thread.*:\n'
200 br' File .*", line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100201 else:
202 with self.assertRaises(SystemError) as cm:
203 _testcapi.return_null_without_error()
204 self.assertRegex(str(cm.exception),
205 'return_null_without_error.* '
206 'returned NULL without setting an error')
207
208 def test_return_result_with_error(self):
209 # Issue #23571: A function must not return a result with an error set
210 if Py_DEBUG:
211 code = textwrap.dedent("""
212 import _testcapi
213 from test import support
214
215 with support.SuppressCrashReport():
216 _testcapi.return_result_with_error()
217 """)
218 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100219 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100220 br'Fatal Python error: a function returned a '
221 br'result with an error set\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100222 br'ValueError\n'
223 br'\n'
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300224 br'The above exception was the direct cause '
225 br'of the following exception:\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100226 br'\n'
227 br'SystemError: <built-in '
228 br'function return_result_with_error> '
229 br'returned a result with an error set\n'
230 br'\n'
231 br'Current thread.*:\n'
232 br' File .*, line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100233 else:
234 with self.assertRaises(SystemError) as cm:
235 _testcapi.return_result_with_error()
236 self.assertRegex(str(cm.exception),
237 'return_result_with_error.* '
238 'returned a result with an error set')
239
Serhiy Storchaka13e602e2016-05-20 22:31:14 +0300240 def test_buildvalue_N(self):
241 _testcapi.test_buildvalue_N()
242
xdegaye85f64302017-07-01 14:14:45 +0200243 def test_set_nomemory(self):
244 code = """if 1:
245 import _testcapi
246
247 class C(): pass
248
249 # The first loop tests both functions and that remove_mem_hooks()
250 # can be called twice in a row. The second loop checks a call to
251 # set_nomemory() after a call to remove_mem_hooks(). The third
252 # loop checks the start and stop arguments of set_nomemory().
253 for outer_cnt in range(1, 4):
254 start = 10 * outer_cnt
255 for j in range(100):
256 if j == 0:
257 if outer_cnt != 3:
258 _testcapi.set_nomemory(start)
259 else:
260 _testcapi.set_nomemory(start, start + 1)
261 try:
262 C()
263 except MemoryError as e:
264 if outer_cnt != 3:
265 _testcapi.remove_mem_hooks()
266 print('MemoryError', outer_cnt, j)
267 _testcapi.remove_mem_hooks()
268 break
269 """
270 rc, out, err = assert_python_ok('-c', code)
271 self.assertIn(b'MemoryError 1 10', out)
272 self.assertIn(b'MemoryError 2 20', out)
273 self.assertIn(b'MemoryError 3 30', out)
274
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800275
Benjamin Petersona54c9092009-01-13 02:11:23 +0000276class TestPendingCalls(unittest.TestCase):
277
278 def pendingcalls_submit(self, l, n):
279 def callback():
280 #this function can be interrupted by thread switching so let's
281 #use an atomic operation
282 l.append(None)
283
284 for i in range(n):
285 time.sleep(random.random()*0.02) #0.01 secs on average
286 #try submitting callback until successful.
287 #rely on regular interrupt to flush queue if we are
288 #unsuccessful.
289 while True:
290 if _testcapi._pending_threadfunc(callback):
291 break;
292
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000293 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000294 #now, stick around until l[0] has grown to 10
295 count = 0;
296 while len(l) != n:
297 #this busy loop is where we expect to be interrupted to
298 #run our callbacks. Note that callbacks are only run on the
299 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000300 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000301 print("(%i)"%(len(l),),)
302 for i in range(1000):
303 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000304 if context and not context.event.is_set():
305 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000306 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000307 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000308 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000309 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000310 print("(%i)"%(len(l),))
311
312 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000313
314 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000315 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000316 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000317 class foo(object):pass
318 context = foo()
319 context.l = []
320 context.n = 2 #submits per thread
321 context.nThreads = n // context.n
322 context.nFinished = 0
323 context.lock = threading.Lock()
324 context.event = threading.Event()
325
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300326 threads = [threading.Thread(target=self.pendingcalls_thread,
327 args=(context,))
328 for i in range(context.nThreads)]
329 with support.start_threads(threads):
330 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000331
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000332 def pendingcalls_thread(self, context):
333 try:
334 self.pendingcalls_submit(context.l, context.n)
335 finally:
336 with context.lock:
337 context.nFinished += 1
338 nFinished = context.nFinished
339 if False and support.verbose:
340 print("finished threads: ", nFinished)
341 if nFinished == context.nThreads:
342 context.event.set()
343
Benjamin Petersona54c9092009-01-13 02:11:23 +0000344 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200345 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000346 #once. It is ok to ask for too many, because we loop until we find a slot.
347 #the loop can be interrupted to dispatch.
348 #there are only 32 dispatch slots, so we go for twice that!
349 l = []
350 n = 64
351 self.pendingcalls_submit(l, n)
352 self.pendingcalls_wait(l, n)
353
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200354
355class SubinterpreterTest(unittest.TestCase):
356
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100357 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100358 import builtins
359 r, w = os.pipe()
360 code = """if 1:
361 import sys, builtins, pickle
362 with open({:d}, "wb") as f:
363 pickle.dump(id(sys.modules), f)
364 pickle.dump(id(builtins), f)
365 """.format(w)
366 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100367 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100368 self.assertEqual(ret, 0)
369 self.assertNotEqual(pickle.load(f), id(sys.modules))
370 self.assertNotEqual(pickle.load(f), id(builtins))
371
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200372
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000373# Bug #6012
374class Test6012(unittest.TestCase):
375 def test(self):
376 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000377
Antoine Pitrou8e605772011-04-25 21:21:07 +0200378
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000379class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000380 def setUp(self):
Zachary Ware6d8a2602015-12-05 00:16:55 -0600381 here = os.path.abspath(__file__)
382 basepath = os.path.dirname(os.path.dirname(os.path.dirname(here)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000383 exename = "_testembed"
384 if sys.platform.startswith("win"):
385 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
386 exename += ext
387 exepath = os.path.dirname(sys.executable)
388 else:
Nick Coghlanbca9acf2014-09-25 19:48:15 +1000389 exepath = os.path.join(basepath, "Programs")
Nick Coghlan4e641df2013-11-03 16:54:46 +1000390 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000391 if not os.path.exists(exe):
392 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200393 # This is needed otherwise we get a fatal error:
394 # "Py_Initialize: Unable to get the locale encoding
395 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000396 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200397 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000398
399 def tearDown(self):
400 os.chdir(self.oldcwd)
401
Nick Coghlan6ea41862017-06-11 13:16:15 +1000402 def run_embedded_interpreter(self, *args, env=None):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000403 """Runs a test in the embedded interpreter"""
404 cmd = [self.test_exe]
405 cmd.extend(args)
Nick Coghlan6ea41862017-06-11 13:16:15 +1000406 if env is not None and sys.platform == 'win32':
407 # Windows requires at least the SYSTEMROOT environment variable to
408 # start Python.
409 env = env.copy()
410 env['SYSTEMROOT'] = os.environ['SYSTEMROOT']
411
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000412 p = subprocess.Popen(cmd,
413 stdout=subprocess.PIPE,
Steve Dower86e9deb2014-11-01 15:11:05 -0700414 stderr=subprocess.PIPE,
Nick Coghlan6ea41862017-06-11 13:16:15 +1000415 universal_newlines=True,
416 env=env)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000417 (out, err) = p.communicate()
418 self.assertEqual(p.returncode, 0,
419 "bad returncode %d, stderr is %r" %
420 (p.returncode, err))
Steve Dower86e9deb2014-11-01 15:11:05 -0700421 return out, err
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000422
Eric Snowd1c3c132017-05-24 17:19:47 -0700423 def run_repeated_init_and_subinterpreters(self):
Steve Dowerea74f0c2017-01-01 20:25:03 -0800424 out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
Eric Snowe3774162017-05-22 19:46:40 -0700425 self.assertEqual(err, "")
426
427 # The output from _testembed looks like this:
428 # --- Pass 0 ---
429 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
430 # interp 1 <0x1d4f690>, thread state <0x1d35350>: id(modules) = 139650431165784
431 # interp 2 <0x1d5a690>, thread state <0x1d99ed0>: id(modules) = 139650413140368
432 # interp 3 <0x1d4f690>, thread state <0x1dc3340>: id(modules) = 139650412862200
433 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
434 # --- Pass 1 ---
435 # ...
436
437 interp_pat = (r"^interp (\d+) <(0x[\dA-F]+)>, "
438 r"thread state <(0x[\dA-F]+)>: "
439 r"id\(modules\) = ([\d]+)$")
440 Interp = namedtuple("Interp", "id interp tstate modules")
441
Eric Snowe3774162017-05-22 19:46:40 -0700442 numloops = 0
Eric Snowd1c3c132017-05-24 17:19:47 -0700443 current_run = []
Eric Snowe3774162017-05-22 19:46:40 -0700444 for line in out.splitlines():
445 if line == "--- Pass {} ---".format(numloops):
Eric Snowd1c3c132017-05-24 17:19:47 -0700446 self.assertEqual(len(current_run), 0)
Eric Snowe3774162017-05-22 19:46:40 -0700447 if support.verbose:
448 print(line)
Eric Snowe3774162017-05-22 19:46:40 -0700449 numloops += 1
Eric Snowe3774162017-05-22 19:46:40 -0700450 continue
Eric Snowe3774162017-05-22 19:46:40 -0700451
Eric Snowd1c3c132017-05-24 17:19:47 -0700452 self.assertLess(len(current_run), 5)
Eric Snowe3774162017-05-22 19:46:40 -0700453 match = re.match(interp_pat, line)
454 if match is None:
455 self.assertRegex(line, interp_pat)
456
Eric Snowe3774162017-05-22 19:46:40 -0700457 # Parse the line from the loop. The first line is the main
458 # interpreter and the 3 afterward are subinterpreters.
459 interp = Interp(*match.groups())
460 if support.verbose:
461 print(interp)
Eric Snowe3774162017-05-22 19:46:40 -0700462 self.assertTrue(interp.interp)
463 self.assertTrue(interp.tstate)
464 self.assertTrue(interp.modules)
Eric Snowd1c3c132017-05-24 17:19:47 -0700465 current_run.append(interp)
466
467 # The last line in the loop should be the same as the first.
468 if len(current_run) == 5:
469 main = current_run[0]
470 self.assertEqual(interp, main)
471 yield current_run
472 current_run = []
473
474 def test_subinterps_main(self):
475 for run in self.run_repeated_init_and_subinterpreters():
476 main = run[0]
477
478 self.assertEqual(main.id, '0')
479
480 def test_subinterps_different_ids(self):
481 for run in self.run_repeated_init_and_subinterpreters():
482 main, *subs, _ = run
483
484 mainid = int(main.id)
485 for i, sub in enumerate(subs):
486 self.assertEqual(sub.id, str(mainid + i + 1))
487
488 def test_subinterps_distinct_state(self):
489 for run in self.run_repeated_init_and_subinterpreters():
490 main, *subs, _ = run
491
492 if '0x0' in main:
493 # XXX Fix on Windows (and other platforms): something
494 # is going on with the pointers in Programs/_testembed.c.
495 # interp.interp is 0x0 and interp.modules is the same
496 # between interpreters.
497 raise unittest.SkipTest('platform prints pointers as 0x0')
498
499 for sub in subs:
Eric Snowe3774162017-05-22 19:46:40 -0700500 # A new subinterpreter may have the same
501 # PyInterpreterState pointer as a previous one if
502 # the earlier one has already been destroyed. So
503 # we compare with the main interpreter. The same
504 # applies to tstate.
Eric Snowd1c3c132017-05-24 17:19:47 -0700505 self.assertNotEqual(sub.interp, main.interp)
506 self.assertNotEqual(sub.tstate, main.tstate)
507 self.assertNotEqual(sub.modules, main.modules)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000508
509 def test_forced_io_encoding(self):
510 # Checks forced configuration of embedded interpreter IO streams
Victor Stinnereb52ac82017-06-13 11:49:44 +0200511 env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape")
Nick Coghlan6ea41862017-06-11 13:16:15 +1000512 out, err = self.run_embedded_interpreter("forced_io_encoding", env=env)
513 if support.verbose > 1:
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000514 print()
515 print(out)
516 print(err)
Nick Coghlan6ea41862017-06-11 13:16:15 +1000517 expected_stream_encoding = "utf-8"
518 expected_errors = "surrogateescape"
Steve Dower86e9deb2014-11-01 15:11:05 -0700519 expected_output = '\n'.join([
Nick Coghlan4e641df2013-11-03 16:54:46 +1000520 "--- Use defaults ---",
521 "Expected encoding: default",
522 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100523 "stdin: {in_encoding}:{errors}",
524 "stdout: {out_encoding}:{errors}",
525 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000526 "--- Set errors only ---",
527 "Expected encoding: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100528 "Expected errors: ignore",
529 "stdin: {in_encoding}:ignore",
530 "stdout: {out_encoding}:ignore",
531 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000532 "--- Set encoding only ---",
533 "Expected encoding: latin-1",
534 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100535 "stdin: latin-1:{errors}",
536 "stdout: latin-1:{errors}",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000537 "stderr: latin-1:backslashreplace",
538 "--- Set encoding and errors ---",
539 "Expected encoding: latin-1",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100540 "Expected errors: replace",
541 "stdin: latin-1:replace",
542 "stdout: latin-1:replace",
543 "stderr: latin-1:backslashreplace"])
544 expected_output = expected_output.format(
Nick Coghlan6ea41862017-06-11 13:16:15 +1000545 in_encoding=expected_stream_encoding,
546 out_encoding=expected_stream_encoding,
Victor Stinnerb2bef622014-03-18 02:38:12 +0100547 errors=expected_errors)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000548 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000549 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000550 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200551
Victor Stinnerc4aec362016-03-14 22:26:53 +0100552
Larry Hastings8f904da2012-06-22 03:56:29 -0700553class SkipitemTest(unittest.TestCase):
554
555 def test_skipitem(self):
556 """
557 If this test failed, you probably added a new "format unit"
558 in Python/getargs.c, but neglected to update our poor friend
559 skipitem() in the same file. (If so, shame on you!)
560
Larry Hastings48ed3602012-06-22 12:58:36 -0700561 With a few exceptions**, this function brute-force tests all
562 printable ASCII*** characters (32 to 126 inclusive) as format units,
563 checking to see that PyArg_ParseTupleAndKeywords() return consistent
564 errors both when the unit is attempted to be used and when it is
565 skipped. If the format unit doesn't exist, we'll get one of two
566 specific error messages (one for used, one for skipped); if it does
567 exist we *won't* get that error--we'll get either no error or some
568 other error. If we get the specific "does not exist" error for one
569 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700570
Larry Hastings48ed3602012-06-22 12:58:36 -0700571 ** Some format units have special funny semantics and it would
Martin Panter46f50722016-05-26 05:35:26 +0000572 be difficult to accommodate them here. Since these are all
Larry Hastings48ed3602012-06-22 12:58:36 -0700573 well-established and properly skipped in skipitem() we can
574 get away with not testing them--this test is really intended
575 to catch *new* format units.
576
577 *** Python C source files must be ASCII. Therefore it's impossible
578 to have non-ASCII format units.
579
Larry Hastings8f904da2012-06-22 03:56:29 -0700580 """
581 empty_tuple = ()
582 tuple_1 = (0,)
583 dict_b = {'b':1}
584 keywords = ["a", "b"]
585
Larry Hastings48ed3602012-06-22 12:58:36 -0700586 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700587 c = chr(i)
588
Larry Hastings8f904da2012-06-22 03:56:29 -0700589 # skip parentheses, the error reporting is inconsistent about them
590 # skip 'e', it's always a two-character code
591 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700592 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700593 continue
594
595 # test the format unit when not skipped
596 format = c + "i"
597 try:
Larry Hastings8f904da2012-06-22 03:56:29 -0700598 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300599 format, keywords)
Larry Hastings8f904da2012-06-22 03:56:29 -0700600 when_not_skipped = False
Serhiy Storchaka4cd63ef2016-02-08 01:22:47 +0200601 except SystemError as e:
Serhiy Storchakac4b813d2016-02-08 01:06:11 +0200602 s = "argument 1 (impossible<bad format char>)"
Larry Hastings8f904da2012-06-22 03:56:29 -0700603 when_not_skipped = (str(e) == s)
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200604 except TypeError:
Larry Hastings8f904da2012-06-22 03:56:29 -0700605 when_not_skipped = False
606
607 # test the format unit when skipped
608 optional_format = "|" + format
609 try:
610 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300611 optional_format, keywords)
Larry Hastings8f904da2012-06-22 03:56:29 -0700612 when_skipped = False
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200613 except SystemError as e:
Larry Hastings8f904da2012-06-22 03:56:29 -0700614 s = "impossible<bad format char>: '{}'".format(format)
615 when_skipped = (str(e) == s)
616
617 message = ("test_skipitem_parity: "
618 "detected mismatch between convertsimple and skipitem "
619 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
620 c, i, when_skipped, when_not_skipped))
621 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200622
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200623 def test_parse_tuple_and_keywords(self):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300624 # Test handling errors in the parse_tuple_and_keywords helper itself
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200625 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
626 (), {}, 42, [])
627 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300628 (), {}, '', 42)
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200629 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300630 (), {}, '', [''] * 42)
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200631 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300632 (), {}, '', [42])
633
634 def test_bad_use(self):
635 # Test handling invalid format and keywords in
636 # PyArg_ParseTupleAndKeywords()
637 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
638 (1,), {}, '||O', ['a'])
639 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
640 (1, 2), {}, '|O|O', ['a', 'b'])
641 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
642 (), {'a': 1}, '$$O', ['a'])
643 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
644 (), {'a': 1, 'b': 2}, '$O$O', ['a', 'b'])
645 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
646 (), {'a': 1}, '$|O', ['a'])
647 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
648 (), {'a': 1, 'b': 2}, '$O|O', ['a', 'b'])
649 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
650 (1,), {}, '|O', ['a', 'b'])
651 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
652 (1,), {}, '|OO', ['a'])
653 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
654 (), {}, '|$O', [''])
655 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
656 (), {}, '|OO', ['a', ''])
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200657
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300658 def test_positional_only(self):
659 parse = _testcapi.parse_tuple_and_keywords
660
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300661 parse((1, 2, 3), {}, 'OOO', ['', '', 'a'])
662 parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300663 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200664 r'function takes at least 2 positional arguments \(1 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300665 parse((1,), {'a': 3}, 'OOO', ['', '', 'a'])
666 parse((1,), {}, 'O|OO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300667 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200668 r'function takes at least 1 positional arguments \(0 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300669 parse((), {}, 'O|OO', ['', '', 'a'])
670 parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300671 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200672 r'function takes exactly 2 positional arguments \(1 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300673 parse((1,), {'a': 3}, 'OO$O', ['', '', 'a'])
674 parse((1,), {}, 'O|O$O', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300675 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200676 r'function takes at least 1 positional arguments \(0 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300677 parse((), {}, 'O|O$O', ['', '', 'a'])
R David Murray44b548d2016-09-08 13:59:53 -0400678 with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300679 parse((1,), {}, 'O|$OO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300680 with self.assertRaisesRegex(SystemError, 'Empty keyword'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300681 parse((1,), {}, 'O|OO', ['', 'a', ''])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300682
Victor Stinner34be8072016-03-14 12:04:26 +0100683
Ezio Melotti29267c82013-02-23 05:52:46 +0200684class TestThreadState(unittest.TestCase):
685
686 @support.reap_threads
687 def test_thread_state(self):
688 # some extra thread-state tests driven via _testcapi
689 def target():
690 idents = []
691
692 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200693 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200694
695 _testcapi._test_thread_state(callback)
696 a = b = callback
697 time.sleep(1)
698 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200699 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200700 "Couldn't find main thread correctly in the list")
701
702 target()
703 t = threading.Thread(target=target)
704 t.start()
705 t.join()
706
Victor Stinner34be8072016-03-14 12:04:26 +0100707
Zachary Warec12f09e2013-11-11 22:47:04 -0600708class Test_testcapi(unittest.TestCase):
709 def test__testcapi(self):
710 for name in dir(_testcapi):
711 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600712 with self.subTest("internal", name=name):
713 test = getattr(_testcapi, name)
714 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000715
Victor Stinner34be8072016-03-14 12:04:26 +0100716
Victor Stinnerc4aec362016-03-14 22:26:53 +0100717class PyMemDebugTests(unittest.TestCase):
718 PYTHONMALLOC = 'debug'
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100719 # '0x04c06e0' or '04C06E0'
Victor Stinner08572f62016-03-14 21:55:43 +0100720 PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+'
Victor Stinner34be8072016-03-14 12:04:26 +0100721
722 def check(self, code):
723 with support.SuppressCrashReport():
Victor Stinnerc4aec362016-03-14 22:26:53 +0100724 out = assert_python_failure('-c', code,
725 PYTHONMALLOC=self.PYTHONMALLOC)
Victor Stinner34be8072016-03-14 12:04:26 +0100726 stderr = out.err
727 return stderr.decode('ascii', 'replace')
728
729 def test_buffer_overflow(self):
730 out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()')
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100731 regex = (r"Debug memory block at address p={ptr}: API 'm'\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100732 r" 16 bytes originally requested\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100733 r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n"
734 r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100735 r" at tail\+0: 0x78 \*\*\* OUCH\n"
736 r" at tail\+1: 0xfb\n"
737 r" at tail\+2: 0xfb\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100738 r" .*\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100739 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100740 r" Data at p: cb cb cb .*\n"
Victor Stinner6453e9e2016-03-15 23:36:28 +0100741 r"\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100742 r"Fatal Python error: bad trailing pad byte")
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100743 regex = regex.format(ptr=self.PTR_REGEX)
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100744 regex = re.compile(regex, flags=re.DOTALL)
Victor Stinner34be8072016-03-14 12:04:26 +0100745 self.assertRegex(out, regex)
746
747 def test_api_misuse(self):
748 out = self.check('import _testcapi; _testcapi.pymem_api_misuse()')
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100749 regex = (r"Debug memory block at address p={ptr}: API 'm'\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100750 r" 16 bytes originally requested\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100751 r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n"
752 r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100753 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100754 r" Data at p: cb cb cb .*\n"
Victor Stinner6453e9e2016-03-15 23:36:28 +0100755 r"\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100756 r"Fatal Python error: bad ID: Allocated using API 'm', verified using API 'r'\n")
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100757 regex = regex.format(ptr=self.PTR_REGEX)
Victor Stinner34be8072016-03-14 12:04:26 +0100758 self.assertRegex(out, regex)
759
Victor Stinnerad524372016-03-16 12:12:53 +0100760 def check_malloc_without_gil(self, code):
Victor Stinnerc4aec362016-03-14 22:26:53 +0100761 out = self.check(code)
762 expected = ('Fatal Python error: Python memory allocator called '
763 'without holding the GIL')
764 self.assertIn(expected, out)
Victor Stinner34be8072016-03-14 12:04:26 +0100765
Victor Stinnerad524372016-03-16 12:12:53 +0100766 def test_pymem_malloc_without_gil(self):
767 # Debug hooks must raise an error if PyMem_Malloc() is called
768 # without holding the GIL
769 code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()'
770 self.check_malloc_without_gil(code)
771
772 def test_pyobject_malloc_without_gil(self):
773 # Debug hooks must raise an error if PyObject_Malloc() is called
774 # without holding the GIL
775 code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()'
776 self.check_malloc_without_gil(code)
777
Victor Stinnerc4aec362016-03-14 22:26:53 +0100778
779class PyMemMallocDebugTests(PyMemDebugTests):
780 PYTHONMALLOC = 'malloc_debug'
Victor Stinner34be8072016-03-14 12:04:26 +0100781
782
783@unittest.skipUnless(sysconfig.get_config_var('WITH_PYMALLOC') == 1,
784 'need pymalloc')
Victor Stinnerc4aec362016-03-14 22:26:53 +0100785class PyMemPymallocDebugTests(PyMemDebugTests):
786 PYTHONMALLOC = 'pymalloc_debug'
Victor Stinner34be8072016-03-14 12:04:26 +0100787
788
789@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG')
Victor Stinnerc4aec362016-03-14 22:26:53 +0100790class PyMemDefaultTests(PyMemDebugTests):
791 # test default allocator of Python compiled in debug mode
792 PYTHONMALLOC = ''
Victor Stinner34be8072016-03-14 12:04:26 +0100793
794
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000795if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600796 unittest.main()