|
1 | 1 | from collections import abc |
2 | 2 | from itertools import combinations |
3 | 3 | import array |
| 4 | +from concurrent.futures import InterpreterPoolExecutor |
4 | 5 | import gc |
5 | 6 | import math |
6 | 7 | import operator |
7 | | -import threading |
8 | 8 | import unittest |
9 | 9 | import platform |
10 | 10 | import struct |
@@ -40,24 +40,6 @@ def bigendian_to_native(value): |
40 | 40 | else: |
41 | 41 | return string_reverse(value) |
42 | 42 |
|
43 | | -# Helper for test_endian_table_init_subinterpreters |
44 | | -class _Result: |
45 | | - def __init__(self): |
46 | | - self.ret = -1 |
47 | | - self.err = None |
48 | | - |
49 | | -def _run_in_subinterp_worker(code, barrier, result): |
50 | | - """ |
51 | | - Worker function for a thread. Waits on the barrier, then runs the |
52 | | - code in a subinterpreter. |
53 | | - """ |
54 | | - try: |
55 | | - # Wait until all threads are ready to start simultaneously. |
56 | | - barrier.wait() |
57 | | - result.ret = support.run_in_subinterp(code) |
58 | | - except Exception as e: |
59 | | - result.err = e |
60 | | - |
61 | 43 | class StructTest(ComplexesAreIdenticalMixin, unittest.TestCase): |
62 | 44 | def test_isbigendian(self): |
63 | 45 | self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN) |
@@ -820,42 +802,13 @@ def test_c_complex_round_trip(self): |
820 | 802 | self.assertComplexesAreIdentical(z, round_trip) |
821 | 803 |
|
822 | 804 | def test_endian_table_init_subinterpreters(self): |
823 | | - # Verify that struct works correctly in subinterpreters after |
824 | | - # once-only endian table initialization (gh-140260), when |
825 | | - # initialized concurrently. |
826 | | - # Use struct in the main interpreter first. |
827 | | - self.assertEqual(struct.unpack('>i', struct.pack('>i', 1))[0], 1) |
828 | | - self.assertEqual(struct.unpack('<i', struct.pack('<i', 1))[0], 1) |
829 | | - |
830 | | - code = ( |
831 | | - "import struct\n" |
832 | | - "x = struct.pack('>i', 1)\n" |
833 | | - "assert struct.unpack('>i', x)[0] == 1\n" |
834 | | - "y = struct.pack('<i', 1)\n" |
835 | | - "assert struct.unpack('<i', y)[0] == 1\n" |
836 | | - ) |
837 | | - |
838 | | - num_threads = 3 |
839 | | - barrier = threading.Barrier(num_threads) |
840 | | - results = [_Result() for _ in range(num_threads)] |
841 | | - threads = [ |
842 | | - threading.Thread( |
843 | | - target=_run_in_subinterp_worker, |
844 | | - args=(code, barrier, results[i]) |
845 | | - ) |
846 | | - for i in range(num_threads) |
847 | | - ] |
848 | | - |
849 | | - for t in threads: |
850 | | - t.start() |
851 | | - |
852 | | - for t in threads: |
853 | | - t.join() |
854 | | - |
855 | | - for result in results: |
856 | | - if result.err: |
857 | | - raise result.err |
858 | | - self.assertEqual(result.ret, 0) |
| 805 | + # Verify that the _struct extension module can be initialized |
| 806 | + # concurrently in subinterpreters (gh-140260). |
| 807 | + code = "import struct" |
| 808 | + with InterpreterPoolExecutor(max_workers=5) as executor: |
| 809 | + results = executor.map(support.run_in_subinterp, [code] * 5) |
| 810 | + for ret in results: |
| 811 | + self.assertEqual(ret, 0) |
859 | 812 |
|
860 | 813 |
|
861 | 814 | class UnpackIteratorTest(unittest.TestCase): |
|
0 commit comments