blob: 10e8c4e216a366177a3b9df101d21809c30b6132 [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 Hastings581ee362014-01-28 05:00:08 -0800129 "sig= (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
135 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
136 "This docstring has a valid signature.")
Larry Hastings5c661892014-01-24 06:17:25 -0800137 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(module, sig)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800138
139 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
140 "This docstring has a valid signature and some extra newlines.")
141 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings5c661892014-01-24 06:17:25 -0800142 "(module, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800143
144
Victor Stinner45df8202010-04-28 22:31:17 +0000145@unittest.skipUnless(threading, 'Threading required for this test.')
Benjamin Petersona54c9092009-01-13 02:11:23 +0000146class TestPendingCalls(unittest.TestCase):
147
148 def pendingcalls_submit(self, l, n):
149 def callback():
150 #this function can be interrupted by thread switching so let's
151 #use an atomic operation
152 l.append(None)
153
154 for i in range(n):
155 time.sleep(random.random()*0.02) #0.01 secs on average
156 #try submitting callback until successful.
157 #rely on regular interrupt to flush queue if we are
158 #unsuccessful.
159 while True:
160 if _testcapi._pending_threadfunc(callback):
161 break;
162
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000163 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000164 #now, stick around until l[0] has grown to 10
165 count = 0;
166 while len(l) != n:
167 #this busy loop is where we expect to be interrupted to
168 #run our callbacks. Note that callbacks are only run on the
169 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000170 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000171 print("(%i)"%(len(l),),)
172 for i in range(1000):
173 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000174 if context and not context.event.is_set():
175 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000176 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000177 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000178 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
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
182 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000183
184 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000185 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000186 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000187 class foo(object):pass
188 context = foo()
189 context.l = []
190 context.n = 2 #submits per thread
191 context.nThreads = n // context.n
192 context.nFinished = 0
193 context.lock = threading.Lock()
194 context.event = threading.Event()
195
196 for i in range(context.nThreads):
197 t = threading.Thread(target=self.pendingcalls_thread, args = (context,))
Benjamin Petersona54c9092009-01-13 02:11:23 +0000198 t.start()
199 threads.append(t)
200
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000201 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000202
203 for t in threads:
204 t.join()
205
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000206 def pendingcalls_thread(self, context):
207 try:
208 self.pendingcalls_submit(context.l, context.n)
209 finally:
210 with context.lock:
211 context.nFinished += 1
212 nFinished = context.nFinished
213 if False and support.verbose:
214 print("finished threads: ", nFinished)
215 if nFinished == context.nThreads:
216 context.event.set()
217
Benjamin Petersona54c9092009-01-13 02:11:23 +0000218 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200219 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000220 #once. It is ok to ask for too many, because we loop until we find a slot.
221 #the loop can be interrupted to dispatch.
222 #there are only 32 dispatch slots, so we go for twice that!
223 l = []
224 n = 64
225 self.pendingcalls_submit(l, n)
226 self.pendingcalls_wait(l, n)
227
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200228
229class SubinterpreterTest(unittest.TestCase):
230
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100231 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100232 import builtins
233 r, w = os.pipe()
234 code = """if 1:
235 import sys, builtins, pickle
236 with open({:d}, "wb") as f:
237 pickle.dump(id(sys.modules), f)
238 pickle.dump(id(builtins), f)
239 """.format(w)
240 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100241 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100242 self.assertEqual(ret, 0)
243 self.assertNotEqual(pickle.load(f), id(sys.modules))
244 self.assertNotEqual(pickle.load(f), id(builtins))
245
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200246
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000247# Bug #6012
248class Test6012(unittest.TestCase):
249 def test(self):
250 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000251
Antoine Pitrou8e605772011-04-25 21:21:07 +0200252
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000253class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000254 def setUp(self):
Antoine Pitrou8e605772011-04-25 21:21:07 +0200255 basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000256 exename = "_testembed"
257 if sys.platform.startswith("win"):
258 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
259 exename += ext
260 exepath = os.path.dirname(sys.executable)
261 else:
262 exepath = os.path.join(basepath, "Modules")
263 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000264 if not os.path.exists(exe):
265 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200266 # This is needed otherwise we get a fatal error:
267 # "Py_Initialize: Unable to get the locale encoding
268 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000269 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200270 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000271
272 def tearDown(self):
273 os.chdir(self.oldcwd)
274
275 def run_embedded_interpreter(self, *args):
276 """Runs a test in the embedded interpreter"""
277 cmd = [self.test_exe]
278 cmd.extend(args)
279 p = subprocess.Popen(cmd,
280 stdout=subprocess.PIPE,
281 stderr=subprocess.PIPE)
282 (out, err) = p.communicate()
283 self.assertEqual(p.returncode, 0,
284 "bad returncode %d, stderr is %r" %
285 (p.returncode, err))
286 return out.decode("latin1"), err.decode("latin1")
287
288 def test_subinterps(self):
289 # This is just a "don't crash" test
290 out, err = self.run_embedded_interpreter()
291 if support.verbose:
292 print()
293 print(out)
294 print(err)
295
Nick Coghlan4e641df2013-11-03 16:54:46 +1000296 @staticmethod
297 def _get_default_pipe_encoding():
298 rp, wp = os.pipe()
299 try:
300 with os.fdopen(wp, 'w') as w:
301 default_pipe_encoding = w.encoding
302 finally:
303 os.close(rp)
304 return default_pipe_encoding
305
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000306 def test_forced_io_encoding(self):
307 # Checks forced configuration of embedded interpreter IO streams
308 out, err = self.run_embedded_interpreter("forced_io_encoding")
309 if support.verbose:
310 print()
311 print(out)
312 print(err)
Nick Coghlan4e641df2013-11-03 16:54:46 +1000313 expected_stdin_encoding = sys.__stdin__.encoding
314 expected_pipe_encoding = self._get_default_pipe_encoding()
315 expected_output = os.linesep.join([
316 "--- Use defaults ---",
317 "Expected encoding: default",
318 "Expected errors: default",
319 "stdin: {0}:strict",
320 "stdout: {1}:strict",
321 "stderr: {1}:backslashreplace",
322 "--- Set errors only ---",
323 "Expected encoding: default",
324 "Expected errors: surrogateescape",
325 "stdin: {0}:surrogateescape",
326 "stdout: {1}:surrogateescape",
327 "stderr: {1}:backslashreplace",
328 "--- Set encoding only ---",
329 "Expected encoding: latin-1",
330 "Expected errors: default",
331 "stdin: latin-1:strict",
332 "stdout: latin-1:strict",
333 "stderr: latin-1:backslashreplace",
334 "--- Set encoding and errors ---",
335 "Expected encoding: latin-1",
336 "Expected errors: surrogateescape",
337 "stdin: latin-1:surrogateescape",
338 "stdout: latin-1:surrogateescape",
339 "stderr: latin-1:backslashreplace"]).format(expected_stdin_encoding,
340 expected_pipe_encoding)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000341 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000342 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000343 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200344
Larry Hastings8f904da2012-06-22 03:56:29 -0700345class SkipitemTest(unittest.TestCase):
346
347 def test_skipitem(self):
348 """
349 If this test failed, you probably added a new "format unit"
350 in Python/getargs.c, but neglected to update our poor friend
351 skipitem() in the same file. (If so, shame on you!)
352
Larry Hastings48ed3602012-06-22 12:58:36 -0700353 With a few exceptions**, this function brute-force tests all
354 printable ASCII*** characters (32 to 126 inclusive) as format units,
355 checking to see that PyArg_ParseTupleAndKeywords() return consistent
356 errors both when the unit is attempted to be used and when it is
357 skipped. If the format unit doesn't exist, we'll get one of two
358 specific error messages (one for used, one for skipped); if it does
359 exist we *won't* get that error--we'll get either no error or some
360 other error. If we get the specific "does not exist" error for one
361 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700362
Larry Hastings48ed3602012-06-22 12:58:36 -0700363 ** Some format units have special funny semantics and it would
364 be difficult to accomodate them here. Since these are all
365 well-established and properly skipped in skipitem() we can
366 get away with not testing them--this test is really intended
367 to catch *new* format units.
368
369 *** Python C source files must be ASCII. Therefore it's impossible
370 to have non-ASCII format units.
371
Larry Hastings8f904da2012-06-22 03:56:29 -0700372 """
373 empty_tuple = ()
374 tuple_1 = (0,)
375 dict_b = {'b':1}
376 keywords = ["a", "b"]
377
Larry Hastings48ed3602012-06-22 12:58:36 -0700378 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700379 c = chr(i)
380
Larry Hastings8f904da2012-06-22 03:56:29 -0700381 # skip parentheses, the error reporting is inconsistent about them
382 # skip 'e', it's always a two-character code
383 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700384 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700385 continue
386
387 # test the format unit when not skipped
388 format = c + "i"
389 try:
390 # (note: the format string must be bytes!)
391 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
392 format.encode("ascii"), keywords)
393 when_not_skipped = False
394 except TypeError as e:
395 s = "argument 1 must be impossible<bad format char>, not int"
396 when_not_skipped = (str(e) == s)
397 except RuntimeError as e:
398 when_not_skipped = False
399
400 # test the format unit when skipped
401 optional_format = "|" + format
402 try:
403 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
404 optional_format.encode("ascii"), keywords)
405 when_skipped = False
406 except RuntimeError as e:
407 s = "impossible<bad format char>: '{}'".format(format)
408 when_skipped = (str(e) == s)
409
410 message = ("test_skipitem_parity: "
411 "detected mismatch between convertsimple and skipitem "
412 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
413 c, i, when_skipped, when_not_skipped))
414 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200415
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200416 def test_parse_tuple_and_keywords(self):
417 # parse_tuple_and_keywords error handling tests
418 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
419 (), {}, 42, [])
420 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
421 (), {}, b'', 42)
422 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
423 (), {}, b'', [''] * 42)
424 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
425 (), {}, b'', [42])
426
Ezio Melotti29267c82013-02-23 05:52:46 +0200427@unittest.skipUnless(threading, 'Threading required for this test.')
428class TestThreadState(unittest.TestCase):
429
430 @support.reap_threads
431 def test_thread_state(self):
432 # some extra thread-state tests driven via _testcapi
433 def target():
434 idents = []
435
436 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200437 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200438
439 _testcapi._test_thread_state(callback)
440 a = b = callback
441 time.sleep(1)
442 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200443 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200444 "Couldn't find main thread correctly in the list")
445
446 target()
447 t = threading.Thread(target=target)
448 t.start()
449 t.join()
450
Zachary Warec12f09e2013-11-11 22:47:04 -0600451class Test_testcapi(unittest.TestCase):
452 def test__testcapi(self):
453 for name in dir(_testcapi):
454 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600455 with self.subTest("internal", name=name):
456 test = getattr(_testcapi, name)
457 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000458
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000459if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600460 unittest.main()