Skip to content

Commit 75f38af

Browse files
authored
Revert "gh-128942: make array module thread safe (#128943)" (#130707)
The change regressed performance on scimark benchmarks from the pyperformance benchmark suite. This reverts commit 8ba0d7b.
1 parent da4899b commit 75f38af

File tree

4 files changed

+159
-784
lines changed

4 files changed

+159
-784
lines changed

Lib/test/test_array.py

-266
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,16 @@
33
"""
44

55
import collections.abc
6-
import io
76
import unittest
87
from test import support
98
from test.support import import_helper
109
from test.support import os_helper
11-
from test.support import threading_helper
1210
from test.support import _2G
1311
import weakref
1412
import pickle
1513
import operator
16-
import random
1714
import struct
1815
import sys
19-
import sysconfig
20-
import threading
2116
import warnings
2217

2318
import array
@@ -1678,266 +1673,5 @@ def test_gh_128961(self):
16781673
self.assertRaises(StopIteration, next, it)
16791674

16801675

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-
19421676
if __name__ == "__main__":
19431677
unittest.main()

Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst

-1
This file was deleted.

0 commit comments

Comments
 (0)