blob: 36c62376b1577cff0d81113fb707c383ffaad2ae [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
Antoine Pitrou8e605772011-04-25 21:21:07 +02004import os
Antoine Pitrou2f828f22012-01-18 00:21:11 +01005import pickle
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +00006import random
7import subprocess
Martin v. Löwis6ce7ed22005-03-03 12:26:35 +00008import sys
Benjamin Petersona54c9092009-01-13 02:11:23 +00009import time
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000010import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000011from test import support
Larry Hastingsfcafe432013-11-23 17:35:48 -080012from test.support import MISSING_C_DOCSTRINGS
Victor Stinner45df8202010-04-28 22:31:17 +000013try:
Stefan Krahfd24f9e2012-08-20 11:04:24 +020014 import _posixsubprocess
15except ImportError:
16 _posixsubprocess = None
17try:
Victor Stinner45df8202010-04-28 22:31:17 +000018 import threading
19except ImportError:
20 threading = None
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020021# Skip this test if the _testcapi module isn't available.
22_testcapi = support.import_module('_testcapi')
Tim Peters9ea17ac2001-02-02 05:57:15 +000023
Benjamin Petersona54c9092009-01-13 02:11:23 +000024
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000025def testfunction(self):
26 """some doc"""
27 return self
28
29class InstanceMethod:
30 id = _testcapi.instancemethod(id)
31 testfunction = _testcapi.instancemethod(testfunction)
32
33class CAPITest(unittest.TestCase):
34
35 def test_instancemethod(self):
36 inst = InstanceMethod()
37 self.assertEqual(id(inst), inst.id())
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000038 self.assertTrue(inst.testfunction() is inst)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000039 self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__)
40 self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__)
41
42 InstanceMethod.testfunction.attribute = "test"
43 self.assertEqual(testfunction.attribute, "test")
44 self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
45
Stefan Krah0ca46242010-06-09 08:56:28 +000046 @unittest.skipUnless(threading, 'Threading required for this test.')
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000047 def test_no_FatalError_infinite_loop(self):
Antoine Pitrou77e904e2013-10-08 23:04:32 +020048 with support.SuppressCrashReport():
Ezio Melotti25a40452013-03-05 20:26:17 +020049 p = subprocess.Popen([sys.executable, "-c",
Ezio Melottie1857d92013-03-05 20:31:34 +020050 'import _testcapi;'
51 '_testcapi.crash_no_current_thread()'],
52 stdout=subprocess.PIPE,
53 stderr=subprocess.PIPE)
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000054 (out, err) = p.communicate()
55 self.assertEqual(out, b'')
56 # This used to cause an infinite loop.
Vinay Sajip73954042012-05-06 11:34:50 +010057 self.assertTrue(err.rstrip().startswith(
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000058 b'Fatal Python error:'
Vinay Sajip73954042012-05-06 11:34:50 +010059 b' PyThreadState_Get: no current thread'))
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000060
Antoine Pitrou915605c2011-02-24 20:53:48 +000061 def test_memoryview_from_NULL_pointer(self):
62 self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000063
Martin v. Löwisaa2efcb2012-04-19 14:33:43 +020064 def test_exc_info(self):
65 raised_exception = ValueError("5")
66 new_exc = TypeError("TEST")
67 try:
68 raise raised_exception
69 except ValueError as e:
70 tb = e.__traceback__
71 orig_sys_exc_info = sys.exc_info()
72 orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
73 new_sys_exc_info = sys.exc_info()
74 new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
75 reset_sys_exc_info = sys.exc_info()
76
77 self.assertEqual(orig_exc_info[1], e)
78
79 self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
80 self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
81 self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
82 self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
83 self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
84 else:
85 self.assertTrue(False)
86
Stefan Krahfd24f9e2012-08-20 11:04:24 +020087 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
88 def test_seq_bytes_to_charp_array(self):
89 # Issue #15732: crash in _PySequence_BytesToCharpArray()
90 class Z(object):
91 def __len__(self):
92 return 1
93 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
94 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 +020095 # Issue #15736: overflow in _PySequence_BytesToCharpArray()
96 class Z(object):
97 def __len__(self):
98 return sys.maxsize
99 def __getitem__(self, i):
100 return b'x'
101 self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
102 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 +0200103
Stefan Krahdb579d72012-08-20 14:36:47 +0200104 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
105 def test_subprocess_fork_exec(self):
106 class Z(object):
107 def __len__(self):
108 return 1
109
110 # Issue #15738: crash in subprocess_fork_exec()
111 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
112 Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
113
Larry Hastingsfcafe432013-11-23 17:35:48 -0800114 @unittest.skipIf(MISSING_C_DOCSTRINGS,
115 "Signature information for builtins requires docstrings")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800116 def test_docstring_signature_parsing(self):
117
118 self.assertEqual(_testcapi.no_docstring.__doc__, None)
119 self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
120
121 self.assertEqual(_testcapi.docstring_empty.__doc__, "")
122 self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
123
124 self.assertEqual(_testcapi.docstring_no_signature.__doc__,
125 "This docstring has no signature.")
126 self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
127
128 self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800129 "docstring_with_invalid_signature($module, /, boo)\n"
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800130 "\n"
131 "This docstring has an invalid signature."
132 )
133 self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
134
Larry Hastings2623c8c2014-02-08 22:15:29 -0800135 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__,
136 "docstring_with_invalid_signature2($module, /, boo)\n"
137 "\n"
138 "--\n"
139 "\n"
140 "This docstring also has an invalid signature."
141 )
142 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None)
143
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800144 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
145 "This docstring has a valid signature.")
Larry Hastings2623c8c2014-02-08 22:15:29 -0800146 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800147
148 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800149 "\nThis docstring has a valid signature and some extra newlines.")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800150 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800151 "($module, /, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800152
153
Victor Stinner45df8202010-04-28 22:31:17 +0000154@unittest.skipUnless(threading, 'Threading required for this test.')
Benjamin Petersona54c9092009-01-13 02:11:23 +0000155class TestPendingCalls(unittest.TestCase):
156
157 def pendingcalls_submit(self, l, n):
158 def callback():
159 #this function can be interrupted by thread switching so let's
160 #use an atomic operation
161 l.append(None)
162
163 for i in range(n):
164 time.sleep(random.random()*0.02) #0.01 secs on average
165 #try submitting callback until successful.
166 #rely on regular interrupt to flush queue if we are
167 #unsuccessful.
168 while True:
169 if _testcapi._pending_threadfunc(callback):
170 break;
171
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000172 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000173 #now, stick around until l[0] has grown to 10
174 count = 0;
175 while len(l) != n:
176 #this busy loop is where we expect to be interrupted to
177 #run our callbacks. Note that callbacks are only run on the
178 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000179 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000180 print("(%i)"%(len(l),),)
181 for i in range(1000):
182 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000183 if context and not context.event.is_set():
184 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000185 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000186 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000187 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000188 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000189 print("(%i)"%(len(l),))
190
191 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000192
193 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000194 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000195 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000196 class foo(object):pass
197 context = foo()
198 context.l = []
199 context.n = 2 #submits per thread
200 context.nThreads = n // context.n
201 context.nFinished = 0
202 context.lock = threading.Lock()
203 context.event = threading.Event()
204
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300205 threads = [threading.Thread(target=self.pendingcalls_thread,
206 args=(context,))
207 for i in range(context.nThreads)]
208 with support.start_threads(threads):
209 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000210
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000211 def pendingcalls_thread(self, context):
212 try:
213 self.pendingcalls_submit(context.l, context.n)
214 finally:
215 with context.lock:
216 context.nFinished += 1
217 nFinished = context.nFinished
218 if False and support.verbose:
219 print("finished threads: ", nFinished)
220 if nFinished == context.nThreads:
221 context.event.set()
222
Benjamin Petersona54c9092009-01-13 02:11:23 +0000223 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200224 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000225 #once. It is ok to ask for too many, because we loop until we find a slot.
226 #the loop can be interrupted to dispatch.
227 #there are only 32 dispatch slots, so we go for twice that!
228 l = []
229 n = 64
230 self.pendingcalls_submit(l, n)
231 self.pendingcalls_wait(l, n)
232
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200233
234class SubinterpreterTest(unittest.TestCase):
235
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100236 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100237 import builtins
238 r, w = os.pipe()
239 code = """if 1:
240 import sys, builtins, pickle
241 with open({:d}, "wb") as f:
242 pickle.dump(id(sys.modules), f)
243 pickle.dump(id(builtins), f)
244 """.format(w)
245 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100246 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100247 self.assertEqual(ret, 0)
248 self.assertNotEqual(pickle.load(f), id(sys.modules))
249 self.assertNotEqual(pickle.load(f), id(builtins))
250
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200251
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000252# Bug #6012
253class Test6012(unittest.TestCase):
254 def test(self):
255 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000256
Antoine Pitrou8e605772011-04-25 21:21:07 +0200257
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000258class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000259 def setUp(self):
Antoine Pitrou8e605772011-04-25 21:21:07 +0200260 basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000261 exename = "_testembed"
262 if sys.platform.startswith("win"):
263 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
264 exename += ext
265 exepath = os.path.dirname(sys.executable)
266 else:
267 exepath = os.path.join(basepath, "Modules")
268 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000269 if not os.path.exists(exe):
270 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200271 # This is needed otherwise we get a fatal error:
272 # "Py_Initialize: Unable to get the locale encoding
273 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000274 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200275 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000276
277 def tearDown(self):
278 os.chdir(self.oldcwd)
279
280 def run_embedded_interpreter(self, *args):
281 """Runs a test in the embedded interpreter"""
282 cmd = [self.test_exe]
283 cmd.extend(args)
284 p = subprocess.Popen(cmd,
285 stdout=subprocess.PIPE,
286 stderr=subprocess.PIPE)
287 (out, err) = p.communicate()
288 self.assertEqual(p.returncode, 0,
289 "bad returncode %d, stderr is %r" %
290 (p.returncode, err))
291 return out.decode("latin1"), err.decode("latin1")
292
293 def test_subinterps(self):
294 # This is just a "don't crash" test
295 out, err = self.run_embedded_interpreter()
296 if support.verbose:
297 print()
298 print(out)
299 print(err)
300
Nick Coghlan4e641df2013-11-03 16:54:46 +1000301 @staticmethod
302 def _get_default_pipe_encoding():
303 rp, wp = os.pipe()
304 try:
305 with os.fdopen(wp, 'w') as w:
306 default_pipe_encoding = w.encoding
307 finally:
308 os.close(rp)
309 return default_pipe_encoding
310
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000311 def test_forced_io_encoding(self):
312 # Checks forced configuration of embedded interpreter IO streams
313 out, err = self.run_embedded_interpreter("forced_io_encoding")
314 if support.verbose:
315 print()
316 print(out)
317 print(err)
Nick Coghlan4e641df2013-11-03 16:54:46 +1000318 expected_stdin_encoding = sys.__stdin__.encoding
319 expected_pipe_encoding = self._get_default_pipe_encoding()
320 expected_output = os.linesep.join([
321 "--- Use defaults ---",
322 "Expected encoding: default",
323 "Expected errors: default",
324 "stdin: {0}:strict",
325 "stdout: {1}:strict",
326 "stderr: {1}:backslashreplace",
327 "--- Set errors only ---",
328 "Expected encoding: default",
329 "Expected errors: surrogateescape",
330 "stdin: {0}:surrogateescape",
331 "stdout: {1}:surrogateescape",
332 "stderr: {1}:backslashreplace",
333 "--- Set encoding only ---",
334 "Expected encoding: latin-1",
335 "Expected errors: default",
336 "stdin: latin-1:strict",
337 "stdout: latin-1:strict",
338 "stderr: latin-1:backslashreplace",
339 "--- Set encoding and errors ---",
340 "Expected encoding: latin-1",
341 "Expected errors: surrogateescape",
342 "stdin: latin-1:surrogateescape",
343 "stdout: latin-1:surrogateescape",
344 "stderr: latin-1:backslashreplace"]).format(expected_stdin_encoding,
345 expected_pipe_encoding)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000346 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000347 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000348 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200349
Larry Hastings8f904da2012-06-22 03:56:29 -0700350class SkipitemTest(unittest.TestCase):
351
352 def test_skipitem(self):
353 """
354 If this test failed, you probably added a new "format unit"
355 in Python/getargs.c, but neglected to update our poor friend
356 skipitem() in the same file. (If so, shame on you!)
357
Larry Hastings48ed3602012-06-22 12:58:36 -0700358 With a few exceptions**, this function brute-force tests all
359 printable ASCII*** characters (32 to 126 inclusive) as format units,
360 checking to see that PyArg_ParseTupleAndKeywords() return consistent
361 errors both when the unit is attempted to be used and when it is
362 skipped. If the format unit doesn't exist, we'll get one of two
363 specific error messages (one for used, one for skipped); if it does
364 exist we *won't* get that error--we'll get either no error or some
365 other error. If we get the specific "does not exist" error for one
366 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700367
Larry Hastings48ed3602012-06-22 12:58:36 -0700368 ** Some format units have special funny semantics and it would
369 be difficult to accomodate them here. Since these are all
370 well-established and properly skipped in skipitem() we can
371 get away with not testing them--this test is really intended
372 to catch *new* format units.
373
374 *** Python C source files must be ASCII. Therefore it's impossible
375 to have non-ASCII format units.
376
Larry Hastings8f904da2012-06-22 03:56:29 -0700377 """
378 empty_tuple = ()
379 tuple_1 = (0,)
380 dict_b = {'b':1}
381 keywords = ["a", "b"]
382
Larry Hastings48ed3602012-06-22 12:58:36 -0700383 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700384 c = chr(i)
385
Larry Hastings8f904da2012-06-22 03:56:29 -0700386 # skip parentheses, the error reporting is inconsistent about them
387 # skip 'e', it's always a two-character code
388 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700389 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700390 continue
391
392 # test the format unit when not skipped
393 format = c + "i"
394 try:
395 # (note: the format string must be bytes!)
396 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
397 format.encode("ascii"), keywords)
398 when_not_skipped = False
399 except TypeError as e:
400 s = "argument 1 must be impossible<bad format char>, not int"
401 when_not_skipped = (str(e) == s)
402 except RuntimeError as e:
403 when_not_skipped = False
404
405 # test the format unit when skipped
406 optional_format = "|" + format
407 try:
408 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
409 optional_format.encode("ascii"), keywords)
410 when_skipped = False
411 except RuntimeError as e:
412 s = "impossible<bad format char>: '{}'".format(format)
413 when_skipped = (str(e) == s)
414
415 message = ("test_skipitem_parity: "
416 "detected mismatch between convertsimple and skipitem "
417 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
418 c, i, when_skipped, when_not_skipped))
419 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200420
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200421 def test_parse_tuple_and_keywords(self):
422 # parse_tuple_and_keywords error handling tests
423 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
424 (), {}, 42, [])
425 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
426 (), {}, b'', 42)
427 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
428 (), {}, b'', [''] * 42)
429 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
430 (), {}, b'', [42])
431
Ezio Melotti29267c82013-02-23 05:52:46 +0200432@unittest.skipUnless(threading, 'Threading required for this test.')
433class TestThreadState(unittest.TestCase):
434
435 @support.reap_threads
436 def test_thread_state(self):
437 # some extra thread-state tests driven via _testcapi
438 def target():
439 idents = []
440
441 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200442 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200443
444 _testcapi._test_thread_state(callback)
445 a = b = callback
446 time.sleep(1)
447 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200448 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200449 "Couldn't find main thread correctly in the list")
450
451 target()
452 t = threading.Thread(target=target)
453 t.start()
454 t.join()
455
Zachary Warec12f09e2013-11-11 22:47:04 -0600456class Test_testcapi(unittest.TestCase):
457 def test__testcapi(self):
458 for name in dir(_testcapi):
459 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600460 with self.subTest("internal", name=name):
461 test = getattr(_testcapi, name)
462 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000463
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000464if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600465 unittest.main()