blob: d56d7023f29a6b0ba2dcd0daf59028c6b581eadc [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 Stinner34be8072016-03-14 12:04:26 +01009import sysconfig
Victor Stinnerefde1462015-03-21 15:04:43 +010010import textwrap
Benjamin Petersona54c9092009-01-13 02:11:23 +000011import time
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000012import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000013from test import support
Larry Hastingsfcafe432013-11-23 17:35:48 -080014from test.support import MISSING_C_DOCSTRINGS
Berker Peksagce643912015-05-06 06:33:17 +030015from test.support.script_helper import assert_python_failure
Victor Stinner45df8202010-04-28 22:31:17 +000016try:
Stefan Krahfd24f9e2012-08-20 11:04:24 +020017 import _posixsubprocess
18except ImportError:
19 _posixsubprocess = None
20try:
Victor Stinner45df8202010-04-28 22:31:17 +000021 import threading
22except ImportError:
23 threading = None
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020024# Skip this test if the _testcapi module isn't available.
25_testcapi = support.import_module('_testcapi')
Tim Peters9ea17ac2001-02-02 05:57:15 +000026
Victor Stinnerefde1462015-03-21 15:04:43 +010027# Were we compiled --with-pydebug or with #define Py_DEBUG?
28Py_DEBUG = hasattr(sys, 'gettotalrefcount')
29
Benjamin Petersona54c9092009-01-13 02:11:23 +000030
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000031def testfunction(self):
32 """some doc"""
33 return self
34
35class InstanceMethod:
36 id = _testcapi.instancemethod(id)
37 testfunction = _testcapi.instancemethod(testfunction)
38
39class CAPITest(unittest.TestCase):
40
41 def test_instancemethod(self):
42 inst = InstanceMethod()
43 self.assertEqual(id(inst), inst.id())
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000044 self.assertTrue(inst.testfunction() is inst)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000045 self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__)
46 self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__)
47
48 InstanceMethod.testfunction.attribute = "test"
49 self.assertEqual(testfunction.attribute, "test")
50 self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
51
Stefan Krah0ca46242010-06-09 08:56:28 +000052 @unittest.skipUnless(threading, 'Threading required for this test.')
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000053 def test_no_FatalError_infinite_loop(self):
Antoine Pitrou77e904e2013-10-08 23:04:32 +020054 with support.SuppressCrashReport():
Ezio Melotti25a40452013-03-05 20:26:17 +020055 p = subprocess.Popen([sys.executable, "-c",
Ezio Melottie1857d92013-03-05 20:31:34 +020056 'import _testcapi;'
57 '_testcapi.crash_no_current_thread()'],
58 stdout=subprocess.PIPE,
59 stderr=subprocess.PIPE)
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000060 (out, err) = p.communicate()
61 self.assertEqual(out, b'')
62 # This used to cause an infinite loop.
Vinay Sajip73954042012-05-06 11:34:50 +010063 self.assertTrue(err.rstrip().startswith(
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000064 b'Fatal Python error:'
Vinay Sajip73954042012-05-06 11:34:50 +010065 b' PyThreadState_Get: no current thread'))
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000066
Antoine Pitrou915605c2011-02-24 20:53:48 +000067 def test_memoryview_from_NULL_pointer(self):
68 self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000069
Martin v. Löwisaa2efcb2012-04-19 14:33:43 +020070 def test_exc_info(self):
71 raised_exception = ValueError("5")
72 new_exc = TypeError("TEST")
73 try:
74 raise raised_exception
75 except ValueError as e:
76 tb = e.__traceback__
77 orig_sys_exc_info = sys.exc_info()
78 orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
79 new_sys_exc_info = sys.exc_info()
80 new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
81 reset_sys_exc_info = sys.exc_info()
82
83 self.assertEqual(orig_exc_info[1], e)
84
85 self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
86 self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
87 self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
88 self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
89 self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
90 else:
91 self.assertTrue(False)
92
Stefan Krahfd24f9e2012-08-20 11:04:24 +020093 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
94 def test_seq_bytes_to_charp_array(self):
95 # Issue #15732: crash in _PySequence_BytesToCharpArray()
96 class Z(object):
97 def __len__(self):
98 return 1
99 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
100 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
Stefan Krah7cacd2e2012-08-21 08:16:09 +0200101 # Issue #15736: overflow in _PySequence_BytesToCharpArray()
102 class Z(object):
103 def __len__(self):
104 return sys.maxsize
105 def __getitem__(self, i):
106 return b'x'
107 self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
108 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
Stefan Krahfd24f9e2012-08-20 11:04:24 +0200109
Stefan Krahdb579d72012-08-20 14:36:47 +0200110 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
111 def test_subprocess_fork_exec(self):
112 class Z(object):
113 def __len__(self):
114 return 1
115
116 # Issue #15738: crash in subprocess_fork_exec()
117 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
118 Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
119
Larry Hastingsfcafe432013-11-23 17:35:48 -0800120 @unittest.skipIf(MISSING_C_DOCSTRINGS,
121 "Signature information for builtins requires docstrings")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800122 def test_docstring_signature_parsing(self):
123
124 self.assertEqual(_testcapi.no_docstring.__doc__, None)
125 self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
126
Zachary Ware8ef887c2015-04-13 18:22:35 -0500127 self.assertEqual(_testcapi.docstring_empty.__doc__, None)
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800128 self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
129
130 self.assertEqual(_testcapi.docstring_no_signature.__doc__,
131 "This docstring has no signature.")
132 self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
133
134 self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800135 "docstring_with_invalid_signature($module, /, boo)\n"
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800136 "\n"
137 "This docstring has an invalid signature."
138 )
139 self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
140
Larry Hastings2623c8c2014-02-08 22:15:29 -0800141 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__,
142 "docstring_with_invalid_signature2($module, /, boo)\n"
143 "\n"
144 "--\n"
145 "\n"
146 "This docstring also has an invalid signature."
147 )
148 self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None)
149
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800150 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
151 "This docstring has a valid signature.")
Larry Hastings2623c8c2014-02-08 22:15:29 -0800152 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800153
Zachary Ware8ef887c2015-04-13 18:22:35 -0500154 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None)
155 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__,
156 "($module, /, sig)")
157
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800158 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800159 "\nThis docstring has a valid signature and some extra newlines.")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800160 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800161 "($module, /, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800162
Benjamin Petersond51374e2014-04-09 23:55:56 -0400163 def test_c_type_with_matrix_multiplication(self):
164 M = _testcapi.matmulType
165 m1 = M()
166 m2 = M()
167 self.assertEqual(m1 @ m2, ("matmul", m1, m2))
168 self.assertEqual(m1 @ 42, ("matmul", m1, 42))
169 self.assertEqual(42 @ m1, ("matmul", 42, m1))
170 o = m1
171 o @= m2
172 self.assertEqual(o, ("imatmul", m1, m2))
173 o = m1
174 o @= 42
175 self.assertEqual(o, ("imatmul", m1, 42))
176 o = 42
177 o @= m1
178 self.assertEqual(o, ("matmul", 42, m1))
179
Victor Stinnerefde1462015-03-21 15:04:43 +0100180 def test_return_null_without_error(self):
181 # Issue #23571: A function must not return NULL without setting an
182 # error
183 if Py_DEBUG:
184 code = textwrap.dedent("""
185 import _testcapi
186 from test import support
187
188 with support.SuppressCrashReport():
189 _testcapi.return_null_without_error()
190 """)
191 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100192 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100193 br'Fatal Python error: a function returned NULL '
194 br'without setting an error\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100195 br'SystemError: <built-in function '
196 br'return_null_without_error> returned NULL '
197 br'without setting an error\n'
198 br'\n'
199 br'Current thread.*:\n'
200 br' File .*", line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100201 else:
202 with self.assertRaises(SystemError) as cm:
203 _testcapi.return_null_without_error()
204 self.assertRegex(str(cm.exception),
205 'return_null_without_error.* '
206 'returned NULL without setting an error')
207
208 def test_return_result_with_error(self):
209 # Issue #23571: A function must not return a result with an error set
210 if Py_DEBUG:
211 code = textwrap.dedent("""
212 import _testcapi
213 from test import support
214
215 with support.SuppressCrashReport():
216 _testcapi.return_result_with_error()
217 """)
218 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100219 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100220 br'Fatal Python error: a function returned a '
221 br'result with an error set\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100222 br'ValueError\n'
223 br'\n'
224 br'During handling of the above exception, '
225 br'another exception occurred:\n'
226 br'\n'
227 br'SystemError: <built-in '
228 br'function return_result_with_error> '
229 br'returned a result with an error set\n'
230 br'\n'
231 br'Current thread.*:\n'
232 br' File .*, line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100233 else:
234 with self.assertRaises(SystemError) as cm:
235 _testcapi.return_result_with_error()
236 self.assertRegex(str(cm.exception),
237 'return_result_with_error.* '
238 'returned a result with an error set')
239
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800240
Victor Stinner45df8202010-04-28 22:31:17 +0000241@unittest.skipUnless(threading, 'Threading required for this test.')
Benjamin Petersona54c9092009-01-13 02:11:23 +0000242class TestPendingCalls(unittest.TestCase):
243
244 def pendingcalls_submit(self, l, n):
245 def callback():
246 #this function can be interrupted by thread switching so let's
247 #use an atomic operation
248 l.append(None)
249
250 for i in range(n):
251 time.sleep(random.random()*0.02) #0.01 secs on average
252 #try submitting callback until successful.
253 #rely on regular interrupt to flush queue if we are
254 #unsuccessful.
255 while True:
256 if _testcapi._pending_threadfunc(callback):
257 break;
258
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000259 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000260 #now, stick around until l[0] has grown to 10
261 count = 0;
262 while len(l) != n:
263 #this busy loop is where we expect to be interrupted to
264 #run our callbacks. Note that callbacks are only run on the
265 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000266 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000267 print("(%i)"%(len(l),),)
268 for i in range(1000):
269 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000270 if context and not context.event.is_set():
271 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000272 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000273 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000274 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000275 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000276 print("(%i)"%(len(l),))
277
278 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000279
280 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000281 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000282 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000283 class foo(object):pass
284 context = foo()
285 context.l = []
286 context.n = 2 #submits per thread
287 context.nThreads = n // context.n
288 context.nFinished = 0
289 context.lock = threading.Lock()
290 context.event = threading.Event()
291
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300292 threads = [threading.Thread(target=self.pendingcalls_thread,
293 args=(context,))
294 for i in range(context.nThreads)]
295 with support.start_threads(threads):
296 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000297
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000298 def pendingcalls_thread(self, context):
299 try:
300 self.pendingcalls_submit(context.l, context.n)
301 finally:
302 with context.lock:
303 context.nFinished += 1
304 nFinished = context.nFinished
305 if False and support.verbose:
306 print("finished threads: ", nFinished)
307 if nFinished == context.nThreads:
308 context.event.set()
309
Benjamin Petersona54c9092009-01-13 02:11:23 +0000310 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200311 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000312 #once. It is ok to ask for too many, because we loop until we find a slot.
313 #the loop can be interrupted to dispatch.
314 #there are only 32 dispatch slots, so we go for twice that!
315 l = []
316 n = 64
317 self.pendingcalls_submit(l, n)
318 self.pendingcalls_wait(l, n)
319
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200320
321class SubinterpreterTest(unittest.TestCase):
322
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100323 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100324 import builtins
325 r, w = os.pipe()
326 code = """if 1:
327 import sys, builtins, pickle
328 with open({:d}, "wb") as f:
329 pickle.dump(id(sys.modules), f)
330 pickle.dump(id(builtins), f)
331 """.format(w)
332 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100333 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100334 self.assertEqual(ret, 0)
335 self.assertNotEqual(pickle.load(f), id(sys.modules))
336 self.assertNotEqual(pickle.load(f), id(builtins))
337
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200338
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000339# Bug #6012
340class Test6012(unittest.TestCase):
341 def test(self):
342 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000343
Antoine Pitrou8e605772011-04-25 21:21:07 +0200344
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000345class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000346 def setUp(self):
Zachary Ware6d8a2602015-12-05 00:16:55 -0600347 here = os.path.abspath(__file__)
348 basepath = os.path.dirname(os.path.dirname(os.path.dirname(here)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000349 exename = "_testembed"
350 if sys.platform.startswith("win"):
351 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
352 exename += ext
353 exepath = os.path.dirname(sys.executable)
354 else:
Nick Coghlanbca9acf2014-09-25 19:48:15 +1000355 exepath = os.path.join(basepath, "Programs")
Nick Coghlan4e641df2013-11-03 16:54:46 +1000356 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000357 if not os.path.exists(exe):
358 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200359 # This is needed otherwise we get a fatal error:
360 # "Py_Initialize: Unable to get the locale encoding
361 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000362 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200363 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000364
365 def tearDown(self):
366 os.chdir(self.oldcwd)
367
368 def run_embedded_interpreter(self, *args):
369 """Runs a test in the embedded interpreter"""
370 cmd = [self.test_exe]
371 cmd.extend(args)
372 p = subprocess.Popen(cmd,
373 stdout=subprocess.PIPE,
Steve Dower86e9deb2014-11-01 15:11:05 -0700374 stderr=subprocess.PIPE,
375 universal_newlines=True)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000376 (out, err) = p.communicate()
377 self.assertEqual(p.returncode, 0,
378 "bad returncode %d, stderr is %r" %
379 (p.returncode, err))
Steve Dower86e9deb2014-11-01 15:11:05 -0700380 return out, err
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000381
382 def test_subinterps(self):
383 # This is just a "don't crash" test
384 out, err = self.run_embedded_interpreter()
385 if support.verbose:
386 print()
387 print(out)
388 print(err)
389
Nick Coghlan4e641df2013-11-03 16:54:46 +1000390 @staticmethod
391 def _get_default_pipe_encoding():
392 rp, wp = os.pipe()
393 try:
394 with os.fdopen(wp, 'w') as w:
395 default_pipe_encoding = w.encoding
396 finally:
397 os.close(rp)
398 return default_pipe_encoding
399
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000400 def test_forced_io_encoding(self):
401 # Checks forced configuration of embedded interpreter IO streams
402 out, err = self.run_embedded_interpreter("forced_io_encoding")
403 if support.verbose:
404 print()
405 print(out)
406 print(err)
Victor Stinnerb2bef622014-03-18 02:38:12 +0100407 expected_errors = sys.__stdout__.errors
Nick Coghlan4e641df2013-11-03 16:54:46 +1000408 expected_stdin_encoding = sys.__stdin__.encoding
409 expected_pipe_encoding = self._get_default_pipe_encoding()
Steve Dower86e9deb2014-11-01 15:11:05 -0700410 expected_output = '\n'.join([
Nick Coghlan4e641df2013-11-03 16:54:46 +1000411 "--- Use defaults ---",
412 "Expected encoding: default",
413 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100414 "stdin: {in_encoding}:{errors}",
415 "stdout: {out_encoding}:{errors}",
416 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000417 "--- Set errors only ---",
418 "Expected encoding: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100419 "Expected errors: ignore",
420 "stdin: {in_encoding}:ignore",
421 "stdout: {out_encoding}:ignore",
422 "stderr: {out_encoding}:backslashreplace",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000423 "--- Set encoding only ---",
424 "Expected encoding: latin-1",
425 "Expected errors: default",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100426 "stdin: latin-1:{errors}",
427 "stdout: latin-1:{errors}",
Nick Coghlan4e641df2013-11-03 16:54:46 +1000428 "stderr: latin-1:backslashreplace",
429 "--- Set encoding and errors ---",
430 "Expected encoding: latin-1",
Victor Stinnerb2bef622014-03-18 02:38:12 +0100431 "Expected errors: replace",
432 "stdin: latin-1:replace",
433 "stdout: latin-1:replace",
434 "stderr: latin-1:backslashreplace"])
435 expected_output = expected_output.format(
436 in_encoding=expected_stdin_encoding,
437 out_encoding=expected_pipe_encoding,
438 errors=expected_errors)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000439 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000440 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000441 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200442
Larry Hastings8f904da2012-06-22 03:56:29 -0700443class SkipitemTest(unittest.TestCase):
444
445 def test_skipitem(self):
446 """
447 If this test failed, you probably added a new "format unit"
448 in Python/getargs.c, but neglected to update our poor friend
449 skipitem() in the same file. (If so, shame on you!)
450
Larry Hastings48ed3602012-06-22 12:58:36 -0700451 With a few exceptions**, this function brute-force tests all
452 printable ASCII*** characters (32 to 126 inclusive) as format units,
453 checking to see that PyArg_ParseTupleAndKeywords() return consistent
454 errors both when the unit is attempted to be used and when it is
455 skipped. If the format unit doesn't exist, we'll get one of two
456 specific error messages (one for used, one for skipped); if it does
457 exist we *won't* get that error--we'll get either no error or some
458 other error. If we get the specific "does not exist" error for one
459 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700460
Larry Hastings48ed3602012-06-22 12:58:36 -0700461 ** Some format units have special funny semantics and it would
462 be difficult to accomodate them here. Since these are all
463 well-established and properly skipped in skipitem() we can
464 get away with not testing them--this test is really intended
465 to catch *new* format units.
466
467 *** Python C source files must be ASCII. Therefore it's impossible
468 to have non-ASCII format units.
469
Larry Hastings8f904da2012-06-22 03:56:29 -0700470 """
471 empty_tuple = ()
472 tuple_1 = (0,)
473 dict_b = {'b':1}
474 keywords = ["a", "b"]
475
Larry Hastings48ed3602012-06-22 12:58:36 -0700476 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700477 c = chr(i)
478
Larry Hastings8f904da2012-06-22 03:56:29 -0700479 # skip parentheses, the error reporting is inconsistent about them
480 # skip 'e', it's always a two-character code
481 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700482 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700483 continue
484
485 # test the format unit when not skipped
486 format = c + "i"
487 try:
488 # (note: the format string must be bytes!)
489 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
490 format.encode("ascii"), keywords)
491 when_not_skipped = False
Serhiy Storchaka4cd63ef2016-02-08 01:22:47 +0200492 except SystemError as e:
Serhiy Storchakac4b813d2016-02-08 01:06:11 +0200493 s = "argument 1 (impossible<bad format char>)"
Larry Hastings8f904da2012-06-22 03:56:29 -0700494 when_not_skipped = (str(e) == s)
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200495 except TypeError:
Larry Hastings8f904da2012-06-22 03:56:29 -0700496 when_not_skipped = False
497
498 # test the format unit when skipped
499 optional_format = "|" + format
500 try:
501 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
502 optional_format.encode("ascii"), keywords)
503 when_skipped = False
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200504 except SystemError as e:
Larry Hastings8f904da2012-06-22 03:56:29 -0700505 s = "impossible<bad format char>: '{}'".format(format)
506 when_skipped = (str(e) == s)
507
508 message = ("test_skipitem_parity: "
509 "detected mismatch between convertsimple and skipitem "
510 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
511 c, i, when_skipped, when_not_skipped))
512 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200513
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200514 def test_parse_tuple_and_keywords(self):
515 # parse_tuple_and_keywords error handling tests
516 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
517 (), {}, 42, [])
518 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
519 (), {}, b'', 42)
520 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
521 (), {}, b'', [''] * 42)
522 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
523 (), {}, b'', [42])
524
Victor Stinner34be8072016-03-14 12:04:26 +0100525
Ezio Melotti29267c82013-02-23 05:52:46 +0200526@unittest.skipUnless(threading, 'Threading required for this test.')
527class TestThreadState(unittest.TestCase):
528
529 @support.reap_threads
530 def test_thread_state(self):
531 # some extra thread-state tests driven via _testcapi
532 def target():
533 idents = []
534
535 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200536 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200537
538 _testcapi._test_thread_state(callback)
539 a = b = callback
540 time.sleep(1)
541 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200542 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200543 "Couldn't find main thread correctly in the list")
544
545 target()
546 t = threading.Thread(target=target)
547 t.start()
548 t.join()
549
Victor Stinner34be8072016-03-14 12:04:26 +0100550
Zachary Warec12f09e2013-11-11 22:47:04 -0600551class Test_testcapi(unittest.TestCase):
552 def test__testcapi(self):
553 for name in dir(_testcapi):
554 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600555 with self.subTest("internal", name=name):
556 test = getattr(_testcapi, name)
557 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000558
Victor Stinner34be8072016-03-14 12:04:26 +0100559
560class MallocTests(unittest.TestCase):
561 ENV = 'debug'
562
563 def check(self, code):
564 with support.SuppressCrashReport():
565 out = assert_python_failure('-c', code, PYTHONMALLOC=self.ENV)
566 stderr = out.err
567 return stderr.decode('ascii', 'replace')
568
569 def test_buffer_overflow(self):
570 out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()')
571 regex = (r"Debug memory block at address p=0x[0-9a-f]+: API 'm'\n"
572 r" 16 bytes originally requested\n"
573 r" The 7 pad bytes at p-7 are FORBIDDENBYTE, as expected.\n"
574 r" The 8 pad bytes at tail=0x[0-9a-f]+ are not all FORBIDDENBYTE \(0x[0-9a-f]{2}\):\n"
575 r" at tail\+0: 0x78 \*\*\* OUCH\n"
576 r" at tail\+1: 0xfb\n"
577 r" at tail\+2: 0xfb\n"
578 r" at tail\+3: 0xfb\n"
579 r" at tail\+4: 0xfb\n"
580 r" at tail\+5: 0xfb\n"
581 r" at tail\+6: 0xfb\n"
582 r" at tail\+7: 0xfb\n"
583 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
584 r" Data at p: cb cb cb cb cb cb cb cb cb cb cb cb cb cb cb cb\n"
585 r"Fatal Python error: bad trailing pad byte")
586 self.assertRegex(out, regex)
587
588 def test_api_misuse(self):
589 out = self.check('import _testcapi; _testcapi.pymem_api_misuse()')
590 regex = (r"Debug memory block at address p=0x[0-9a-f]+: API 'm'\n"
591 r" 16 bytes originally requested\n"
592 r" The 7 pad bytes at p-7 are FORBIDDENBYTE, as expected.\n"
593 r" The 8 pad bytes at tail=0x[0-9a-f]+ are FORBIDDENBYTE, as expected.\n"
594 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
595 r" Data at p: .*\n"
596 r"Fatal Python error: bad ID: Allocated using API 'm', verified using API 'r'\n")
597 self.assertRegex(out, regex)
598
599
600class MallocDebugTests(MallocTests):
601 ENV = 'malloc_debug'
602
603
604@unittest.skipUnless(sysconfig.get_config_var('WITH_PYMALLOC') == 1,
605 'need pymalloc')
606class PymallocDebugTests(MallocTests):
607 ENV = 'pymalloc_debug'
608
609
610@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG')
611class DefaultMallocDebugTests(MallocTests):
612 ENV = ''
613
614
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000615if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600616 unittest.main()