blob: 58258bb66af8a8508d2d56218897cd86fc97122d [file] [log] [blame]
Joannah Nanjekyebae872f2020-06-10 00:53:23 -03001import contextlib
2import os
3import threading
4from textwrap import dedent
5import unittest
6import time
7
8import _xxsubinterpreters as _interpreters
9from test.support import interpreters
10
11
12def _captured_script(script):
13 r, w = os.pipe()
14 indented = script.replace('\n', '\n ')
15 wrapped = dedent(f"""
16 import contextlib
17 with open({w}, 'w') as spipe:
18 with contextlib.redirect_stdout(spipe):
19 {indented}
20 """)
21 return wrapped, open(r)
22
23
24def clean_up_interpreters():
25 for interp in interpreters.list_all():
26 if interp.id == 0: # main
27 continue
28 try:
29 interp.close()
30 except RuntimeError:
31 pass # already destroyed
32
33
Eric Snow818f5b52020-06-16 18:24:40 -060034def _run_output(interp, request, channels=None):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030035 script, rpipe = _captured_script(request)
36 with rpipe:
Eric Snow818f5b52020-06-16 18:24:40 -060037 interp.run(script, channels=channels)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030038 return rpipe.read()
39
40
41@contextlib.contextmanager
42def _running(interp):
43 r, w = os.pipe()
44 def run():
45 interp.run(dedent(f"""
46 # wait for "signal"
47 with open({r}) as rpipe:
48 rpipe.read()
49 """))
50
51 t = threading.Thread(target=run)
52 t.start()
53
54 yield
55
56 with open(w, 'w') as spipe:
57 spipe.write('done')
58 t.join()
59
60
61class TestBase(unittest.TestCase):
62
63 def tearDown(self):
64 clean_up_interpreters()
65
66
67class CreateTests(TestBase):
68
69 def test_in_main(self):
70 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -060071 self.assertIsInstance(interp, interpreters.Interpreter)
72 self.assertIn(interp, interpreters.list_all())
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030073
74 def test_in_thread(self):
75 lock = threading.Lock()
Eric Snow818f5b52020-06-16 18:24:40 -060076 interp = None
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030077 def f():
Eric Snow818f5b52020-06-16 18:24:40 -060078 nonlocal interp
79 interp = interpreters.create()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030080 lock.acquire()
81 lock.release()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030082 t = threading.Thread(target=f)
83 with lock:
84 t.start()
85 t.join()
Eric Snow818f5b52020-06-16 18:24:40 -060086 self.assertIn(interp, interpreters.list_all())
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030087
88 def test_in_subinterpreter(self):
89 main, = interpreters.list_all()
90 interp = interpreters.create()
91 out = _run_output(interp, dedent("""
92 from test.support import interpreters
93 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -060094 print(interp.id)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030095 """))
Eric Snow818f5b52020-06-16 18:24:40 -060096 interp2 = interpreters.Interpreter(int(out))
97 self.assertEqual(interpreters.list_all(), [main, interp, interp2])
Joannah Nanjekyebae872f2020-06-10 00:53:23 -030098
99 def test_after_destroy_all(self):
100 before = set(interpreters.list_all())
101 # Create 3 subinterpreters.
102 interp_lst = []
103 for _ in range(3):
104 interps = interpreters.create()
105 interp_lst.append(interps)
106 # Now destroy them.
107 for interp in interp_lst:
108 interp.close()
109 # Finally, create another.
110 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600111 self.assertEqual(set(interpreters.list_all()), before | {interp})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300112
113 def test_after_destroy_some(self):
114 before = set(interpreters.list_all())
115 # Create 3 subinterpreters.
116 interp1 = interpreters.create()
117 interp2 = interpreters.create()
118 interp3 = interpreters.create()
119 # Now destroy 2 of them.
120 interp1.close()
121 interp2.close()
122 # Finally, create another.
123 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600124 self.assertEqual(set(interpreters.list_all()), before | {interp3, interp})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300125
126
127class GetCurrentTests(TestBase):
128
129 def test_main(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600130 main = interpreters.get_main()
131 current = interpreters.get_current()
132 self.assertEqual(current, main)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300133
134 def test_subinterpreter(self):
135 main = _interpreters.get_main()
136 interp = interpreters.create()
137 out = _run_output(interp, dedent("""
138 from test.support import interpreters
139 cur = interpreters.get_current()
Eric Snow818f5b52020-06-16 18:24:40 -0600140 print(cur.id)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300141 """))
Eric Snow818f5b52020-06-16 18:24:40 -0600142 current = interpreters.Interpreter(int(out))
143 self.assertNotEqual(current, main)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300144
145
146class ListAllTests(TestBase):
147
148 def test_initial(self):
149 interps = interpreters.list_all()
150 self.assertEqual(1, len(interps))
151
152 def test_after_creating(self):
153 main = interpreters.get_current()
154 first = interpreters.create()
155 second = interpreters.create()
156
157 ids = []
158 for interp in interpreters.list_all():
159 ids.append(interp.id)
160
161 self.assertEqual(ids, [main.id, first.id, second.id])
162
163 def test_after_destroying(self):
164 main = interpreters.get_current()
165 first = interpreters.create()
166 second = interpreters.create()
167 first.close()
168
169 ids = []
170 for interp in interpreters.list_all():
171 ids.append(interp.id)
172
173 self.assertEqual(ids, [main.id, second.id])
174
175
Eric Snow818f5b52020-06-16 18:24:40 -0600176class TestInterpreterAttrs(TestBase):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300177
Eric Snow818f5b52020-06-16 18:24:40 -0600178 def test_id_type(self):
179 main = interpreters.get_main()
180 current = interpreters.get_current()
181 interp = interpreters.create()
182 self.assertIsInstance(main.id, _interpreters.InterpreterID)
183 self.assertIsInstance(current.id, _interpreters.InterpreterID)
184 self.assertIsInstance(interp.id, _interpreters.InterpreterID)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300185
Eric Snow818f5b52020-06-16 18:24:40 -0600186 def test_main_id(self):
187 main = interpreters.get_main()
188 self.assertEqual(main.id, 0)
189
190 def test_custom_id(self):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300191 interp = interpreters.Interpreter(1)
Eric Snow818f5b52020-06-16 18:24:40 -0600192 self.assertEqual(interp.id, 1)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300193
Eric Snow818f5b52020-06-16 18:24:40 -0600194 with self.assertRaises(TypeError):
195 interpreters.Interpreter('1')
196
197 def test_id_readonly(self):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300198 interp = interpreters.Interpreter(1)
199 with self.assertRaises(AttributeError):
200 interp.id = 2
201
Eric Snow818f5b52020-06-16 18:24:40 -0600202 @unittest.skip('not ready yet (see bpo-32604)')
203 def test_main_isolated(self):
204 main = interpreters.get_main()
205 self.assertFalse(main.isolated)
206
207 @unittest.skip('not ready yet (see bpo-32604)')
208 def test_subinterpreter_isolated_default(self):
209 interp = interpreters.create()
210 self.assertFalse(interp.isolated)
211
212 def test_subinterpreter_isolated_explicit(self):
213 interp1 = interpreters.create(isolated=True)
214 interp2 = interpreters.create(isolated=False)
215 self.assertTrue(interp1.isolated)
216 self.assertFalse(interp2.isolated)
217
218 @unittest.skip('not ready yet (see bpo-32604)')
219 def test_custom_isolated_default(self):
220 interp = interpreters.Interpreter(1)
221 self.assertFalse(interp.isolated)
222
223 def test_custom_isolated_explicit(self):
224 interp1 = interpreters.Interpreter(1, isolated=True)
225 interp2 = interpreters.Interpreter(1, isolated=False)
226 self.assertTrue(interp1.isolated)
227 self.assertFalse(interp2.isolated)
228
229 def test_isolated_readonly(self):
230 interp = interpreters.Interpreter(1)
231 with self.assertRaises(AttributeError):
232 interp.isolated = True
233
234 def test_equality(self):
235 interp1 = interpreters.create()
236 interp2 = interpreters.create()
237 self.assertEqual(interp1, interp1)
238 self.assertNotEqual(interp1, interp2)
239
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300240
241class TestInterpreterIsRunning(TestBase):
242
243 def test_main(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600244 main = interpreters.get_main()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300245 self.assertTrue(main.is_running())
246
247 def test_subinterpreter(self):
248 interp = interpreters.create()
249 self.assertFalse(interp.is_running())
250
251 with _running(interp):
252 self.assertTrue(interp.is_running())
253 self.assertFalse(interp.is_running())
254
255 def test_from_subinterpreter(self):
256 interp = interpreters.create()
257 out = _run_output(interp, dedent(f"""
258 import _xxsubinterpreters as _interpreters
259 if _interpreters.is_running({interp.id}):
260 print(True)
261 else:
262 print(False)
263 """))
264 self.assertEqual(out.strip(), 'True')
265
266 def test_already_destroyed(self):
267 interp = interpreters.create()
268 interp.close()
269 with self.assertRaises(RuntimeError):
270 interp.is_running()
271
Eric Snow818f5b52020-06-16 18:24:40 -0600272 def test_does_not_exist(self):
273 interp = interpreters.Interpreter(1_000_000)
274 with self.assertRaises(RuntimeError):
275 interp.is_running()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300276
Eric Snow818f5b52020-06-16 18:24:40 -0600277 def test_bad_id(self):
278 interp = interpreters.Interpreter(-1)
279 with self.assertRaises(ValueError):
280 interp.is_running()
281
282
283class TestInterpreterClose(TestBase):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300284
285 def test_basic(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600286 main = interpreters.get_main()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300287 interp1 = interpreters.create()
288 interp2 = interpreters.create()
289 interp3 = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600290 self.assertEqual(set(interpreters.list_all()),
291 {main, interp1, interp2, interp3})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300292 interp2.close()
Eric Snow818f5b52020-06-16 18:24:40 -0600293 self.assertEqual(set(interpreters.list_all()),
294 {main, interp1, interp3})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300295
296 def test_all(self):
297 before = set(interpreters.list_all())
298 interps = set()
299 for _ in range(3):
300 interp = interpreters.create()
301 interps.add(interp)
Eric Snow818f5b52020-06-16 18:24:40 -0600302 self.assertEqual(set(interpreters.list_all()), before | interps)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300303 for interp in interps:
304 interp.close()
Eric Snow818f5b52020-06-16 18:24:40 -0600305 self.assertEqual(set(interpreters.list_all()), before)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300306
307 def test_main(self):
308 main, = interpreters.list_all()
309 with self.assertRaises(RuntimeError):
310 main.close()
311
312 def f():
313 with self.assertRaises(RuntimeError):
314 main.close()
315
316 t = threading.Thread(target=f)
317 t.start()
318 t.join()
319
320 def test_already_destroyed(self):
321 interp = interpreters.create()
322 interp.close()
323 with self.assertRaises(RuntimeError):
324 interp.close()
325
Eric Snow818f5b52020-06-16 18:24:40 -0600326 def test_does_not_exist(self):
327 interp = interpreters.Interpreter(1_000_000)
328 with self.assertRaises(RuntimeError):
329 interp.close()
330
331 def test_bad_id(self):
332 interp = interpreters.Interpreter(-1)
333 with self.assertRaises(ValueError):
334 interp.close()
335
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300336 def test_from_current(self):
337 main, = interpreters.list_all()
338 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600339 out = _run_output(interp, dedent(f"""
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300340 from test.support import interpreters
Eric Snow818f5b52020-06-16 18:24:40 -0600341 interp = interpreters.Interpreter({int(interp.id)})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300342 try:
Eric Snow818f5b52020-06-16 18:24:40 -0600343 interp.close()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300344 except RuntimeError:
Eric Snow818f5b52020-06-16 18:24:40 -0600345 print('failed')
346 """))
347 self.assertEqual(out.strip(), 'failed')
348 self.assertEqual(set(interpreters.list_all()), {main, interp})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300349
350 def test_from_sibling(self):
351 main, = interpreters.list_all()
352 interp1 = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600353 interp2 = interpreters.create()
354 self.assertEqual(set(interpreters.list_all()),
355 {main, interp1, interp2})
356 interp1.run(dedent(f"""
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300357 from test.support import interpreters
Eric Snow818f5b52020-06-16 18:24:40 -0600358 interp2 = interpreters.Interpreter(int({interp2.id}))
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300359 interp2.close()
Eric Snow818f5b52020-06-16 18:24:40 -0600360 interp3 = interpreters.create()
361 interp3.close()
362 """))
363 self.assertEqual(set(interpreters.list_all()), {main, interp1})
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300364
365 def test_from_other_thread(self):
366 interp = interpreters.create()
367 def f():
368 interp.close()
369
370 t = threading.Thread(target=f)
371 t.start()
372 t.join()
373
374 def test_still_running(self):
375 main, = interpreters.list_all()
376 interp = interpreters.create()
377 with _running(interp):
378 with self.assertRaises(RuntimeError):
379 interp.close()
380 self.assertTrue(interp.is_running())
381
382
383class TestInterpreterRun(TestBase):
384
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300385 def test_success(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600386 interp = interpreters.create()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300387 script, file = _captured_script('print("it worked!", end="")')
388 with file:
Eric Snow818f5b52020-06-16 18:24:40 -0600389 interp.run(script)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300390 out = file.read()
391
392 self.assertEqual(out, 'it worked!')
393
394 def test_in_thread(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600395 interp = interpreters.create()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300396 script, file = _captured_script('print("it worked!", end="")')
397 with file:
398 def f():
Eric Snow818f5b52020-06-16 18:24:40 -0600399 interp.run(script)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300400
401 t = threading.Thread(target=f)
402 t.start()
403 t.join()
404 out = file.read()
405
406 self.assertEqual(out, 'it worked!')
407
408 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
409 def test_fork(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600410 interp = interpreters.create()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300411 import tempfile
412 with tempfile.NamedTemporaryFile('w+') as file:
413 file.write('')
414 file.flush()
415
416 expected = 'spam spam spam spam spam'
417 script = dedent(f"""
418 import os
419 try:
420 os.fork()
421 except RuntimeError:
422 with open('{file.name}', 'w') as out:
423 out.write('{expected}')
424 """)
Eric Snow818f5b52020-06-16 18:24:40 -0600425 interp.run(script)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300426
427 file.seek(0)
428 content = file.read()
429 self.assertEqual(content, expected)
430
431 def test_already_running(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600432 interp = interpreters.create()
433 with _running(interp):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300434 with self.assertRaises(RuntimeError):
Eric Snow818f5b52020-06-16 18:24:40 -0600435 interp.run('print("spam")')
436
437 def test_does_not_exist(self):
438 interp = interpreters.Interpreter(1_000_000)
439 with self.assertRaises(RuntimeError):
440 interp.run('print("spam")')
441
442 def test_bad_id(self):
443 interp = interpreters.Interpreter(-1)
444 with self.assertRaises(ValueError):
445 interp.run('print("spam")')
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300446
447 def test_bad_script(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600448 interp = interpreters.create()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300449 with self.assertRaises(TypeError):
Eric Snow818f5b52020-06-16 18:24:40 -0600450 interp.run(10)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300451
452 def test_bytes_for_script(self):
Eric Snow818f5b52020-06-16 18:24:40 -0600453 interp = interpreters.create()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300454 with self.assertRaises(TypeError):
Eric Snow818f5b52020-06-16 18:24:40 -0600455 interp.run(b'print("spam")')
456
457 # test_xxsubinterpreters covers the remaining Interpreter.run() behavior.
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300458
459
460class TestIsShareable(TestBase):
461
462 def test_default_shareables(self):
463 shareables = [
464 # singletons
465 None,
466 # builtin objects
467 b'spam',
468 'spam',
469 10,
470 -10,
471 ]
472 for obj in shareables:
473 with self.subTest(obj):
Eric Snow818f5b52020-06-16 18:24:40 -0600474 shareable = interpreters.is_shareable(obj)
475 self.assertTrue(shareable)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300476
477 def test_not_shareable(self):
478 class Cheese:
479 def __init__(self, name):
480 self.name = name
481 def __str__(self):
482 return self.name
483
484 class SubBytes(bytes):
485 """A subclass of a shareable type."""
486
487 not_shareables = [
488 # singletons
489 True,
490 False,
491 NotImplemented,
492 ...,
493 # builtin types and objects
494 type,
495 object,
496 object(),
497 Exception(),
498 100.0,
499 # user-defined types and objects
500 Cheese,
501 Cheese('Wensleydale'),
502 SubBytes(b'spam'),
503 ]
504 for obj in not_shareables:
505 with self.subTest(repr(obj)):
506 self.assertFalse(
507 interpreters.is_shareable(obj))
508
509
Eric Snow818f5b52020-06-16 18:24:40 -0600510class TestChannels(TestBase):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300511
Eric Snow818f5b52020-06-16 18:24:40 -0600512 def test_create(self):
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300513 r, s = interpreters.create_channel()
514 self.assertIsInstance(r, interpreters.RecvChannel)
515 self.assertIsInstance(s, interpreters.SendChannel)
516
Eric Snow818f5b52020-06-16 18:24:40 -0600517 def test_list_all(self):
518 self.assertEqual(interpreters.list_all_channels(), [])
519 created = set()
520 for _ in range(3):
521 ch = interpreters.create_channel()
522 created.add(ch)
523 after = set(interpreters.list_all_channels())
524 self.assertEqual(after, created)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300525
Eric Snow818f5b52020-06-16 18:24:40 -0600526
527class TestRecvChannelAttrs(TestBase):
528
529 def test_id_type(self):
530 rch, _ = interpreters.create_channel()
531 self.assertIsInstance(rch.id, _interpreters.ChannelID)
532
533 def test_custom_id(self):
534 rch = interpreters.RecvChannel(1)
535 self.assertEqual(rch.id, 1)
536
537 with self.assertRaises(TypeError):
538 interpreters.RecvChannel('1')
539
540 def test_id_readonly(self):
541 rch = interpreters.RecvChannel(1)
542 with self.assertRaises(AttributeError):
543 rch.id = 2
544
545 def test_equality(self):
546 ch1, _ = interpreters.create_channel()
547 ch2, _ = interpreters.create_channel()
548 self.assertEqual(ch1, ch1)
549 self.assertNotEqual(ch1, ch2)
550
551
552class TestSendChannelAttrs(TestBase):
553
554 def test_id_type(self):
555 _, sch = interpreters.create_channel()
556 self.assertIsInstance(sch.id, _interpreters.ChannelID)
557
558 def test_custom_id(self):
559 sch = interpreters.SendChannel(1)
560 self.assertEqual(sch.id, 1)
561
562 with self.assertRaises(TypeError):
563 interpreters.SendChannel('1')
564
565 def test_id_readonly(self):
566 sch = interpreters.SendChannel(1)
567 with self.assertRaises(AttributeError):
568 sch.id = 2
569
570 def test_equality(self):
571 _, ch1 = interpreters.create_channel()
572 _, ch2 = interpreters.create_channel()
573 self.assertEqual(ch1, ch1)
574 self.assertNotEqual(ch1, ch2)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300575
576
577class TestSendRecv(TestBase):
578
579 def test_send_recv_main(self):
580 r, s = interpreters.create_channel()
581 orig = b'spam'
Eric Snow818f5b52020-06-16 18:24:40 -0600582 s.send_nowait(orig)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300583 obj = r.recv()
584
585 self.assertEqual(obj, orig)
586 self.assertIsNot(obj, orig)
587
588 def test_send_recv_same_interpreter(self):
589 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600590 interp.run(dedent("""
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300591 from test.support import interpreters
592 r, s = interpreters.create_channel()
593 orig = b'spam'
Eric Snow818f5b52020-06-16 18:24:40 -0600594 s.send_nowait(orig)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300595 obj = r.recv()
Eric Snow818f5b52020-06-16 18:24:40 -0600596 assert obj == orig, 'expected: obj == orig'
597 assert obj is not orig, 'expected: obj is not orig'
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300598 """))
599
Eric Snow818f5b52020-06-16 18:24:40 -0600600 @unittest.skip('broken (see BPO-...)')
601 def test_send_recv_different_interpreters(self):
602 r1, s1 = interpreters.create_channel()
603 r2, s2 = interpreters.create_channel()
604 orig1 = b'spam'
605 s1.send_nowait(orig1)
606 out = _run_output(
607 interpreters.create(),
608 dedent(f"""
609 obj1 = r.recv()
610 assert obj1 == b'spam', 'expected: obj1 == orig1'
611 # When going to another interpreter we get a copy.
612 assert id(obj1) != {id(orig1)}, 'expected: obj1 is not orig1'
613 orig2 = b'eggs'
614 print(id(orig2))
615 s.send_nowait(orig2)
616 """),
617 channels=dict(r=r1, s=s2),
618 )
619 obj2 = r2.recv()
620
621 self.assertEqual(obj2, b'eggs')
622 self.assertNotEqual(id(obj2), int(out))
623
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300624 def test_send_recv_different_threads(self):
625 r, s = interpreters.create_channel()
626
627 def f():
628 while True:
629 try:
630 obj = r.recv()
631 break
632 except interpreters.ChannelEmptyError:
633 time.sleep(0.1)
634 s.send(obj)
635 t = threading.Thread(target=f)
636 t.start()
637
Eric Snow818f5b52020-06-16 18:24:40 -0600638 orig = b'spam'
639 s.send(orig)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300640 t.join()
641 obj = r.recv()
642
Eric Snow818f5b52020-06-16 18:24:40 -0600643 self.assertEqual(obj, orig)
644 self.assertIsNot(obj, orig)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300645
646 def test_send_recv_nowait_main(self):
647 r, s = interpreters.create_channel()
648 orig = b'spam'
Eric Snow818f5b52020-06-16 18:24:40 -0600649 s.send_nowait(orig)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300650 obj = r.recv_nowait()
651
652 self.assertEqual(obj, orig)
653 self.assertIsNot(obj, orig)
654
Eric Snow818f5b52020-06-16 18:24:40 -0600655 def test_send_recv_nowait_main_with_default(self):
656 r, _ = interpreters.create_channel()
657 obj = r.recv_nowait(None)
658
659 self.assertIsNone(obj)
660
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300661 def test_send_recv_nowait_same_interpreter(self):
662 interp = interpreters.create()
Eric Snow818f5b52020-06-16 18:24:40 -0600663 interp.run(dedent("""
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300664 from test.support import interpreters
665 r, s = interpreters.create_channel()
666 orig = b'spam'
Eric Snow818f5b52020-06-16 18:24:40 -0600667 s.send_nowait(orig)
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300668 obj = r.recv_nowait()
Eric Snow818f5b52020-06-16 18:24:40 -0600669 assert obj == orig, 'expected: obj == orig'
670 # When going back to the same interpreter we get the same object.
671 assert obj is not orig, 'expected: obj is not orig'
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300672 """))
673
Eric Snow818f5b52020-06-16 18:24:40 -0600674 @unittest.skip('broken (see BPO-...)')
675 def test_send_recv_nowait_different_interpreters(self):
676 r1, s1 = interpreters.create_channel()
677 r2, s2 = interpreters.create_channel()
678 orig1 = b'spam'
679 s1.send_nowait(orig1)
680 out = _run_output(
681 interpreters.create(),
682 dedent(f"""
683 obj1 = r.recv_nowait()
684 assert obj1 == b'spam', 'expected: obj1 == orig1'
685 # When going to another interpreter we get a copy.
686 assert id(obj1) != {id(orig1)}, 'expected: obj1 is not orig1'
687 orig2 = b'eggs'
688 print(id(orig2))
689 s.send_nowait(orig2)
690 """),
691 channels=dict(r=r1, s=s2),
692 )
693 obj2 = r2.recv_nowait()
Joannah Nanjekyebae872f2020-06-10 00:53:23 -0300694
Eric Snow818f5b52020-06-16 18:24:40 -0600695 self.assertEqual(obj2, b'eggs')
696 self.assertNotEqual(id(obj2), int(out))
697
698 def test_recv_channel_does_not_exist(self):
699 ch = interpreters.RecvChannel(1_000_000)
700 with self.assertRaises(interpreters.ChannelNotFoundError):
701 ch.recv()
702
703 def test_send_channel_does_not_exist(self):
704 ch = interpreters.SendChannel(1_000_000)
705 with self.assertRaises(interpreters.ChannelNotFoundError):
706 ch.send(b'spam')
707
708 def test_recv_nowait_channel_does_not_exist(self):
709 ch = interpreters.RecvChannel(1_000_000)
710 with self.assertRaises(interpreters.ChannelNotFoundError):
711 ch.recv_nowait()
712
713 def test_send_nowait_channel_does_not_exist(self):
714 ch = interpreters.SendChannel(1_000_000)
715 with self.assertRaises(interpreters.ChannelNotFoundError):
716 ch.send_nowait(b'spam')
717
718 def test_recv_nowait_empty(self):
719 ch, _ = interpreters.create_channel()
720 with self.assertRaises(interpreters.ChannelEmptyError):
721 ch.recv_nowait()
722
723 def test_recv_nowait_default(self):
724 default = object()
725 rch, sch = interpreters.create_channel()
726 obj1 = rch.recv_nowait(default)
727 sch.send_nowait(None)
728 sch.send_nowait(1)
729 sch.send_nowait(b'spam')
730 sch.send_nowait(b'eggs')
731 obj2 = rch.recv_nowait(default)
732 obj3 = rch.recv_nowait(default)
733 obj4 = rch.recv_nowait()
734 obj5 = rch.recv_nowait(default)
735 obj6 = rch.recv_nowait(default)
736
737 self.assertIs(obj1, default)
738 self.assertIs(obj2, None)
739 self.assertEqual(obj3, 1)
740 self.assertEqual(obj4, b'spam')
741 self.assertEqual(obj5, b'eggs')
742 self.assertIs(obj6, default)