|
3 | 3 | """ |
4 | 4 |
|
5 | 5 | import collections.abc |
6 | | -import io |
7 | 6 | import unittest |
8 | 7 | from test import support |
9 | 8 | from test.support import import_helper |
10 | 9 | from test.support import os_helper |
11 | | -from test.support import threading_helper |
12 | 10 | from test.support import _2G |
13 | 11 | import weakref |
14 | 12 | import pickle |
15 | 13 | import operator |
16 | | -import random |
17 | 14 | import struct |
18 | 15 | import sys |
19 | | -import sysconfig |
20 | | -import threading |
21 | 16 | import warnings |
22 | 17 |
|
23 | 18 | import array |
@@ -1678,266 +1673,5 @@ def test_gh_128961(self): |
1678 | 1673 | self.assertRaises(StopIteration, next, it) |
1679 | 1674 |
|
1680 | 1675 |
|
1681 | | -class FreeThreadingTest(unittest.TestCase): |
1682 | | - # Test pretty much everything that can break under free-threading. |
1683 | | - # Non-deterministic, but at least one of these things will fail if |
1684 | | - # array module is not free-thread safe. |
1685 | | - |
1686 | | - @unittest.skipUnless(support.Py_GIL_DISABLED, 'this test can only possibly fail with GIL disabled') |
1687 | | - @threading_helper.reap_threads |
1688 | | - @threading_helper.requires_working_threading() |
1689 | | - def test_free_threading(self): |
1690 | | - def pop1(b, a): # MODIFIES! |
1691 | | - b.wait() |
1692 | | - try: a.pop() |
1693 | | - except IndexError: pass |
1694 | | - |
1695 | | - def append1(b, a): # MODIFIES! |
1696 | | - b.wait() |
1697 | | - a.append(2) |
1698 | | - |
1699 | | - def insert1(b, a): # MODIFIES! |
1700 | | - b.wait() |
1701 | | - a.insert(0, 2) |
1702 | | - |
1703 | | - def extend(b, a): # MODIFIES! |
1704 | | - c = array.array('i', [2]) |
1705 | | - b.wait() |
1706 | | - a.extend(c) |
1707 | | - |
1708 | | - def extend2(b, a, c): # MODIFIES! |
1709 | | - b.wait() |
1710 | | - a.extend(c) |
1711 | | - |
1712 | | - def inplace_concat(b, a): # MODIFIES! |
1713 | | - c = array.array('i', [2]) |
1714 | | - b.wait() |
1715 | | - a += c |
1716 | | - |
1717 | | - def inplace_concat2(b, a, c): # MODIFIES! |
1718 | | - b.wait() |
1719 | | - a += c |
1720 | | - |
1721 | | - def inplace_repeat2(b, a): # MODIFIES! |
1722 | | - b.wait() |
1723 | | - a *= 2 |
1724 | | - |
1725 | | - def clear(b, a, *args): # MODIFIES! |
1726 | | - b.wait() |
1727 | | - a.clear() |
1728 | | - |
1729 | | - def clear2(b, a, c): # MODIFIES c! |
1730 | | - b.wait() |
1731 | | - try: c.clear() |
1732 | | - except BufferError: pass |
1733 | | - |
1734 | | - def remove1(b, a): # MODIFIES! |
1735 | | - b.wait() |
1736 | | - try: a.remove(1) |
1737 | | - except ValueError: pass |
1738 | | - |
1739 | | - def fromunicode(b, a): # MODIFIES! |
1740 | | - b.wait() |
1741 | | - a.fromunicode('test') |
1742 | | - |
1743 | | - def frombytes(b, a): # MODIFIES! |
1744 | | - b.wait() |
1745 | | - a.frombytes(b'0000') |
1746 | | - |
1747 | | - def frombytes2(b, a, c): # MODIFIES! |
1748 | | - b.wait() |
1749 | | - a.frombytes(c) |
1750 | | - |
1751 | | - def fromlist(b, a): # MODIFIES! |
1752 | | - n = random.randint(0, 100) |
1753 | | - b.wait() |
1754 | | - a.fromlist([2] * n) |
1755 | | - |
1756 | | - def ass_subscr2(b, a, c): # MODIFIES! |
1757 | | - b.wait() |
1758 | | - a[:] = c |
1759 | | - |
1760 | | - def ass0(b, a): # modifies inplace |
1761 | | - b.wait() |
1762 | | - try: a[0] = 0 |
1763 | | - except IndexError: pass |
1764 | | - |
1765 | | - def byteswap(b, a): # modifies inplace |
1766 | | - b.wait() |
1767 | | - a.byteswap() |
1768 | | - |
1769 | | - def tounicode(b, a): |
1770 | | - b.wait() |
1771 | | - a.tounicode() |
1772 | | - |
1773 | | - def tobytes(b, a): |
1774 | | - b.wait() |
1775 | | - a.tobytes() |
1776 | | - |
1777 | | - def tolist(b, a): |
1778 | | - b.wait() |
1779 | | - a.tolist() |
1780 | | - |
1781 | | - def tofile(b, a): |
1782 | | - f = io.BytesIO() |
1783 | | - b.wait() |
1784 | | - a.tofile(f) |
1785 | | - |
1786 | | - def reduce_ex2(b, a): |
1787 | | - b.wait() |
1788 | | - a.__reduce_ex__(2) |
1789 | | - |
1790 | | - def reduce_ex3(b, a): |
1791 | | - b.wait() |
1792 | | - c = a.__reduce_ex__(3) |
1793 | | - assert not c[1] or 0xdd not in c[1][3] |
1794 | | - |
1795 | | - def copy(b, a): |
1796 | | - b.wait() |
1797 | | - c = a.__copy__() |
1798 | | - assert not c or 0xdd not in c |
1799 | | - |
1800 | | - def repr1(b, a): |
1801 | | - b.wait() |
1802 | | - repr(a) |
1803 | | - |
1804 | | - def repeat2(b, a): |
1805 | | - b.wait() |
1806 | | - a * 2 |
1807 | | - |
1808 | | - def count1(b, a): |
1809 | | - b.wait() |
1810 | | - a.count(1) |
1811 | | - |
1812 | | - def index1(b, a): |
1813 | | - b.wait() |
1814 | | - try: a.index(1) |
1815 | | - except ValueError: pass |
1816 | | - |
1817 | | - def contains1(b, a): |
1818 | | - b.wait() |
1819 | | - try: 1 in a |
1820 | | - except ValueError: pass |
1821 | | - |
1822 | | - def subscr0(b, a): |
1823 | | - b.wait() |
1824 | | - try: a[0] |
1825 | | - except IndexError: pass |
1826 | | - |
1827 | | - def concat(b, a): |
1828 | | - b.wait() |
1829 | | - a + a |
1830 | | - |
1831 | | - def concat2(b, a, c): |
1832 | | - b.wait() |
1833 | | - a + c |
1834 | | - |
1835 | | - def richcmplhs(b, a): |
1836 | | - c = a[:] |
1837 | | - b.wait() |
1838 | | - a == c |
1839 | | - |
1840 | | - def richcmprhs(b, a): |
1841 | | - c = a[:] |
1842 | | - b.wait() |
1843 | | - c == a |
1844 | | - |
1845 | | - def new(b, a): |
1846 | | - tc = a.typecode |
1847 | | - b.wait() |
1848 | | - array.array(tc, a) |
1849 | | - |
1850 | | - def repr_(b, a): |
1851 | | - b.wait() |
1852 | | - repr(a) |
1853 | | - |
1854 | | - def irepeat(b, a): # MODIFIES! |
1855 | | - b.wait() |
1856 | | - a *= 2 |
1857 | | - |
1858 | | - def newi(b, l): |
1859 | | - b.wait() |
1860 | | - array.array('i', l) |
1861 | | - |
1862 | | - def fromlistl(b, a, l): # MODIFIES! |
1863 | | - b.wait() |
1864 | | - a.fromlist(l) |
1865 | | - |
1866 | | - def fromlistlclear(b, a, l): # MODIFIES LIST! |
1867 | | - b.wait() |
1868 | | - l.clear() |
1869 | | - |
1870 | | - def iter_next(b, a, it): # MODIFIES ITERATOR! |
1871 | | - b.wait() |
1872 | | - list(it) |
1873 | | - |
1874 | | - def iter_reduce(b, a, it): |
1875 | | - b.wait() |
1876 | | - c = it.__reduce__() |
1877 | | - assert not c[1] or 0xdd not in c[1][0] |
1878 | | - |
1879 | | - def check(funcs, a=None, *args): |
1880 | | - if a is None: |
1881 | | - a = array.array('i', [1]) |
1882 | | - |
1883 | | - barrier = threading.Barrier(len(funcs)) |
1884 | | - threads = [] |
1885 | | - |
1886 | | - for func in funcs: |
1887 | | - thread = threading.Thread(target=func, args=(barrier, a, *args)) |
1888 | | - |
1889 | | - threads.append(thread) |
1890 | | - |
1891 | | - with threading_helper.start_threads(threads): |
1892 | | - pass |
1893 | | - |
1894 | | - check([pop1] * 10) |
1895 | | - check([pop1] + [subscr0] * 10) |
1896 | | - check([append1] * 10) |
1897 | | - check([insert1] * 10) |
1898 | | - check([pop1] + [index1] * 10) |
1899 | | - check([pop1] + [contains1] * 10) |
1900 | | - check([insert1] + [repeat2] * 10) |
1901 | | - check([pop1] + [repr1] * 10) |
1902 | | - check([inplace_repeat2] * 10) |
1903 | | - check([byteswap] * 10) |
1904 | | - check([insert1] + [clear] * 10) |
1905 | | - check([pop1] + [count1] * 10) |
1906 | | - check([remove1] * 10) |
1907 | | - check([clear] + [copy] * 10, array.array('B', b'0' * 0x400000)) |
1908 | | - check([pop1] + [reduce_ex2] * 10) |
1909 | | - check([clear] + [reduce_ex3] * 10, array.array('B', b'0' * 0x400000)) |
1910 | | - check([pop1] + [tobytes] * 10) |
1911 | | - check([pop1] + [tolist] * 10) |
1912 | | - check([clear, tounicode] * 10, array.array('w', 'a'*10000)) |
1913 | | - check([clear, tofile] * 10, array.array('w', 'a'*10000)) |
1914 | | - check([clear] + [extend] * 10) |
1915 | | - check([clear] + [inplace_concat] * 10) |
1916 | | - check([clear] + [concat] * 10, array.array('w', 'a'*10000)) |
1917 | | - check([fromunicode] * 10, array.array('w', 'a')) |
1918 | | - check([frombytes] * 10) |
1919 | | - check([fromlist] * 10) |
1920 | | - check([clear] + [richcmplhs] * 10, array.array('i', [1]*10000)) |
1921 | | - check([clear] + [richcmprhs] * 10, array.array('i', [1]*10000)) |
1922 | | - check([clear, ass0] * 10, array.array('i', [1]*10000)) # to test array_ass_item must disable Py_mp_ass_subscript |
1923 | | - check([clear] + [new] * 10, array.array('w', 'a'*10000)) |
1924 | | - check([clear] + [repr_] * 10, array.array('B', b'0' * 0x40000)) |
1925 | | - check([clear] + [repr_] * 10, array.array('B', b'0' * 0x40000)) |
1926 | | - check([clear] + [irepeat] * 10, array.array('B', b'0' * 0x40000)) |
1927 | | - check([clear] + [iter_reduce] * 10, a := array.array('B', b'0' * 0x400), iter(a)) |
1928 | | - |
1929 | | - # make sure we handle non-self objects correctly |
1930 | | - check([clear] + [newi] * 10, [2] * random.randint(0, 100)) |
1931 | | - check([fromlistlclear] + [fromlistl] * 10, array.array('i', [1]), [2] * random.randint(0, 100)) |
1932 | | - check([clear2] + [concat2] * 10, array.array('w', 'a'*10000), array.array('w', 'a'*10000)) |
1933 | | - check([clear2] + [inplace_concat2] * 10, array.array('w', 'a'*10000), array.array('w', 'a'*10000)) |
1934 | | - check([clear2] + [extend2] * 10, array.array('w', 'a'*10000), array.array('w', 'a'*10000)) |
1935 | | - check([clear2] + [ass_subscr2] * 10, array.array('w', 'a'*10000), array.array('w', 'a'*10000)) |
1936 | | - check([clear2] + [frombytes2] * 10, array.array('w', 'a'*10000), array.array('B', b'a'*10000)) |
1937 | | - |
1938 | | - # iterator stuff |
1939 | | - check([clear] + [iter_next] * 10, a := array.array('i', [1] * 10), iter(a)) |
1940 | | - |
1941 | | - |
1942 | 1676 | if __name__ == "__main__": |
1943 | 1677 | unittest.main() |
0 commit comments