blob: dff717b5e05cfab00b9e4ae02bf524e7056c4beb [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
Victor Stinnerefde1462015-03-21 15:04:43 +01009import textwrap
Benjamin Petersona54c9092009-01-13 02:11:23 +000010import time
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000011import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000012from test import support
Larry Hastingsfcafe432013-11-23 17:35:48 -080013from test.support import MISSING_C_DOCSTRINGS
Victor Stinnerefde1462015-03-21 15:04:43 +010014from test.script_helper import assert_python_failure
Victor Stinner45df8202010-04-28 22:31:17 +000015try:
Stefan Krahfd24f9e2012-08-20 11:04:24 +020016 import _posixsubprocess
17except ImportError:
18 _posixsubprocess = None
19try:
Victor Stinner45df8202010-04-28 22:31:17 +000020 import threading
21except ImportError:
22 threading = None
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020023# Skip this test if the _testcapi module isn't available.
24_testcapi = support.import_module('_testcapi')
Tim Peters9ea17ac2001-02-02 05:57:15 +000025
Victor Stinnerefde1462015-03-21 15:04:43 +010026# Were we compiled --with-pydebug or with #define Py_DEBUG?
27Py_DEBUG = hasattr(sys, 'gettotalrefcount')
28
Benjamin Petersona54c9092009-01-13 02:11:23 +000029
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000030def testfunction(self):
31 """some doc"""
32 return self
33
34class InstanceMethod:
35 id = _testcapi.instancemethod(id)
36 testfunction = _testcapi.instancemethod(testfunction)
37
38class CAPITest(unittest.TestCase):
39
40 def test_instancemethod(self):
41 inst = InstanceMethod()
42 self.assertEqual(id(inst), inst.id())
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000043 self.assertTrue(inst.testfunction() is inst)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000044 self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__)
45 self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__)
46
47 InstanceMethod.testfunction.attribute = "test"
48 self.assertEqual(testfunction.attribute, "test")
49 self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
50
Stefan Krah0ca46242010-06-09 08:56:28 +000051 @unittest.skipUnless(threading, 'Threading required for this test.')
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000052 def test_no_FatalError_infinite_loop(self):
Antoine Pitrou77e904e2013-10-08 23:04:32 +020053 with support.SuppressCrashReport():
Ezio Melotti25a40452013-03-05 20:26:17 +020054 p = subprocess.Popen([sys.executable, "-c",
Ezio Melottie1857d92013-03-05 20:31:34 +020055 'import _testcapi;'
56 '_testcapi.crash_no_current_thread()'],
57 stdout=subprocess.PIPE,
58 stderr=subprocess.PIPE)
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000059 (out, err) = p.communicate()
60 self.assertEqual(out, b'')
61 # This used to cause an infinite loop.
Vinay Sajip73954042012-05-06 11:34:50 +010062 self.assertTrue(err.rstrip().startswith(
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000063 b'Fatal Python error:'
Vinay Sajip73954042012-05-06 11:34:50 +010064 b' PyThreadState_Get: no current thread'))
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000065
Antoine Pitrou915605c2011-02-24 20:53:48 +000066 def test_memoryview_from_NULL_pointer(self):
67 self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000068
Martin v. Löwisaa2efcb2012-04-19 14:33:43 +020069 def test_exc_info(self):
70 raised_exception = ValueError("5")
71 new_exc = TypeError("TEST")
72 try:
73 raise raised_exception
74 except ValueError as e:
75 tb = e.__traceback__
76 orig_sys_exc_info = sys.exc_info()
77 orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
78 new_sys_exc_info = sys.exc_info()
79 new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
80 reset_sys_exc_info = sys.exc_info()
81
82 self.assertEqual(orig_exc_info[1], e)
83
84 self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
85 self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
86 self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
87 self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
88 self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
89 else:
90 self.assertTrue(False)
91
Stefan Krahfd24f9e2012-08-20 11:04:24 +020092 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
93 def test_seq_bytes_to_charp_array(self):
94 # Issue #15732: crash in _PySequence_BytesToCharpArray()
95 class Z(object):
96 def __len__(self):
97 return 1
98 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
99 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 +0200100 # Issue #15736: overflow in _PySequence_BytesToCharpArray()
101 class Z(object):
102 def __len__(self):
103 return sys.maxsize
104 def __getitem__(self, i):
105 return b'x'
106 self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
107 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 +0200108
Stefan Krahdb579d72012-08-20 14:36:47 +0200109 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
110 def test_subprocess_fork_exec(self):
111 class Z(object):
112 def __len__(self):
113 return 1
114
115 # Issue #15738: crash in subprocess_fork_exec()
116 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
117 Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
118
Larry Hastingsfcafe432013-11-23 17:35:48 -0800119 @unittest.skipIf(MISSING_C_DOCSTRINGS,
120 "Signature information for builtins requires docstrings")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800121 def test_docstring_signature_parsing(self):
122
123 self.assertEqual(_testcapi.no_docstring.__doc__, None)
124 self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
125
126 self.assertEqual(_testcapi.docstring_empty.__doc__, "")
127 self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
128
129 self.assertEqual(_testcapi.docstring_no_signature.__doc__,
130 "This docstring has no signature.")
131 self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
132
133 self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800134 "docstring_with_invalid_signature($module, /, boo)\n"
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800135 "\n"
136 "This docstring has an invalid signature."
137 )
138 self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
139
Larry Hastings2623c8c2014-02-08 22:15:29 -0800140 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__,
141 "docstring_with_invalid_signature2($module, /, boo)\n"
142 "\n"
143 "--\n"
144 "\n"
145 "This docstring also has an invalid signature."
146 )
147 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None)
148
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800149 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
150 "This docstring has a valid signature.")
Larry Hastings2623c8c2014-02-08 22:15:29 -0800151 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800152
153 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800154 "\nThis docstring has a valid signature and some extra newlines.")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800155 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800156 "($module, /, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800157
Benjamin Petersond51374e2014-04-09 23:55:56 -0400158 def test_c_type_with_matrix_multiplication(self):
159 M = _testcapi.matmulType
160 m1 = M()
161 m2 = M()
162 self.assertEqual(m1 @ m2, ("matmul", m1, m2))
163 self.assertEqual(m1 @ 42, ("matmul", m1, 42))
164 self.assertEqual(42 @ m1, ("matmul", 42, m1))
165 o = m1
166 o @= m2
167 self.assertEqual(o, ("imatmul", m1, m2))
168 o = m1
169 o @= 42
170 self.assertEqual(o, ("imatmul", m1, 42))
171 o = 42
172 o @= m1
173 self.assertEqual(o, ("matmul", 42, m1))
174
Victor Stinnerefde1462015-03-21 15:04:43 +0100175 def test_return_null_without_error(self):
176 # Issue #23571: A function must not return NULL without setting an
177 # error
178 if Py_DEBUG:
179 code = textwrap.dedent("""
180 import _testcapi
181 from test import support
182
183 with support.SuppressCrashReport():
184 _testcapi.return_null_without_error()
185 """)
186 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100187 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100188 br'Fatal Python error: a function returned NULL '
189 br'without setting an error\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100190 br'SystemError: <built-in function '
191 br'return_null_without_error> returned NULL '
192 br'without setting an error\n'
193 br'\n'
194 br'Current thread.*:\n'
195 br' File .*", line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100196 else:
197 with self.assertRaises(SystemError) as cm:
198 _testcapi.return_null_without_error()
199 self.assertRegex(str(cm.exception),
200 'return_null_without_error.* '
201 'returned NULL without setting an error')
202
203 def test_return_result_with_error(self):
204 # Issue #23571: A function must not return a result with an error set
205 if Py_DEBUG:
206 code = textwrap.dedent("""
207 import _testcapi
208 from test import support
209
210 with support.SuppressCrashReport():
211 _testcapi.return_result_with_error()
212 """)
213 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100214 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100215 br'Fatal Python error: a function returned a '
216 br'result with an error set\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100217 br'ValueError\n'
218 br'\n'
219 br'During handling of the above exception, '
220 br'another exception occurred:\n'
221 br'\n'
222 br'SystemError: <built-in '
223 br'function return_result_with_error> '
224 br'returned a result with an error set\n'
225 br'\n'
226 br'Current thread.*:\n'
227 br' File .*, line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100228 else:
229 with self.assertRaises(SystemError) as cm:
230 _testcapi.return_result_with_error()
231 self.assertRegex(str(cm.exception),
232 'return_result_with_error.* '
233 'returned a result with an error set')
234
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800235
Victor Stinner45df8202010-04-28 22:31:17 +0000236@unittest.skipUnless(threading, 'Threading required for this test.')
Benjamin Petersona54c9092009-01-13 02:11:23 +0000237class TestPendingCalls(unittest.TestCase):
238
239 def pendingcalls_submit(self, l, n):
240 def callback():
241 #this function can be interrupted by thread switching so let's
242 #use an atomic operation
243 l.append(None)
244
245 for i in range(n):
246 time.sleep(random.random()*0.02) #0.01 secs on average
247 #try submitting callback until successful.
248 #rely on regular interrupt to flush queue if we are
249 #unsuccessful.
250 while True:
251 if _testcapi._pending_threadfunc(callback):
252 break;
253
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000254 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000255 #now, stick around until l[0] has grown to 10
256 count = 0;
257 while len(l) != n:
258 #this busy loop is where we expect to be interrupted to
259 #run our callbacks. Note that callbacks are only run on the
260 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000261 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000262 print("(%i)"%(len(l),),)
263 for i in range(1000):
264 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000265 if context and not context.event.is_set():
266 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000267 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000268 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000269 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000270 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000271 print("(%i)"%(len(l),))
272
273 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000274
275 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000276 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000277 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000278 class foo(object):pass
279 context = foo()
280 context.l = []
281 context.n = 2 #submits per thread
282 context.nThreads = n // context.n
283 context.nFinished = 0
284 context.lock = threading.Lock()
285 context.event = threading.Event()
286
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300287 threads = [threading.Thread(target=self.pendingcalls_thread,
288 args=(context,))
289 for i in range(context.nThreads)]
290 with support.start_threads(threads):
291 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000292
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000293 def pendingcalls_thread(self, context):
294 try:
295 self.pendingcalls_submit(context.l, context.n)
296 finally:
297 with context.lock:
298 context.nFinished += 1
299 nFinished = context.nFinished
300 if False and support.verbose:
301 print("finished threads: ", nFinished)
302 if nFinished == context.nThreads:
303 context.event.set()
304
Benjamin Petersona54c9092009-01-13 02:11:23 +0000305 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200306 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000307 #once. It is ok to ask for too many, because we loop until we find a slot.
308 #the loop can be interrupted to dispatch.
309 #there are only 32 dispatch slots, so we go for twice that!
310 l = []
311 n = 64
312 self.pendingcalls_submit(l, n)
313 self.pendingcalls_wait(l, n)
314
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200315
316class SubinterpreterTest(unittest.TestCase):
317
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100318 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100319 import builtins
320 r, w = os.pipe()
321 code = """if 1:
322 import sys, builtins, pickle
323 with open({:d}, "wb") as f:
324 pickle.dump(id(sys.modules), f)
325 pickle.dump(id(builtins), f)
326 """.format(w)
327 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100328 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100329 self.assertEqual(ret, 0)
330 self.assertNotEqual(pickle.load(f), id(sys.modules))
331 self.assertNotEqual(pickle.load(f), id(builtins))
332
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200333
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000334# Bug #6012
335class Test6012(unittest.TestCase):
336 def test(self):
337 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000338
Antoine Pitrou8e605772011-04-25 21:21:07 +0200339
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000340class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000341 def setUp(self):
Antoine Pitrou8e605772011-04-25 21:21:07 +0200342 basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000343 exename = "_testembed"
344 if sys.platform.startswith("win"):
345 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
346 exename += ext
347 exepath = os.path.dirname(sys.executable)
348 else:
Nick Coghlanbca9acf2014-09-25 19:48:15 +1000349 exepath = os.path.join(basepath, "Programs")
Nick Coghlan4e641df2013-11-03 16:54:46 +1000350 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000351 if not os.path.exists(exe):
352 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200353 # This is needed otherwise we get a fatal error:
354 # "Py_Initialize: Unable to get the locale encoding
355 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000356 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200357 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000358
359 def tearDown(self):
360 os.chdir(self.oldcwd)
361
362 def run_embedded_interpreter(self, *args):
363 """Runs a test in the embedded interpreter"""
364 cmd = [self.test_exe]
365 cmd.extend(args)
366 p = subprocess.Popen(cmd,
367 stdout=subprocess.PIPE,
Steve Dower86e9deb2014-11-01 15:11:05 -0700368 stderr=subprocess.PIPE,
369 universal_newlines=True)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000370 (out, err) = p.communicate()
371 self.assertEqual(p.returncode, 0,
372 "bad returncode %d, stderr is %r" %
373 (p.returncode, err))
Steve Dower86e9deb2014-11-01 15:11:05 -0700374 return out, err
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000375
376 def test_subinterps(self):
377 # This is just a "don't crash" test
378 out, err = self.run_embedded_interpreter()
379 if support.verbose:
380 print()
381 print(out)
382 print(err)
383
Nick Coghlan4e641df2013-11-03 16:54:46 +1000384 @staticmethod
385 def _get_default_pipe_encoding():
386 rp, wp = os.pipe()
387 try:
388 with os.fdopen(wp, 'w') as w:
389 default_pipe_encoding = w.encoding
390 finally:
391 os.close(rp)
392 return default_pipe_encoding
393
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000394 def test_forced_io_encoding(self):
395 # Checks forced configuration of embedded interpreter IO streams
396 out, err = self.run_embedded_interpreter("forced_io_encoding")
397 if support.verbose:
398 print()
399 print(out)
400 print(err)
Victor Stinnerb2bef622014-03-18 02:38:12 +0100401 expected_errors = sys.__stdout__.errors
Nick Coghlan4e641df2013-11-03 16:54:46 +1000402 expected_stdin_encoding = sys.__stdin__.encoding
403 expected_pipe_encoding = self._get_default_pipe_encoding()
Steve Dower86e9deb2014-11-01 15:11:05 -0700404 expected_output = '\n'.join([
Nick Coghlan4e641df2013-11-03 16:54:46 +1000405 "--- Use defaults ---",
406 "Expected encoding: default",
407 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100408 "stdin: {in_encoding}:{errors}",
409 "stdout: {out_encoding}:{errors}",
410 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000411 "--- Set errors only ---",
412 "Expected encoding: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100413 "Expected errors: ignore",
414 "stdin: {in_encoding}:ignore",
415 "stdout: {out_encoding}:ignore",
416 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000417 "--- Set encoding only ---",
418 "Expected encoding: latin-1",
419 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100420 "stdin: latin-1:{errors}",
421 "stdout: latin-1:{errors}",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000422 "stderr: latin-1:backslashreplace",
423 "--- Set encoding and errors ---",
424 "Expected encoding: latin-1",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100425 "Expected errors: replace",
426 "stdin: latin-1:replace",
427 "stdout: latin-1:replace",
428 "stderr: latin-1:backslashreplace"])
429 expected_output = expected_output.format(
430 in_encoding=expected_stdin_encoding,
431 out_encoding=expected_pipe_encoding,
432 errors=expected_errors)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000433 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000434 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000435 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200436
Larry Hastings8f904da2012-06-22 03:56:29 -0700437class SkipitemTest(unittest.TestCase):
438
439 def test_skipitem(self):
440 """
441 If this test failed, you probably added a new "format unit"
442 in Python/getargs.c, but neglected to update our poor friend
443 skipitem() in the same file. (If so, shame on you!)
444
Larry Hastings48ed3602012-06-22 12:58:36 -0700445 With a few exceptions**, this function brute-force tests all
446 printable ASCII*** characters (32 to 126 inclusive) as format units,
447 checking to see that PyArg_ParseTupleAndKeywords() return consistent
448 errors both when the unit is attempted to be used and when it is
449 skipped. If the format unit doesn't exist, we'll get one of two
450 specific error messages (one for used, one for skipped); if it does
451 exist we *won't* get that error--we'll get either no error or some
452 other error. If we get the specific "does not exist" error for one
453 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700454
Larry Hastings48ed3602012-06-22 12:58:36 -0700455 ** Some format units have special funny semantics and it would
456 be difficult to accomodate them here. Since these are all
457 well-established and properly skipped in skipitem() we can
458 get away with not testing them--this test is really intended
459 to catch *new* format units.
460
461 *** Python C source files must be ASCII. Therefore it's impossible
462 to have non-ASCII format units.
463
Larry Hastings8f904da2012-06-22 03:56:29 -0700464 """
465 empty_tuple = ()
466 tuple_1 = (0,)
467 dict_b = {'b':1}
468 keywords = ["a", "b"]
469
Larry Hastings48ed3602012-06-22 12:58:36 -0700470 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700471 c = chr(i)
472
Larry Hastings8f904da2012-06-22 03:56:29 -0700473 # skip parentheses, the error reporting is inconsistent about them
474 # skip 'e', it's always a two-character code
475 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700476 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700477 continue
478
479 # test the format unit when not skipped
480 format = c + "i"
481 try:
482 # (note: the format string must be bytes!)
483 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
484 format.encode("ascii"), keywords)
485 when_not_skipped = False
486 except TypeError as e:
487 s = "argument 1 must be impossible<bad format char>, not int"
488 when_not_skipped = (str(e) == s)
489 except RuntimeError as e:
490 when_not_skipped = False
491
492 # test the format unit when skipped
493 optional_format = "|" + format
494 try:
495 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
496 optional_format.encode("ascii"), keywords)
497 when_skipped = False
498 except RuntimeError as e:
499 s = "impossible<bad format char>: '{}'".format(format)
500 when_skipped = (str(e) == s)
501
502 message = ("test_skipitem_parity: "
503 "detected mismatch between convertsimple and skipitem "
504 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
505 c, i, when_skipped, when_not_skipped))
506 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200507
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200508 def test_parse_tuple_and_keywords(self):
509 # parse_tuple_and_keywords error handling tests
510 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
511 (), {}, 42, [])
512 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
513 (), {}, b'', 42)
514 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
515 (), {}, b'', [''] * 42)
516 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
517 (), {}, b'', [42])
518
Ezio Melotti29267c82013-02-23 05:52:46 +0200519@unittest.skipUnless(threading, 'Threading required for this test.')
520class TestThreadState(unittest.TestCase):
521
522 @support.reap_threads
523 def test_thread_state(self):
524 # some extra thread-state tests driven via _testcapi
525 def target():
526 idents = []
527
528 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200529 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200530
531 _testcapi._test_thread_state(callback)
532 a = b = callback
533 time.sleep(1)
534 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200535 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200536 "Couldn't find main thread correctly in the list")
537
538 target()
539 t = threading.Thread(target=target)
540 t.start()
541 t.join()
542
Zachary Warec12f09e2013-11-11 22:47:04 -0600543class Test_testcapi(unittest.TestCase):
544 def test__testcapi(self):
545 for name in dir(_testcapi):
546 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600547 with self.subTest("internal", name=name):
548 test = getattr(_testcapi, name)
549 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000550
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600552 unittest.main()