blob: 22c8eb0709ce2e582c5b9e908132d96883eb1052 [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
Tim Petersd66595f2001-02-04 03:09:53 +000021import _testcapi
Tim Peters9ea17ac2001-02-02 05:57:15 +000022
Benjamin Petersona54c9092009-01-13 02:11:23 +000023
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000024def testfunction(self):
25 """some doc"""
26 return self
27
28class InstanceMethod:
29 id = _testcapi.instancemethod(id)
30 testfunction = _testcapi.instancemethod(testfunction)
31
32class CAPITest(unittest.TestCase):
33
34 def test_instancemethod(self):
35 inst = InstanceMethod()
36 self.assertEqual(id(inst), inst.id())
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000037 self.assertTrue(inst.testfunction() is inst)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000038 self.assertEqual(inst.testfunction.__doc__, testfunction.__doc__)
39 self.assertEqual(InstanceMethod.testfunction.__doc__, testfunction.__doc__)
40
41 InstanceMethod.testfunction.attribute = "test"
42 self.assertEqual(testfunction.attribute, "test")
43 self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
44
Stefan Krah0ca46242010-06-09 08:56:28 +000045 @unittest.skipUnless(threading, 'Threading required for this test.')
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000046 def test_no_FatalError_infinite_loop(self):
Antoine Pitrou77e904e2013-10-08 23:04:32 +020047 with support.SuppressCrashReport():
Ezio Melotti25a40452013-03-05 20:26:17 +020048 p = subprocess.Popen([sys.executable, "-c",
Ezio Melottie1857d92013-03-05 20:31:34 +020049 'import _testcapi;'
50 '_testcapi.crash_no_current_thread()'],
51 stdout=subprocess.PIPE,
52 stderr=subprocess.PIPE)
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000053 (out, err) = p.communicate()
54 self.assertEqual(out, b'')
55 # This used to cause an infinite loop.
Vinay Sajip73954042012-05-06 11:34:50 +010056 self.assertTrue(err.rstrip().startswith(
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000057 b'Fatal Python error:'
Vinay Sajip73954042012-05-06 11:34:50 +010058 b' PyThreadState_Get: no current thread'))
Jeffrey Yasskin8e0bdfd2010-05-13 18:31:05 +000059
Antoine Pitrou915605c2011-02-24 20:53:48 +000060 def test_memoryview_from_NULL_pointer(self):
61 self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
Benjamin Peterson9b6df6a2008-10-16 23:56:29 +000062
Martin v. Löwisaa2efcb2012-04-19 14:33:43 +020063 def test_exc_info(self):
64 raised_exception = ValueError("5")
65 new_exc = TypeError("TEST")
66 try:
67 raise raised_exception
68 except ValueError as e:
69 tb = e.__traceback__
70 orig_sys_exc_info = sys.exc_info()
71 orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
72 new_sys_exc_info = sys.exc_info()
73 new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
74 reset_sys_exc_info = sys.exc_info()
75
76 self.assertEqual(orig_exc_info[1], e)
77
78 self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
79 self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
80 self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
81 self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
82 self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
83 else:
84 self.assertTrue(False)
85
Stefan Krahfd24f9e2012-08-20 11:04:24 +020086 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
87 def test_seq_bytes_to_charp_array(self):
88 # Issue #15732: crash in _PySequence_BytesToCharpArray()
89 class Z(object):
90 def __len__(self):
91 return 1
92 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
93 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 +020094 # Issue #15736: overflow in _PySequence_BytesToCharpArray()
95 class Z(object):
96 def __len__(self):
97 return sys.maxsize
98 def __getitem__(self, i):
99 return b'x'
100 self.assertRaises(MemoryError, _posixsubprocess.fork_exec,
101 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 +0200102
Stefan Krahdb579d72012-08-20 14:36:47 +0200103 @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
104 def test_subprocess_fork_exec(self):
105 class Z(object):
106 def __len__(self):
107 return 1
108
109 # Issue #15738: crash in subprocess_fork_exec()
110 self.assertRaises(TypeError, _posixsubprocess.fork_exec,
111 Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
112
Larry Hastingsfcafe432013-11-23 17:35:48 -0800113 @unittest.skipIf(MISSING_C_DOCSTRINGS,
114 "Signature information for builtins requires docstrings")
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800115 def test_docstring_signature_parsing(self):
116
117 self.assertEqual(_testcapi.no_docstring.__doc__, None)
118 self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
119
120 self.assertEqual(_testcapi.docstring_empty.__doc__, "")
121 self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
122
123 self.assertEqual(_testcapi.docstring_no_signature.__doc__,
124 "This docstring has no signature.")
125 self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
126
127 self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
128 "docstring_with_invalid_signature (boo)\n"
129 "\n"
130 "This docstring has an invalid signature."
131 )
132 self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
133
134 self.assertEqual(_testcapi.docstring_with_signature.__doc__,
135 "This docstring has a valid signature.")
136 self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)")
137
138 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
139 "This docstring has a valid signature and some extra newlines.")
140 self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
141 "(parameter)")
142
143
Victor Stinner45df8202010-04-28 22:31:17 +0000144@unittest.skipUnless(threading, 'Threading required for this test.')
Benjamin Petersona54c9092009-01-13 02:11:23 +0000145class TestPendingCalls(unittest.TestCase):
146
147 def pendingcalls_submit(self, l, n):
148 def callback():
149 #this function can be interrupted by thread switching so let's
150 #use an atomic operation
151 l.append(None)
152
153 for i in range(n):
154 time.sleep(random.random()*0.02) #0.01 secs on average
155 #try submitting callback until successful.
156 #rely on regular interrupt to flush queue if we are
157 #unsuccessful.
158 while True:
159 if _testcapi._pending_threadfunc(callback):
160 break;
161
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000162 def pendingcalls_wait(self, l, n, context = None):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000163 #now, stick around until l[0] has grown to 10
164 count = 0;
165 while len(l) != n:
166 #this busy loop is where we expect to be interrupted to
167 #run our callbacks. Note that callbacks are only run on the
168 #main thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000169 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000170 print("(%i)"%(len(l),),)
171 for i in range(1000):
172 a = i*i
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000173 if context and not context.event.is_set():
174 continue
Benjamin Petersona54c9092009-01-13 02:11:23 +0000175 count += 1
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000176 self.assertTrue(count < 10000,
Benjamin Petersona54c9092009-01-13 02:11:23 +0000177 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000178 if False and support.verbose:
Benjamin Petersona54c9092009-01-13 02:11:23 +0000179 print("(%i)"%(len(l),))
180
181 def test_pendingcalls_threaded(self):
Benjamin Petersona54c9092009-01-13 02:11:23 +0000182
183 #do every callback on a separate thread
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000184 n = 32 #total callbacks
Benjamin Petersona54c9092009-01-13 02:11:23 +0000185 threads = []
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000186 class foo(object):pass
187 context = foo()
188 context.l = []
189 context.n = 2 #submits per thread
190 context.nThreads = n // context.n
191 context.nFinished = 0
192 context.lock = threading.Lock()
193 context.event = threading.Event()
194
195 for i in range(context.nThreads):
196 t = threading.Thread(target=self.pendingcalls_thread, args = (context,))
Benjamin Petersona54c9092009-01-13 02:11:23 +0000197 t.start()
198 threads.append(t)
199
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000200 self.pendingcalls_wait(context.l, n, context)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000201
202 for t in threads:
203 t.join()
204
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000205 def pendingcalls_thread(self, context):
206 try:
207 self.pendingcalls_submit(context.l, context.n)
208 finally:
209 with context.lock:
210 context.nFinished += 1
211 nFinished = context.nFinished
212 if False and support.verbose:
213 print("finished threads: ", nFinished)
214 if nFinished == context.nThreads:
215 context.event.set()
216
Benjamin Petersona54c9092009-01-13 02:11:23 +0000217 def test_pendingcalls_non_threaded(self):
Ezio Melotti13925002011-03-16 11:05:33 +0200218 #again, just using the main thread, likely they will all be dispatched at
Benjamin Petersona54c9092009-01-13 02:11:23 +0000219 #once. It is ok to ask for too many, because we loop until we find a slot.
220 #the loop can be interrupted to dispatch.
221 #there are only 32 dispatch slots, so we go for twice that!
222 l = []
223 n = 64
224 self.pendingcalls_submit(l, n)
225 self.pendingcalls_wait(l, n)
226
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200227
228class SubinterpreterTest(unittest.TestCase):
229
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100230 def test_subinterps(self):
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100231 import builtins
232 r, w = os.pipe()
233 code = """if 1:
234 import sys, builtins, pickle
235 with open({:d}, "wb") as f:
236 pickle.dump(id(sys.modules), f)
237 pickle.dump(id(builtins), f)
238 """.format(w)
239 with open(r, "rb") as f:
Victor Stinnered3b0bc2013-11-23 12:27:24 +0100240 ret = support.run_in_subinterp(code)
Antoine Pitrou2f828f22012-01-18 00:21:11 +0100241 self.assertEqual(ret, 0)
242 self.assertNotEqual(pickle.load(f), id(sys.modules))
243 self.assertNotEqual(pickle.load(f), id(builtins))
244
Antoine Pitrou7a2572c2013-08-01 20:43:26 +0200245
Martin v. Löwisc15bdef2009-05-29 14:47:46 +0000246# Bug #6012
247class Test6012(unittest.TestCase):
248 def test(self):
249 self.assertEqual(_testcapi.argparsing("Hello", "World"), 1)
Benjamin Petersona54c9092009-01-13 02:11:23 +0000250
Antoine Pitrou8e605772011-04-25 21:21:07 +0200251
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000252class EmbeddingTests(unittest.TestCase):
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000253 def setUp(self):
Antoine Pitrou8e605772011-04-25 21:21:07 +0200254 basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
Nick Coghlan4e641df2013-11-03 16:54:46 +1000255 exename = "_testembed"
256 if sys.platform.startswith("win"):
257 ext = ("_d" if "_d" in sys.executable else "") + ".exe"
258 exename += ext
259 exepath = os.path.dirname(sys.executable)
260 else:
261 exepath = os.path.join(basepath, "Modules")
262 self.test_exe = exe = os.path.join(exepath, exename)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000263 if not os.path.exists(exe):
264 self.skipTest("%r doesn't exist" % exe)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200265 # This is needed otherwise we get a fatal error:
266 # "Py_Initialize: Unable to get the locale encoding
267 # LookupError: no codec search functions registered: can't find encoding"
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000268 self.oldcwd = os.getcwd()
Antoine Pitrou8e605772011-04-25 21:21:07 +0200269 os.chdir(basepath)
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000270
271 def tearDown(self):
272 os.chdir(self.oldcwd)
273
274 def run_embedded_interpreter(self, *args):
275 """Runs a test in the embedded interpreter"""
276 cmd = [self.test_exe]
277 cmd.extend(args)
278 p = subprocess.Popen(cmd,
279 stdout=subprocess.PIPE,
280 stderr=subprocess.PIPE)
281 (out, err) = p.communicate()
282 self.assertEqual(p.returncode, 0,
283 "bad returncode %d, stderr is %r" %
284 (p.returncode, err))
285 return out.decode("latin1"), err.decode("latin1")
286
287 def test_subinterps(self):
288 # This is just a "don't crash" test
289 out, err = self.run_embedded_interpreter()
290 if support.verbose:
291 print()
292 print(out)
293 print(err)
294
Nick Coghlan4e641df2013-11-03 16:54:46 +1000295 @staticmethod
296 def _get_default_pipe_encoding():
297 rp, wp = os.pipe()
298 try:
299 with os.fdopen(wp, 'w') as w:
300 default_pipe_encoding = w.encoding
301 finally:
302 os.close(rp)
303 return default_pipe_encoding
304
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000305 def test_forced_io_encoding(self):
306 # Checks forced configuration of embedded interpreter IO streams
307 out, err = self.run_embedded_interpreter("forced_io_encoding")
308 if support.verbose:
309 print()
310 print(out)
311 print(err)
Nick Coghlan4e641df2013-11-03 16:54:46 +1000312 expected_stdin_encoding = sys.__stdin__.encoding
313 expected_pipe_encoding = self._get_default_pipe_encoding()
314 expected_output = os.linesep.join([
315 "--- Use defaults ---",
316 "Expected encoding: default",
317 "Expected errors: default",
318 "stdin: {0}:strict",
319 "stdout: {1}:strict",
320 "stderr: {1}:backslashreplace",
321 "--- Set errors only ---",
322 "Expected encoding: default",
323 "Expected errors: surrogateescape",
324 "stdin: {0}:surrogateescape",
325 "stdout: {1}:surrogateescape",
326 "stderr: {1}:backslashreplace",
327 "--- Set encoding only ---",
328 "Expected encoding: latin-1",
329 "Expected errors: default",
330 "stdin: latin-1:strict",
331 "stdout: latin-1:strict",
332 "stderr: latin-1:backslashreplace",
333 "--- Set encoding and errors ---",
334 "Expected encoding: latin-1",
335 "Expected errors: surrogateescape",
336 "stdin: latin-1:surrogateescape",
337 "stdout: latin-1:surrogateescape",
338 "stderr: latin-1:backslashreplace"]).format(expected_stdin_encoding,
339 expected_pipe_encoding)
Nick Coghlan3321fb82013-10-18 23:59:58 +1000340 # This is useful if we ever trip over odd platform behaviour
Nick Coghlan6508dc52013-10-18 01:44:22 +1000341 self.maxDiff = None
Nick Coghlan7d270ee2013-10-17 22:35:35 +1000342 self.assertEqual(out.strip(), expected_output)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200343
Larry Hastings8f904da2012-06-22 03:56:29 -0700344class SkipitemTest(unittest.TestCase):
345
346 def test_skipitem(self):
347 """
348 If this test failed, you probably added a new "format unit"
349 in Python/getargs.c, but neglected to update our poor friend
350 skipitem() in the same file. (If so, shame on you!)
351
Larry Hastings48ed3602012-06-22 12:58:36 -0700352 With a few exceptions**, this function brute-force tests all
353 printable ASCII*** characters (32 to 126 inclusive) as format units,
354 checking to see that PyArg_ParseTupleAndKeywords() return consistent
355 errors both when the unit is attempted to be used and when it is
356 skipped. If the format unit doesn't exist, we'll get one of two
357 specific error messages (one for used, one for skipped); if it does
358 exist we *won't* get that error--we'll get either no error or some
359 other error. If we get the specific "does not exist" error for one
360 test and not for the other, there's a mismatch, and the test fails.
Larry Hastings8f904da2012-06-22 03:56:29 -0700361
Larry Hastings48ed3602012-06-22 12:58:36 -0700362 ** Some format units have special funny semantics and it would
363 be difficult to accomodate them here. Since these are all
364 well-established and properly skipped in skipitem() we can
365 get away with not testing them--this test is really intended
366 to catch *new* format units.
367
368 *** Python C source files must be ASCII. Therefore it's impossible
369 to have non-ASCII format units.
370
Larry Hastings8f904da2012-06-22 03:56:29 -0700371 """
372 empty_tuple = ()
373 tuple_1 = (0,)
374 dict_b = {'b':1}
375 keywords = ["a", "b"]
376
Larry Hastings48ed3602012-06-22 12:58:36 -0700377 for i in range(32, 127):
Larry Hastings8f904da2012-06-22 03:56:29 -0700378 c = chr(i)
379
Larry Hastings8f904da2012-06-22 03:56:29 -0700380 # skip parentheses, the error reporting is inconsistent about them
381 # skip 'e', it's always a two-character code
382 # skip '|' and '$', they don't represent arguments anyway
Larry Hastings48ed3602012-06-22 12:58:36 -0700383 if c in '()e|$':
Larry Hastings8f904da2012-06-22 03:56:29 -0700384 continue
385
386 # test the format unit when not skipped
387 format = c + "i"
388 try:
389 # (note: the format string must be bytes!)
390 _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
391 format.encode("ascii"), keywords)
392 when_not_skipped = False
393 except TypeError as e:
394 s = "argument 1 must be impossible<bad format char>, not int"
395 when_not_skipped = (str(e) == s)
396 except RuntimeError as e:
397 when_not_skipped = False
398
399 # test the format unit when skipped
400 optional_format = "|" + format
401 try:
402 _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
403 optional_format.encode("ascii"), keywords)
404 when_skipped = False
405 except RuntimeError as e:
406 s = "impossible<bad format char>: '{}'".format(format)
407 when_skipped = (str(e) == s)
408
409 message = ("test_skipitem_parity: "
410 "detected mismatch between convertsimple and skipitem "
411 "for format unit '{}' ({}), not skipped {}, skipped {}".format(
412 c, i, when_skipped, when_not_skipped))
413 self.assertIs(when_skipped, when_not_skipped, message)
Antoine Pitrou8e605772011-04-25 21:21:07 +0200414
Jesus Cea6e1d2b62012-10-04 16:06:30 +0200415 def test_parse_tuple_and_keywords(self):
416 # parse_tuple_and_keywords error handling tests
417 self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
418 (), {}, 42, [])
419 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
420 (), {}, b'', 42)
421 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
422 (), {}, b'', [''] * 42)
423 self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
424 (), {}, b'', [42])
425
Ezio Melotti29267c82013-02-23 05:52:46 +0200426@unittest.skipUnless(threading, 'Threading required for this test.')
427class TestThreadState(unittest.TestCase):
428
429 @support.reap_threads
430 def test_thread_state(self):
431 # some extra thread-state tests driven via _testcapi
432 def target():
433 idents = []
434
435 def callback():
Ezio Melotti35246bd2013-02-23 05:58:38 +0200436 idents.append(threading.get_ident())
Ezio Melotti29267c82013-02-23 05:52:46 +0200437
438 _testcapi._test_thread_state(callback)
439 a = b = callback
440 time.sleep(1)
441 # Check our main thread is in the list exactly 3 times.
Ezio Melotti35246bd2013-02-23 05:58:38 +0200442 self.assertEqual(idents.count(threading.get_ident()), 3,
Ezio Melotti29267c82013-02-23 05:52:46 +0200443 "Couldn't find main thread correctly in the list")
444
445 target()
446 t = threading.Thread(target=target)
447 t.start()
448 t.join()
449
Zachary Warec12f09e2013-11-11 22:47:04 -0600450class Test_testcapi(unittest.TestCase):
451 def test__testcapi(self):
452 for name in dir(_testcapi):
453 if name.startswith('test_'):
Zachary Waredfcd6942013-11-11 22:59:23 -0600454 with self.subTest("internal", name=name):
455 test = getattr(_testcapi, name)
456 test()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000457
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000458if __name__ == "__main__":
Zachary Warec12f09e2013-11-11 22:47:04 -0600459 unittest.main()