blob: 8ac8af9826569597c638c777d3ba9ee602f54954 [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 Stinner34be807c2016-03-14 12:04:26 +010012import sysconfig
Victor Stinnerefde1462015-03-21 15:04:43 +010013import textwrap
Benjamin Petersona54c9092009-01-13 02:11:23 +000014import time
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000015import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000016from test import support
Larry Hastingsfcafe432013-11-23 17:35:48 -080017from test.support import MISSING_C_DOCSTRINGS
Berker Peksagce643912015-05-06 06:33:17 +030018from test.support.script_helper import assert_python_failure
Victor Stinner45df8202010-04-28 22:31:17 +000019try:
Stefan Krahfd24f9e2012-08-20 11:04:24 +020020 import _posixsubprocess
21except ImportError:
22 _posixsubprocess = None
23try:
Victor Stinner45df8202010-04-28 22:31:17 +000024 import threading
25except ImportError:
26 threading = None
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020027# Skip this test if the _testcapi module isn't available.
28_testcapi = support.import_module('_testcapi')
Tim Peters9ea17ac2001-02-02 05:57:15 +000029
Victor Stinnerefde1462015-03-21 15:04:43 +010030# Were we compiled --with-pydebug or with #define Py_DEBUG?
31Py_DEBUG = hasattr(sys, 'gettotalrefcount')
32
Benjamin Petersona54c9092009-01-13 02:11:23 +000033
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000034def testfunction(self):
35 """some doc"""
36 return self
37
38class InstanceMethod:
39 id = _testcapi.instancemethod(id)
40 testfunction = _testcapi.instancemethod(testfunction)
41
42class CAPITest(unittest.TestCase):
43
44 def test_instancemethod(self):
45 inst = InstanceMethod()
46 self.assertEqual(id(inst), inst.id())
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000047 self.assertTrue(inst.testfunction() is inst)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000048 self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__)
49 self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__)
50
51 InstanceMethod.testfunction.attribute = "test"
52 self.assertEqual(testfunction.attribute, "test")
53 self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
54
Stefan Krah0ca46242010-06-09 08:56:28 +000055 @unittest.skipUnless(threading, 'Threading required for this test.')
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000056 def test_no_FatalError_infinite_loop(self):
Antoine Pitrou77e904e2013-10-08 23:04:32 +020057 with support.SuppressCrashReport():
Ezio Melotti25a40452013-03-05 20:26:17 +020058 p = subprocess.Popen([sys.executable, "-c",
Ezio Melottie1857d92013-03-05 20:31:34 +020059 'import _testcapi;'
60 '_testcapi.crash_no_current_thread()'],
61 stdout=subprocess.PIPE,
62 stderr=subprocess.PIPE)
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000063 (out, err) = p.communicate()
64 self.assertEqual(out, b'')
65 # This used to cause an infinite loop.
Vinay Sajip73954042012-05-06 11:34:50 +010066 self.assertTrue(err.rstrip().startswith(
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000067 b'Fatal Python error:'
Vinay Sajip73954042012-05-06 11:34:50 +010068 b' PyThreadState_Get: no current thread'))
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000069
Antoine Pitrou915605c2011-02-24 20:53:48 +000070 def test_memoryview_from_NULL_pointer(self):
71 self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000072
Martin v. Löwisaa2efcb2012-04-19 14:33:43 +020073 def test_exc_info(self):
74 raised_exception = ValueError("5")
75 new_exc = TypeError("TEST")
76 try:
77 raise raised_exception
78 except ValueError as e:
79 tb = e.__traceback__
80 orig_sys_exc_info = sys.exc_info()
81 orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
82 new_sys_exc_info = sys.exc_info()
83 new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
84 reset_sys_exc_info = sys.exc_info()
85
86 self.assertEqual(orig_exc_info[1], e)
87
88 self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
89 self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
90 self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
91 self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
92 self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
93 else:
94 self.assertTrue(False)
95
Stefan Krahfd24f9e2012-08-20 11:04:24 +020096 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
97 def test_seq_bytes_to_charp_array(self):
98 # Issue #15732: crash in _PySequence_BytesToCharpArray()
99 class Z(object):
100 def __len__(self):
101 return 1
102 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300103 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 +0200104 # Issue #15736: overflow in _PySequence_BytesToCharpArray()
105 class Z(object):
106 def __len__(self):
107 return sys.maxsize
108 def __getitem__(self, i):
109 return b'x'
110 self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300111 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 +0200112
Stefan Krahdb579d72012-08-20 14:36:47 +0200113 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
114 def test_subprocess_fork_exec(self):
115 class Z(object):
116 def __len__(self):
117 return 1
118
119 # Issue #15738: crash in subprocess_fork_exec()
120 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300121 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 +0200122
Larry Hastingsfcafe432013-11-23 17:35:48 -0800123 @unittest.skipIf(MISSING_C_DOCSTRINGS,
124 "Signature information for builtins requires docstrings")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800125 def test_docstring_signature_parsing(self):
126
127 self.assertEqual(_testcapi.no_docstring.__doc__, None)
128 self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
129
Zachary Ware8ef887c2015-04-13 18:22:35 -0500130 self.assertEqual(_testcapi.docstring_empty.__doc__, None)
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800131 self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
132
133 self.assertEqual(_testcapi.docstring_no_signature.__doc__,
134 "This docstring has no signature.")
135 self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
136
137 self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800138 "docstring_with_invalid_signature($module, /, boo)\n"
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800139 "\n"
140 "This docstring has an invalid signature."
141 )
142 self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
143
Larry Hastings2623c8c2014-02-08 22:15:29 -0800144 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__,
145 "docstring_with_invalid_signature2($module, /, boo)\n"
146 "\n"
147 "--\n"
148 "\n"
149 "This docstring also has an invalid signature."
150 )
151 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None)
152
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800153 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
154 "This docstring has a valid signature.")
Larry Hastings2623c8c2014-02-08 22:15:29 -0800155 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800156
Zachary Ware8ef887c2015-04-13 18:22:35 -0500157 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None)
158 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__,
159 "($module, /, sig)")
160
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800161 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800162 "\nThis docstring has a valid signature and some extra newlines.")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800163 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800164 "($module, /, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800165
Benjamin Petersond51374e2014-04-09 23:55:56 -0400166 def test_c_type_with_matrix_multiplication(self):
167 M = _testcapi.matmulType
168 m1 = M()
169 m2 = M()
170 self.assertEqual(m1 @ m2, ("matmul", m1, m2))
171 self.assertEqual(m1 @ 42, ("matmul", m1, 42))
172 self.assertEqual(42 @ m1, ("matmul", 42, m1))
173 o = m1
174 o @= m2
175 self.assertEqual(o, ("imatmul", m1, m2))
176 o = m1
177 o @= 42
178 self.assertEqual(o, ("imatmul", m1, 42))
179 o = 42
180 o @= m1
181 self.assertEqual(o, ("matmul", 42, m1))
182
Victor Stinnerefde1462015-03-21 15:04:43 +0100183 def test_return_null_without_error(self):
184 # Issue #23571: A function must not return NULL without setting an
185 # error
186 if Py_DEBUG:
187 code = textwrap.dedent("""
188 import _testcapi
189 from test import support
190
191 with support.SuppressCrashReport():
192 _testcapi.return_null_without_error()
193 """)
194 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100195 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100196 br'Fatal Python error: a function returned NULL '
197 br'without setting an error\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100198 br'SystemError: <built-in function '
199 br'return_null_without_error> returned NULL '
200 br'without setting an error\n'
201 br'\n'
202 br'Current thread.*:\n'
203 br' File .*", line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100204 else:
205 with self.assertRaises(SystemError) as cm:
206 _testcapi.return_null_without_error()
207 self.assertRegex(str(cm.exception),
208 'return_null_without_error.* '
209 'returned NULL without setting an error')
210
211 def test_return_result_with_error(self):
212 # Issue #23571: A function must not return a result with an error set
213 if Py_DEBUG:
214 code = textwrap.dedent("""
215 import _testcapi
216 from test import support
217
218 with support.SuppressCrashReport():
219 _testcapi.return_result_with_error()
220 """)
221 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100222 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100223 br'Fatal Python error: a function returned a '
224 br'result with an error set\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100225 br'ValueError\n'
226 br'\n'
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300227 br'The above exception was the direct cause '
228 br'of the following exception:\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100229 br'\n'
230 br'SystemError: <built-in '
231 br'function return_result_with_error> '
232 br'returned a result with an error set\n'
233 br'\n'
234 br'Current thread.*:\n'
235 br' File .*, line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100236 else:
237 with self.assertRaises(SystemError) as cm:
238 _testcapi.return_result_with_error()
239 self.assertRegex(str(cm.exception),
240 'return_result_with_error.* '
241 'returned a result with an error set')
242
Serhiy Storchaka13e602e2016-05-20 22:31:14 +0300243 def test_buildvalue_N(self):
244 _testcapi.test_buildvalue_N()
245
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800246
Victor Stinner45df8202010-04-28 22:31:17 +0000247@unittest.skipUnless(threading, 'Threading required for this test.')
Benjamin Petersona54c9092009-01-13 02:11:23 +0000248class TestPendingCalls(unittest.TestCase):
249
250 def pendingcalls_submit(self, l, n):
251 def callback():
252 #this function can be interrupted by thread switching so let's
253 #use an atomic operation
254 l.append(None)
255
256 for i in range(n):
257 time.sleep(random.random()*0.02) #0.01 secs on average
258 #try submitting callback until successful.
259 #rely on regular interrupt to flush queue if we are
260 #unsuccessful.
261 while True:
262 if _testcapi._pending_threadfunc(callback):
263 break;
264
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000265 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000266 #now, stick around until l[0] has grown to 10
267 count = 0;
268 while len(l) != n:
269 #this busy loop is where we expect to be interrupted to
270 #run our callbacks. Note that callbacks are only run on the
271 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000272 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000273 print("(%i)"%(len(l),),)
274 for i in range(1000):
275 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000276 if context and not context.event.is_set():
277 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000278 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000279 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000280 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000281 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000282 print("(%i)"%(len(l),))
283
284 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000285
286 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000287 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000288 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000289 class foo(object):pass
290 context = foo()
291 context.l = []
292 context.n = 2 #submits per thread
293 context.nThreads = n // context.n
294 context.nFinished = 0
295 context.lock = threading.Lock()
296 context.event = threading.Event()
297
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300298 threads = [threading.Thread(target=self.pendingcalls_thread,
299 args=(context,))
300 for i in range(context.nThreads)]
301 with support.start_threads(threads):
302 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000303
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000304 def pendingcalls_thread(self, context):
305 try:
306 self.pendingcalls_submit(context.l, context.n)
307 finally:
308 with context.lock:
309 context.nFinished += 1
310 nFinished = context.nFinished
311 if False and support.verbose:
312 print("finished threads: ", nFinished)
313 if nFinished == context.nThreads:
314 context.event.set()
315
Benjamin Petersona54c9092009-01-13 02:11:23 +0000316 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200317 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000318 #once. It is ok to ask for too many, because we loop until we find a slot.
319 #the loop can be interrupted to dispatch.
320 #there are only 32 dispatch slots, so we go for twice that!
321 l = []
322 n = 64
323 self.pendingcalls_submit(l, n)
324 self.pendingcalls_wait(l, n)
325
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200326
327class SubinterpreterTest(unittest.TestCase):
328
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100329 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100330 import builtins
331 r, w = os.pipe()
332 code = """if 1:
333 import sys, builtins, pickle
334 with open({:d}, "wb") as f:
335 pickle.dump(id(sys.modules), f)
336 pickle.dump(id(builtins), f)
337 """.format(w)
338 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100339 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100340 self.assertEqual(ret, 0)
341 self.assertNotEqual(pickle.load(f), id(sys.modules))
342 self.assertNotEqual(pickle.load(f), id(builtins))
343
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200344
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000345# Bug #6012
346class Test6012(unittest.TestCase):
347 def test(self):
348 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000349
Antoine Pitrou8e605772011-04-25 21:21:07 +0200350
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000351class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000352 def setUp(self):
Zachary Ware6d8a2602015-12-05 00:16:55 -0600353 here = os.path.abspath(__file__)
354 basepath = os.path.dirname(os.path.dirname(os.path.dirname(here)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000355 exename = "_testembed"
356 if sys.platform.startswith("win"):
357 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
358 exename += ext
359 exepath = os.path.dirname(sys.executable)
360 else:
Nick Coghlanbca9acf2014-09-25 19:48:15 +1000361 exepath = os.path.join(basepath, "Programs")
Nick Coghlan4e641df2013-11-03 16:54:46 +1000362 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000363 if not os.path.exists(exe):
364 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200365 # This is needed otherwise we get a fatal error:
366 # "Py_Initialize: Unable to get the locale encoding
367 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000368 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200369 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000370
371 def tearDown(self):
372 os.chdir(self.oldcwd)
373
374 def run_embedded_interpreter(self, *args):
375 """Runs a test in the embedded interpreter"""
376 cmd = [self.test_exe]
377 cmd.extend(args)
378 p = subprocess.Popen(cmd,
379 stdout=subprocess.PIPE,
Steve Dower86e9deb2014-11-01 15:11:05 -0700380 stderr=subprocess.PIPE,
381 universal_newlines=True)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000382 (out, err) = p.communicate()
383 self.assertEqual(p.returncode, 0,
384 "bad returncode %d, stderr is %r" %
385 (p.returncode, err))
Steve Dower86e9deb2014-11-01 15:11:05 -0700386 return out, err
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000387
Eric Snowd1c3c132017-05-24 17:19:47 -0700388 def run_repeated_init_and_subinterpreters(self):
Steve Dowerea74f0c2017-01-01 20:25:03 -0800389 out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
Eric Snowe3774162017-05-22 19:46:40 -0700390 self.assertEqual(err, "")
391
392 # The output from _testembed looks like this:
393 # --- Pass 0 ---
394 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
395 # interp 1 <0x1d4f690>, thread state <0x1d35350>: id(modules) = 139650431165784
396 # interp 2 <0x1d5a690>, thread state <0x1d99ed0>: id(modules) = 139650413140368
397 # interp 3 <0x1d4f690>, thread state <0x1dc3340>: id(modules) = 139650412862200
398 # interp 0 <0x1cf9330>, thread state <0x1cf9700>: id(modules) = 139650431942728
399 # --- Pass 1 ---
400 # ...
401
402 interp_pat = (r"^interp (\d+) <(0x[\dA-F]+)>, "
403 r"thread state <(0x[\dA-F]+)>: "
404 r"id\(modules\) = ([\d]+)$")
405 Interp = namedtuple("Interp", "id interp tstate modules")
406
Eric Snowe3774162017-05-22 19:46:40 -0700407 numloops = 0
Eric Snowd1c3c132017-05-24 17:19:47 -0700408 current_run = []
Eric Snowe3774162017-05-22 19:46:40 -0700409 for line in out.splitlines():
410 if line == "--- Pass {} ---".format(numloops):
Eric Snowd1c3c132017-05-24 17:19:47 -0700411 self.assertEqual(len(current_run), 0)
Eric Snowe3774162017-05-22 19:46:40 -0700412 if support.verbose:
413 print(line)
Eric Snowe3774162017-05-22 19:46:40 -0700414 numloops += 1
Eric Snowe3774162017-05-22 19:46:40 -0700415 continue
Eric Snowe3774162017-05-22 19:46:40 -0700416
Eric Snowd1c3c132017-05-24 17:19:47 -0700417 self.assertLess(len(current_run), 5)
Eric Snowe3774162017-05-22 19:46:40 -0700418 match = re.match(interp_pat, line)
419 if match is None:
420 self.assertRegex(line, interp_pat)
421
Eric Snowe3774162017-05-22 19:46:40 -0700422 # Parse the line from the loop. The first line is the main
423 # interpreter and the 3 afterward are subinterpreters.
424 interp = Interp(*match.groups())
425 if support.verbose:
426 print(interp)
Eric Snowe3774162017-05-22 19:46:40 -0700427 self.assertTrue(interp.interp)
428 self.assertTrue(interp.tstate)
429 self.assertTrue(interp.modules)
Eric Snowd1c3c132017-05-24 17:19:47 -0700430 current_run.append(interp)
431
432 # The last line in the loop should be the same as the first.
433 if len(current_run) == 5:
434 main = current_run[0]
435 self.assertEqual(interp, main)
436 yield current_run
437 current_run = []
438
439 def test_subinterps_main(self):
440 for run in self.run_repeated_init_and_subinterpreters():
441 main = run[0]
442
443 self.assertEqual(main.id, '0')
444
445 def test_subinterps_different_ids(self):
446 for run in self.run_repeated_init_and_subinterpreters():
447 main, *subs, _ = run
448
449 mainid = int(main.id)
450 for i, sub in enumerate(subs):
451 self.assertEqual(sub.id, str(mainid + i + 1))
452
453 def test_subinterps_distinct_state(self):
454 for run in self.run_repeated_init_and_subinterpreters():
455 main, *subs, _ = run
456
457 if '0x0' in main:
458 # XXX Fix on Windows (and other platforms): something
459 # is going on with the pointers in Programs/_testembed.c.
460 # interp.interp is 0x0 and interp.modules is the same
461 # between interpreters.
462 raise unittest.SkipTest('platform prints pointers as 0x0')
463
464 for sub in subs:
Eric Snowe3774162017-05-22 19:46:40 -0700465 # A new subinterpreter may have the same
466 # PyInterpreterState pointer as a previous one if
467 # the earlier one has already been destroyed. So
468 # we compare with the main interpreter. The same
469 # applies to tstate.
Eric Snowd1c3c132017-05-24 17:19:47 -0700470 self.assertNotEqual(sub.interp, main.interp)
471 self.assertNotEqual(sub.tstate, main.tstate)
472 self.assertNotEqual(sub.modules, main.modules)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000473
Nick Coghlan4e641df2013-11-03 16:54:46 +1000474 @staticmethod
475 def _get_default_pipe_encoding():
476 rp, wp = os.pipe()
477 try:
478 with os.fdopen(wp, 'w') as w:
479 default_pipe_encoding = w.encoding
480 finally:
481 os.close(rp)
482 return default_pipe_encoding
483
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000484 def test_forced_io_encoding(self):
485 # Checks forced configuration of embedded interpreter IO streams
486 out, err = self.run_embedded_interpreter("forced_io_encoding")
487 if support.verbose:
488 print()
489 print(out)
490 print(err)
Victor Stinnerb2bef622014-03-18 02:38:12 +0100491 expected_errors = sys.__stdout__.errors
Nick Coghlan4e641df2013-11-03 16:54:46 +1000492 expected_stdin_encoding = sys.__stdin__.encoding
493 expected_pipe_encoding = self._get_default_pipe_encoding()
Steve Dower86e9deb2014-11-01 15:11:05 -0700494 expected_output = '\n'.join([
Nick Coghlan4e641df2013-11-03 16:54:46 +1000495 "--- Use defaults ---",
496 "Expected encoding: default",
497 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100498 "stdin: {in_encoding}:{errors}",
499 "stdout: {out_encoding}:{errors}",
500 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000501 "--- Set errors only ---",
502 "Expected encoding: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100503 "Expected errors: ignore",
504 "stdin: {in_encoding}:ignore",
505 "stdout: {out_encoding}:ignore",
506 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000507 "--- Set encoding only ---",
508 "Expected encoding: latin-1",
509 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100510 "stdin: latin-1:{errors}",
511 "stdout: latin-1:{errors}",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000512 "stderr: latin-1:backslashreplace",
513 "--- Set encoding and errors ---",
514 "Expected encoding: latin-1",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100515 "Expected errors: replace",
516 "stdin: latin-1:replace",
517 "stdout: latin-1:replace",
518 "stderr: latin-1:backslashreplace"])
519 expected_output = expected_output.format(
520 in_encoding=expected_stdin_encoding,
521 out_encoding=expected_pipe_encoding,
522 errors=expected_errors)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000523 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000524 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000525 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200526
Victor Stinnerc4aec362016-03-14 22:26:53 +0100527
Larry Hastings8f904da2012-06-22 03:56:29 -0700528class SkipitemTest(unittest.TestCase):
529
530 def test_skipitem(self):
531 """
532 If this test failed, you probably added a new "format unit"
533 in Python/getargs.c, but neglected to update our poor friend
534 skipitem() in the same file. (If so, shame on you!)
535
Larry Hastings48ed3602012-06-22 12:58:36 -0700536 With a few exceptions**, this function brute-force tests all
537 printable ASCII*** characters (32 to 126 inclusive) as format units,
538 checking to see that PyArg_ParseTupleAndKeywords() return consistent
539 errors both when the unit is attempted to be used and when it is
540 skipped. If the format unit doesn't exist, we'll get one of two
541 specific error messages (one for used, one for skipped); if it does
542 exist we *won't* get that error--we'll get either no error or some
543 other error. If we get the specific "does not exist" error for one
544 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700545
Larry Hastings48ed3602012-06-22 12:58:36 -0700546 ** Some format units have special funny semantics and it would
Martin Panter46f50722016-05-26 05:35:26 +0000547 be difficult to accommodate them here. Since these are all
Larry Hastings48ed3602012-06-22 12:58:36 -0700548 well-established and properly skipped in skipitem() we can
549 get away with not testing them--this test is really intended
550 to catch *new* format units.
551
552 *** Python C source files must be ASCII. Therefore it's impossible
553 to have non-ASCII format units.
554
Larry Hastings8f904da2012-06-22 03:56:29 -0700555 """
556 empty_tuple = ()
557 tuple_1 = (0,)
558 dict_b = {'b':1}
559 keywords = ["a", "b"]
560
Larry Hastings48ed3602012-06-22 12:58:36 -0700561 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700562 c = chr(i)
563
Larry Hastings8f904da2012-06-22 03:56:29 -0700564 # skip parentheses, the error reporting is inconsistent about them
565 # skip 'e', it's always a two-character code
566 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700567 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700568 continue
569
570 # test the format unit when not skipped
571 format = c + "i"
572 try:
Larry Hastings8f904da2012-06-22 03:56:29 -0700573 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300574 format, keywords)
Larry Hastings8f904da2012-06-22 03:56:29 -0700575 when_not_skipped = False
Serhiy Storchaka4cd63ef2016-02-08 01:22:47 +0200576 except SystemError as e:
Serhiy Storchakac4b813d2016-02-08 01:06:11 +0200577 s = "argument 1 (impossible<bad format char>)"
Larry Hastings8f904da2012-06-22 03:56:29 -0700578 when_not_skipped = (str(e) == s)
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200579 except TypeError:
Larry Hastings8f904da2012-06-22 03:56:29 -0700580 when_not_skipped = False
581
582 # test the format unit when skipped
583 optional_format = "|" + format
584 try:
585 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300586 optional_format, keywords)
Larry Hastings8f904da2012-06-22 03:56:29 -0700587 when_skipped = False
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200588 except SystemError as e:
Larry Hastings8f904da2012-06-22 03:56:29 -0700589 s = "impossible<bad format char>: '{}'".format(format)
590 when_skipped = (str(e) == s)
591
592 message = ("test_skipitem_parity: "
593 "detected mismatch between convertsimple and skipitem "
594 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
595 c, i, when_skipped, when_not_skipped))
596 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200597
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200598 def test_parse_tuple_and_keywords(self):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300599 # Test handling errors in the parse_tuple_and_keywords helper itself
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200600 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
601 (), {}, 42, [])
602 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300603 (), {}, '', 42)
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200604 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300605 (), {}, '', [''] * 42)
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200606 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300607 (), {}, '', [42])
608
609 def test_bad_use(self):
610 # Test handling invalid format and keywords in
611 # PyArg_ParseTupleAndKeywords()
612 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
613 (1,), {}, '||O', ['a'])
614 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
615 (1, 2), {}, '|O|O', ['a', 'b'])
616 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
617 (), {'a': 1}, '$$O', ['a'])
618 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
619 (), {'a': 1, 'b': 2}, '$O$O', ['a', 'b'])
620 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
621 (), {'a': 1}, '$|O', ['a'])
622 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
623 (), {'a': 1, 'b': 2}, '$O|O', ['a', 'b'])
624 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
625 (1,), {}, '|O', ['a', 'b'])
626 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
627 (1,), {}, '|OO', ['a'])
628 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
629 (), {}, '|$O', [''])
630 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
631 (), {}, '|OO', ['a', ''])
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200632
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300633 def test_positional_only(self):
634 parse = _testcapi.parse_tuple_and_keywords
635
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300636 parse((1, 2, 3), {}, 'OOO', ['', '', 'a'])
637 parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300638 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200639 r'function takes at least 2 positional arguments \(1 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300640 parse((1,), {'a': 3}, 'OOO', ['', '', 'a'])
641 parse((1,), {}, 'O|OO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300642 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200643 r'function takes at least 1 positional arguments \(0 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300644 parse((), {}, 'O|OO', ['', '', 'a'])
645 parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300646 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200647 r'function takes exactly 2 positional arguments \(1 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300648 parse((1,), {'a': 3}, 'OO$O', ['', '', 'a'])
649 parse((1,), {}, 'O|O$O', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300650 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200651 r'function takes at least 1 positional arguments \(0 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300652 parse((), {}, 'O|O$O', ['', '', 'a'])
R David Murray44b548d2016-09-08 13:59:53 -0400653 with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300654 parse((1,), {}, 'O|$OO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300655 with self.assertRaisesRegex(SystemError, 'Empty keyword'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300656 parse((1,), {}, 'O|OO', ['', 'a', ''])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300657
Victor Stinner34be807c2016-03-14 12:04:26 +0100658
Ezio Melotti29267c82013-02-23 05:52:46 +0200659@unittest.skipUnless(threading, 'Threading required for this test.')
660class TestThreadState(unittest.TestCase):
661
662 @support.reap_threads
663 def test_thread_state(self):
664 # some extra thread-state tests driven via _testcapi
665 def target():
666 idents = []
667
668 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200669 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200670
671 _testcapi._test_thread_state(callback)
672 a = b = callback
673 time.sleep(1)
674 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200675 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200676 "Couldn't find main thread correctly in the list")
677
678 target()
679 t = threading.Thread(target=target)
680 t.start()
681 t.join()
682
Victor Stinner34be807c2016-03-14 12:04:26 +0100683
Zachary Warec12f09e2013-11-11 22:47:04 -0600684class Test_testcapi(unittest.TestCase):
685 def test__testcapi(self):
686 for name in dir(_testcapi):
687 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600688 with self.subTest("internal", name=name):
689 test = getattr(_testcapi, name)
690 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000691
Victor Stinner34be807c2016-03-14 12:04:26 +0100692
Victor Stinnerc4aec362016-03-14 22:26:53 +0100693class PyMemDebugTests(unittest.TestCase):
694 PYTHONMALLOC = 'debug'
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100695 # '0x04c06e0' or '04C06E0'
Victor Stinner08572f62016-03-14 21:55:43 +0100696 PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+'
Victor Stinner34be807c2016-03-14 12:04:26 +0100697
698 def check(self, code):
699 with support.SuppressCrashReport():
Victor Stinnerc4aec362016-03-14 22:26:53 +0100700 out = assert_python_failure('-c', code,
701 PYTHONMALLOC=self.PYTHONMALLOC)
Victor Stinner34be807c2016-03-14 12:04:26 +0100702 stderr = out.err
703 return stderr.decode('ascii', 'replace')
704
705 def test_buffer_overflow(self):
706 out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()')
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100707 regex = (r"Debug memory block at address p={ptr}: API 'm'\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100708 r" 16 bytes originally requested\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100709 r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n"
710 r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100711 r" at tail\+0: 0x78 \*\*\* OUCH\n"
712 r" at tail\+1: 0xfb\n"
713 r" at tail\+2: 0xfb\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100714 r" .*\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100715 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100716 r" Data at p: cb cb cb .*\n"
Victor Stinner6453e9e2016-03-15 23:36:28 +0100717 r"\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100718 r"Fatal Python error: bad trailing pad byte")
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100719 regex = regex.format(ptr=self.PTR_REGEX)
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100720 regex = re.compile(regex, flags=re.DOTALL)
Victor Stinner34be807c2016-03-14 12:04:26 +0100721 self.assertRegex(out, regex)
722
723 def test_api_misuse(self):
724 out = self.check('import _testcapi; _testcapi.pymem_api_misuse()')
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100725 regex = (r"Debug memory block at address p={ptr}: API 'm'\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100726 r" 16 bytes originally requested\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100727 r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n"
728 r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100729 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100730 r" Data at p: cb cb cb .*\n"
Victor Stinner6453e9e2016-03-15 23:36:28 +0100731 r"\n"
Victor Stinner34be807c2016-03-14 12:04:26 +0100732 r"Fatal Python error: bad ID: Allocated using API 'm', verified using API 'r'\n")
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100733 regex = regex.format(ptr=self.PTR_REGEX)
Victor Stinner34be807c2016-03-14 12:04:26 +0100734 self.assertRegex(out, regex)
735
Martin Panter56b2cf52016-10-20 21:45:49 +0000736 @unittest.skipUnless(threading, 'Test requires a GIL (multithreading)')
Victor Stinnerad524372016-03-16 12:12:53 +0100737 def check_malloc_without_gil(self, code):
Victor Stinnerc4aec362016-03-14 22:26:53 +0100738 out = self.check(code)
739 expected = ('Fatal Python error: Python memory allocator called '
740 'without holding the GIL')
741 self.assertIn(expected, out)
Victor Stinner34be807c2016-03-14 12:04:26 +0100742
Victor Stinnerad524372016-03-16 12:12:53 +0100743 def test_pymem_malloc_without_gil(self):
744 # Debug hooks must raise an error if PyMem_Malloc() is called
745 # without holding the GIL
746 code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()'
747 self.check_malloc_without_gil(code)
748
749 def test_pyobject_malloc_without_gil(self):
750 # Debug hooks must raise an error if PyObject_Malloc() is called
751 # without holding the GIL
752 code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()'
753 self.check_malloc_without_gil(code)
754
Victor Stinnerc4aec362016-03-14 22:26:53 +0100755
756class PyMemMallocDebugTests(PyMemDebugTests):
757 PYTHONMALLOC = 'malloc_debug'
Victor Stinner34be807c2016-03-14 12:04:26 +0100758
759
760@unittest.skipUnless(sysconfig.get_config_var('WITH_PYMALLOC') == 1,
761 'need pymalloc')
Victor Stinnerc4aec362016-03-14 22:26:53 +0100762class PyMemPymallocDebugTests(PyMemDebugTests):
763 PYTHONMALLOC = 'pymalloc_debug'
Victor Stinner34be807c2016-03-14 12:04:26 +0100764
765
766@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG')
Victor Stinnerc4aec362016-03-14 22:26:53 +0100767class PyMemDefaultTests(PyMemDebugTests):
768 # test default allocator of Python compiled in debug mode
769 PYTHONMALLOC = ''
Victor Stinner34be807c2016-03-14 12:04:26 +0100770
771
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000772if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600773 unittest.main()