blob: 2a6de3c5aa9780c735e72c9a34cc7e7c7082ac6c [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
Nick Coghlan39f0bb52017-11-28 08:11:51 +10004from collections import OrderedDict
Antoine Pitrou8e605772011-04-25 21:21:07 +02005import os
Antoine Pitrou2f828f22012-01-18 00:21:11 +01006import pickle
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +00007import random
Victor Stinnerb3adb1a2016-03-14 17:40:09 +01008import re
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +00009import subprocess
Martin v. Löwis6ce7ed22005-03-03 12:26:35 +000010import sys
Victor Stinner34be8072016-03-14 12:04:26 +010011import sysconfig
Victor Stinnerefde1462015-03-21 15:04:43 +010012import textwrap
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020013import threading
Benjamin Petersona54c9092009-01-13 02:11:23 +000014import time
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000015import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000016from test import support
Larry Hastingsfcafe432013-11-23 17:35:48 -080017from test.support import MISSING_C_DOCSTRINGS
xdegaye85f64302017-07-01 14:14:45 +020018from test.support.script_helper import assert_python_failure, assert_python_ok
Victor Stinner45df8202010-04-28 22:31:17 +000019try:
Stefan Krahfd24f9e2012-08-20 11:04:24 +020020 import _posixsubprocess
21except ImportError:
22 _posixsubprocess = None
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020023
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
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,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +030099 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,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300107 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,
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300117 Z(),[b'1'],3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17)
Stefan Krahdb579d72012-08-20 14:36:47 +0200118
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
Zachary Ware8ef887c2015-04-13 18:22:35 -0500126 self.assertEqual(_testcapi.docstring_empty.__doc__, None)
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800127 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
Zachary Ware8ef887c2015-04-13 18:22:35 -0500153 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None)
154 self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__,
155 "($module, /, sig)")
156
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800157 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800158 "\nThis docstring has a valid signature and some extra newlines.")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800159 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
Larry Hastings2623c8c2014-02-08 22:15:29 -0800160 "($module, /, parameter)")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800161
Benjamin Petersond51374e2014-04-09 23:55:56 -0400162 def test_c_type_with_matrix_multiplication(self):
163 M = _testcapi.matmulType
164 m1 = M()
165 m2 = M()
166 self.assertEqual(m1 @ m2, ("matmul", m1, m2))
167 self.assertEqual(m1 @ 42, ("matmul", m1, 42))
168 self.assertEqual(42 @ m1, ("matmul", 42, m1))
169 o = m1
170 o @= m2
171 self.assertEqual(o, ("imatmul", m1, m2))
172 o = m1
173 o @= 42
174 self.assertEqual(o, ("imatmul", m1, 42))
175 o = 42
176 o @= m1
177 self.assertEqual(o, ("matmul", 42, m1))
178
Victor Stinnerefde1462015-03-21 15:04:43 +0100179 def test_return_null_without_error(self):
180 # Issue #23571: A function must not return NULL without setting an
181 # error
182 if Py_DEBUG:
183 code = textwrap.dedent("""
184 import _testcapi
185 from test import support
186
187 with support.SuppressCrashReport():
188 _testcapi.return_null_without_error()
189 """)
190 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100191 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100192 br'Fatal Python error: a function returned NULL '
193 br'without setting an error\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100194 br'SystemError: <built-in function '
195 br'return_null_without_error> returned NULL '
196 br'without setting an error\n'
197 br'\n'
198 br'Current thread.*:\n'
199 br' File .*", line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100200 else:
201 with self.assertRaises(SystemError) as cm:
202 _testcapi.return_null_without_error()
203 self.assertRegex(str(cm.exception),
204 'return_null_without_error.* '
205 'returned NULL without setting an error')
206
207 def test_return_result_with_error(self):
208 # Issue #23571: A function must not return a result with an error set
209 if Py_DEBUG:
210 code = textwrap.dedent("""
211 import _testcapi
212 from test import support
213
214 with support.SuppressCrashReport():
215 _testcapi.return_result_with_error()
216 """)
217 rc, out, err = assert_python_failure('-c', code)
Victor Stinner381a9bc2015-03-24 14:01:32 +0100218 self.assertRegex(err.replace(b'\r', b''),
Victor Stinner944fbcc2015-03-24 16:28:52 +0100219 br'Fatal Python error: a function returned a '
220 br'result with an error set\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100221 br'ValueError\n'
222 br'\n'
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300223 br'The above exception was the direct cause '
224 br'of the following exception:\n'
Victor Stinner381a9bc2015-03-24 14:01:32 +0100225 br'\n'
226 br'SystemError: <built-in '
227 br'function return_result_with_error> '
228 br'returned a result with an error set\n'
229 br'\n'
230 br'Current thread.*:\n'
231 br' File .*, line 6 in <module>')
Victor Stinnerefde1462015-03-21 15:04:43 +0100232 else:
233 with self.assertRaises(SystemError) as cm:
234 _testcapi.return_result_with_error()
235 self.assertRegex(str(cm.exception),
236 'return_result_with_error.* '
237 'returned a result with an error set')
238
Serhiy Storchaka13e602e2016-05-20 22:31:14 +0300239 def test_buildvalue_N(self):
240 _testcapi.test_buildvalue_N()
241
xdegaye85f64302017-07-01 14:14:45 +0200242 def test_set_nomemory(self):
243 code = """if 1:
244 import _testcapi
245
246 class C(): pass
247
248 # The first loop tests both functions and that remove_mem_hooks()
249 # can be called twice in a row. The second loop checks a call to
250 # set_nomemory() after a call to remove_mem_hooks(). The third
251 # loop checks the start and stop arguments of set_nomemory().
252 for outer_cnt in range(1, 4):
253 start = 10 * outer_cnt
254 for j in range(100):
255 if j == 0:
256 if outer_cnt != 3:
257 _testcapi.set_nomemory(start)
258 else:
259 _testcapi.set_nomemory(start, start + 1)
260 try:
261 C()
262 except MemoryError as e:
263 if outer_cnt != 3:
264 _testcapi.remove_mem_hooks()
265 print('MemoryError', outer_cnt, j)
266 _testcapi.remove_mem_hooks()
267 break
268 """
269 rc, out, err = assert_python_ok('-c', code)
270 self.assertIn(b'MemoryError 1 10', out)
271 self.assertIn(b'MemoryError 2 20', out)
272 self.assertIn(b'MemoryError 3 30', out)
273
Oren Milman0ccc0f62017-10-08 11:17:46 +0300274 def test_mapping_keys_values_items(self):
275 class Mapping1(dict):
276 def keys(self):
277 return list(super().keys())
278 def values(self):
279 return list(super().values())
280 def items(self):
281 return list(super().items())
282 class Mapping2(dict):
283 def keys(self):
284 return tuple(super().keys())
285 def values(self):
286 return tuple(super().values())
287 def items(self):
288 return tuple(super().items())
289 dict_obj = {'foo': 1, 'bar': 2, 'spam': 3}
290
291 for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(),
292 dict_obj, OrderedDict(dict_obj),
293 Mapping1(dict_obj), Mapping2(dict_obj)]:
294 self.assertListEqual(_testcapi.get_mapping_keys(mapping),
295 list(mapping.keys()))
296 self.assertListEqual(_testcapi.get_mapping_values(mapping),
297 list(mapping.values()))
298 self.assertListEqual(_testcapi.get_mapping_items(mapping),
299 list(mapping.items()))
300
301 def test_mapping_keys_values_items_bad_arg(self):
302 self.assertRaises(AttributeError, _testcapi.get_mapping_keys, None)
303 self.assertRaises(AttributeError, _testcapi.get_mapping_values, None)
304 self.assertRaises(AttributeError, _testcapi.get_mapping_items, None)
305
306 class BadMapping:
307 def keys(self):
308 return None
309 def values(self):
310 return None
311 def items(self):
312 return None
313 bad_mapping = BadMapping()
314 self.assertRaises(TypeError, _testcapi.get_mapping_keys, bad_mapping)
315 self.assertRaises(TypeError, _testcapi.get_mapping_values, bad_mapping)
316 self.assertRaises(TypeError, _testcapi.get_mapping_items, bad_mapping)
317
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800318
Benjamin Petersona54c9092009-01-13 02:11:23 +0000319class TestPendingCalls(unittest.TestCase):
320
321 def pendingcalls_submit(self, l, n):
322 def callback():
323 #this function can be interrupted by thread switching so let's
324 #use an atomic operation
325 l.append(None)
326
327 for i in range(n):
328 time.sleep(random.random()*0.02) #0.01 secs on average
329 #try submitting callback until successful.
330 #rely on regular interrupt to flush queue if we are
331 #unsuccessful.
332 while True:
333 if _testcapi._pending_threadfunc(callback):
334 break;
335
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000336 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000337 #now, stick around until l[0] has grown to 10
338 count = 0;
339 while len(l) != n:
340 #this busy loop is where we expect to be interrupted to
341 #run our callbacks. Note that callbacks are only run on the
342 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000343 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000344 print("(%i)"%(len(l),),)
345 for i in range(1000):
346 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000347 if context and not context.event.is_set():
348 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000349 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000350 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000351 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000352 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000353 print("(%i)"%(len(l),))
354
355 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000356
357 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000358 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000359 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000360 class foo(object):pass
361 context = foo()
362 context.l = []
363 context.n = 2 #submits per thread
364 context.nThreads = n // context.n
365 context.nFinished = 0
366 context.lock = threading.Lock()
367 context.event = threading.Event()
368
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300369 threads = [threading.Thread(target=self.pendingcalls_thread,
370 args=(context,))
371 for i in range(context.nThreads)]
372 with support.start_threads(threads):
373 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000374
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000375 def pendingcalls_thread(self, context):
376 try:
377 self.pendingcalls_submit(context.l, context.n)
378 finally:
379 with context.lock:
380 context.nFinished += 1
381 nFinished = context.nFinished
382 if False and support.verbose:
383 print("finished threads: ", nFinished)
384 if nFinished == context.nThreads:
385 context.event.set()
386
Benjamin Petersona54c9092009-01-13 02:11:23 +0000387 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200388 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000389 #once. It is ok to ask for too many, because we loop until we find a slot.
390 #the loop can be interrupted to dispatch.
391 #there are only 32 dispatch slots, so we go for twice that!
392 l = []
393 n = 64
394 self.pendingcalls_submit(l, n)
395 self.pendingcalls_wait(l, n)
396
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200397
398class SubinterpreterTest(unittest.TestCase):
399
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100400 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100401 import builtins
402 r, w = os.pipe()
403 code = """if 1:
404 import sys, builtins, pickle
405 with open({:d}, "wb") as f:
406 pickle.dump(id(sys.modules), f)
407 pickle.dump(id(builtins), f)
408 """.format(w)
409 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100410 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100411 self.assertEqual(ret, 0)
412 self.assertNotEqual(pickle.load(f), id(sys.modules))
413 self.assertNotEqual(pickle.load(f), id(builtins))
414
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200415
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000416# Bug #6012
417class Test6012(unittest.TestCase):
418 def test(self):
419 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000420
Antoine Pitrou8e605772011-04-25 21:21:07 +0200421
Larry Hastings8f904da2012-06-22 03:56:29 -0700422class SkipitemTest(unittest.TestCase):
423
424 def test_skipitem(self):
425 """
426 If this test failed, you probably added a new "format unit"
427 in Python/getargs.c, but neglected to update our poor friend
428 skipitem() in the same file. (If so, shame on you!)
429
Larry Hastings48ed3602012-06-22 12:58:36 -0700430 With a few exceptions**, this function brute-force tests all
431 printable ASCII*** characters (32 to 126 inclusive) as format units,
432 checking to see that PyArg_ParseTupleAndKeywords() return consistent
433 errors both when the unit is attempted to be used and when it is
434 skipped. If the format unit doesn't exist, we'll get one of two
435 specific error messages (one for used, one for skipped); if it does
436 exist we *won't* get that error--we'll get either no error or some
437 other error. If we get the specific "does not exist" error for one
438 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700439
Larry Hastings48ed3602012-06-22 12:58:36 -0700440 ** Some format units have special funny semantics and it would
Martin Panter46f50722016-05-26 05:35:26 +0000441 be difficult to accommodate them here. Since these are all
Larry Hastings48ed3602012-06-22 12:58:36 -0700442 well-established and properly skipped in skipitem() we can
443 get away with not testing them--this test is really intended
444 to catch *new* format units.
445
446 *** Python C source files must be ASCII. Therefore it's impossible
447 to have non-ASCII format units.
448
Larry Hastings8f904da2012-06-22 03:56:29 -0700449 """
450 empty_tuple = ()
451 tuple_1 = (0,)
452 dict_b = {'b':1}
453 keywords = ["a", "b"]
454
Larry Hastings48ed3602012-06-22 12:58:36 -0700455 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700456 c = chr(i)
457
Larry Hastings8f904da2012-06-22 03:56:29 -0700458 # skip parentheses, the error reporting is inconsistent about them
459 # skip 'e', it's always a two-character code
460 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700461 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700462 continue
463
464 # test the format unit when not skipped
465 format = c + "i"
466 try:
Larry Hastings8f904da2012-06-22 03:56:29 -0700467 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300468 format, keywords)
Larry Hastings8f904da2012-06-22 03:56:29 -0700469 when_not_skipped = False
Serhiy Storchaka4cd63ef2016-02-08 01:22:47 +0200470 except SystemError as e:
Serhiy Storchakac4b813d2016-02-08 01:06:11 +0200471 s = "argument 1 (impossible<bad format char>)"
Larry Hastings8f904da2012-06-22 03:56:29 -0700472 when_not_skipped = (str(e) == s)
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200473 except TypeError:
Larry Hastings8f904da2012-06-22 03:56:29 -0700474 when_not_skipped = False
475
476 # test the format unit when skipped
477 optional_format = "|" + format
478 try:
479 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300480 optional_format, keywords)
Larry Hastings8f904da2012-06-22 03:56:29 -0700481 when_skipped = False
Serhiy Storchakaa9725f82016-02-11 12:41:40 +0200482 except SystemError as e:
Larry Hastings8f904da2012-06-22 03:56:29 -0700483 s = "impossible<bad format char>: '{}'".format(format)
484 when_skipped = (str(e) == s)
485
486 message = ("test_skipitem_parity: "
487 "detected mismatch between convertsimple and skipitem "
488 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
489 c, i, when_skipped, when_not_skipped))
490 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200491
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200492 def test_parse_tuple_and_keywords(self):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300493 # Test handling errors in the parse_tuple_and_keywords helper itself
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200494 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
495 (), {}, 42, [])
496 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300497 (), {}, '', 42)
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200498 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300499 (), {}, '', [''] * 42)
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200500 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300501 (), {}, '', [42])
502
503 def test_bad_use(self):
504 # Test handling invalid format and keywords in
505 # PyArg_ParseTupleAndKeywords()
506 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
507 (1,), {}, '||O', ['a'])
508 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
509 (1, 2), {}, '|O|O', ['a', 'b'])
510 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
511 (), {'a': 1}, '$$O', ['a'])
512 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
513 (), {'a': 1, 'b': 2}, '$O$O', ['a', 'b'])
514 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
515 (), {'a': 1}, '$|O', ['a'])
516 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
517 (), {'a': 1, 'b': 2}, '$O|O', ['a', 'b'])
518 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
519 (1,), {}, '|O', ['a', 'b'])
520 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
521 (1,), {}, '|OO', ['a'])
522 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
523 (), {}, '|$O', [''])
524 self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
525 (), {}, '|OO', ['a', ''])
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200526
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300527 def test_positional_only(self):
528 parse = _testcapi.parse_tuple_and_keywords
529
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300530 parse((1, 2, 3), {}, 'OOO', ['', '', 'a'])
531 parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300532 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200533 r'function takes at least 2 positional arguments \(1 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300534 parse((1,), {'a': 3}, 'OOO', ['', '', 'a'])
535 parse((1,), {}, 'O|OO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300536 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200537 r'function takes at least 1 positional arguments \(0 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300538 parse((), {}, 'O|OO', ['', '', 'a'])
539 parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300540 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200541 r'function takes exactly 2 positional arguments \(1 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300542 parse((1,), {'a': 3}, 'OO$O', ['', '', 'a'])
543 parse((1,), {}, 'O|O$O', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300544 with self.assertRaisesRegex(TypeError,
Michael Seifert64c8f702017-04-09 09:47:12 +0200545 r'function takes at least 1 positional arguments \(0 given\)'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300546 parse((), {}, 'O|O$O', ['', '', 'a'])
R David Murray44b548d2016-09-08 13:59:53 -0400547 with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300548 parse((1,), {}, 'O|$OO', ['', '', 'a'])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300549 with self.assertRaisesRegex(SystemError, 'Empty keyword'):
Serhiy Storchaka5f161fd2017-05-04 00:03:23 +0300550 parse((1,), {}, 'O|OO', ['', 'a', ''])
Serhiy Storchakaf41b82f2016-06-09 16:30:29 +0300551
Victor Stinner34be8072016-03-14 12:04:26 +0100552
Ezio Melotti29267c82013-02-23 05:52:46 +0200553class TestThreadState(unittest.TestCase):
554
555 @support.reap_threads
556 def test_thread_state(self):
557 # some extra thread-state tests driven via _testcapi
558 def target():
559 idents = []
560
561 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200562 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200563
564 _testcapi._test_thread_state(callback)
565 a = b = callback
566 time.sleep(1)
567 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200568 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200569 "Couldn't find main thread correctly in the list")
570
571 target()
572 t = threading.Thread(target=target)
573 t.start()
574 t.join()
575
Victor Stinner34be8072016-03-14 12:04:26 +0100576
Zachary Warec12f09e2013-11-11 22:47:04 -0600577class Test_testcapi(unittest.TestCase):
578 def test__testcapi(self):
Victor Stinnere1a470b2017-10-31 08:40:59 -0700579 if support.verbose:
580 print()
Zachary Warec12f09e2013-11-11 22:47:04 -0600581 for name in dir(_testcapi):
Victor Stinnere1a470b2017-10-31 08:40:59 -0700582 if not name.startswith('test_'):
583 continue
584 with self.subTest("internal", name=name):
585 if support.verbose:
586 print(f" {name}", flush=True)
587 test = getattr(_testcapi, name)
588 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000589
Victor Stinner34be8072016-03-14 12:04:26 +0100590
Victor Stinnerc4aec362016-03-14 22:26:53 +0100591class PyMemDebugTests(unittest.TestCase):
592 PYTHONMALLOC = 'debug'
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100593 # '0x04c06e0' or '04C06E0'
Victor Stinner08572f62016-03-14 21:55:43 +0100594 PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+'
Victor Stinner34be8072016-03-14 12:04:26 +0100595
596 def check(self, code):
597 with support.SuppressCrashReport():
Victor Stinnerc4aec362016-03-14 22:26:53 +0100598 out = assert_python_failure('-c', code,
599 PYTHONMALLOC=self.PYTHONMALLOC)
Victor Stinner34be8072016-03-14 12:04:26 +0100600 stderr = out.err
601 return stderr.decode('ascii', 'replace')
602
603 def test_buffer_overflow(self):
604 out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()')
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100605 regex = (r"Debug memory block at address p={ptr}: API 'm'\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100606 r" 16 bytes originally requested\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100607 r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n"
608 r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100609 r" at tail\+0: 0x78 \*\*\* OUCH\n"
610 r" at tail\+1: 0xfb\n"
611 r" at tail\+2: 0xfb\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100612 r" .*\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100613 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100614 r" Data at p: cb cb cb .*\n"
Victor Stinner6453e9e2016-03-15 23:36:28 +0100615 r"\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100616 r"Fatal Python error: bad trailing pad byte")
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100617 regex = regex.format(ptr=self.PTR_REGEX)
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100618 regex = re.compile(regex, flags=re.DOTALL)
Victor Stinner34be8072016-03-14 12:04:26 +0100619 self.assertRegex(out, regex)
620
621 def test_api_misuse(self):
622 out = self.check('import _testcapi; _testcapi.pymem_api_misuse()')
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100623 regex = (r"Debug memory block at address p={ptr}: API 'm'\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100624 r" 16 bytes originally requested\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100625 r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n"
626 r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100627 r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
Victor Stinnerb3adb1a2016-03-14 17:40:09 +0100628 r" Data at p: cb cb cb .*\n"
Victor Stinner6453e9e2016-03-15 23:36:28 +0100629 r"\n"
Victor Stinner34be8072016-03-14 12:04:26 +0100630 r"Fatal Python error: bad ID: Allocated using API 'm', verified using API 'r'\n")
Victor Stinnera1bc28a2016-03-14 17:10:36 +0100631 regex = regex.format(ptr=self.PTR_REGEX)
Victor Stinner34be8072016-03-14 12:04:26 +0100632 self.assertRegex(out, regex)
633
Victor Stinnerad524372016-03-16 12:12:53 +0100634 def check_malloc_without_gil(self, code):
Victor Stinnerc4aec362016-03-14 22:26:53 +0100635 out = self.check(code)
636 expected = ('Fatal Python error: Python memory allocator called '
637 'without holding the GIL')
638 self.assertIn(expected, out)
Victor Stinner34be8072016-03-14 12:04:26 +0100639
Victor Stinnerad524372016-03-16 12:12:53 +0100640 def test_pymem_malloc_without_gil(self):
641 # Debug hooks must raise an error if PyMem_Malloc() is called
642 # without holding the GIL
643 code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()'
644 self.check_malloc_without_gil(code)
645
646 def test_pyobject_malloc_without_gil(self):
647 # Debug hooks must raise an error if PyObject_Malloc() is called
648 # without holding the GIL
649 code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()'
650 self.check_malloc_without_gil(code)
651
Victor Stinnerc4aec362016-03-14 22:26:53 +0100652
653class PyMemMallocDebugTests(PyMemDebugTests):
654 PYTHONMALLOC = 'malloc_debug'
Victor Stinner34be8072016-03-14 12:04:26 +0100655
656
Victor Stinner5d39e042017-11-29 17:20:38 +0100657@unittest.skipUnless(support.with_pymalloc(), 'need pymalloc')
Victor Stinnerc4aec362016-03-14 22:26:53 +0100658class PyMemPymallocDebugTests(PyMemDebugTests):
659 PYTHONMALLOC = 'pymalloc_debug'
Victor Stinner34be8072016-03-14 12:04:26 +0100660
661
662@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG')
Victor Stinnerc4aec362016-03-14 22:26:53 +0100663class PyMemDefaultTests(PyMemDebugTests):
664 # test default allocator of Python compiled in debug mode
665 PYTHONMALLOC = ''
Victor Stinner34be8072016-03-14 12:04:26 +0100666
667
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000668if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600669 unittest.main()