Skip to content

Commit f62f603

Browse files
authored
Merge branch 'main' into extend_ipv6_tests
2 parents 770e6df + e06bebb commit f62f603

File tree

15 files changed

+885
-217
lines changed

15 files changed

+885
-217
lines changed

Doc/library/xmlrpc.client.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ between conformable Python objects and XML on the wire.
6161
The *headers* parameter is an optional sequence of HTTP headers to send with
6262
each request, expressed as a sequence of 2-tuples representing the header
6363
name and value. (e.g. ``[('Header-Name', 'value')]``).
64+
If an HTTPS URL is provided, *context* may be :class:`ssl.SSLContext`
65+
and configures the SSL settings of the underlying HTTPS connection.
6466
The obsolete *use_datetime* flag is similar to *use_builtin_types* but it
6567
applies only to date/time values.
6668

@@ -75,9 +77,7 @@ between conformable Python objects and XML on the wire.
7577
portion will be base64-encoded as an HTTP 'Authorization' header, and sent to
7678
the remote server as part of the connection process when invoking an XML-RPC
7779
method. You only need to use this if the remote server requires a Basic
78-
Authentication user and password. If an HTTPS URL is provided, *context* may
79-
be :class:`ssl.SSLContext` and configures the SSL settings of the underlying
80-
HTTPS connection.
80+
Authentication user and password.
8181

8282
The returned instance is a proxy object with methods that can be used to invoke
8383
corresponding RPC calls on the remote server. If the remote server supports the

Include/internal/pycore_runtime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ extern "C" {
2323
#include "pycore_pymem.h" // struct _pymem_allocators
2424
#include "pycore_pythread.h" // struct _pythread_runtime_state
2525
#include "pycore_signal.h" // struct _signals_runtime_state
26+
#include "pycore_time.h" // struct _PyTime_runtime_state
2627
#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state
2728
#include "pycore_typeobject.h" // struct _types_runtime_state
2829
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_state
@@ -168,6 +169,7 @@ typedef struct pyruntimestate {
168169
struct _Py_float_runtime_state float_state;
169170
struct _Py_unicode_runtime_state unicode_state;
170171
struct _types_runtime_state types;
172+
struct _Py_time_runtime_state time;
171173

172174
#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
173175
// Used in "Python/emscripten_trampoline.c" to choose between type

Include/internal/pycore_time.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,18 @@ extern double _PyTimeFraction_Resolution(
331331
const _PyTimeFraction *frac);
332332

333333

334+
// --- _Py_time_runtime_state ------------------------------------------------
335+
336+
struct _Py_time_runtime_state {
337+
#if defined(MS_WINDOWS) || defined(__APPLE__)
338+
_PyTimeFraction base;
339+
#else
340+
char _unused;
341+
#endif
342+
};
343+
344+
extern PyStatus _PyTime_Init(struct _Py_time_runtime_state *state);
345+
334346
#ifdef __cplusplus
335347
}
336348
#endif

Lib/test/test_array.py

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
"""
44

55
import collections.abc
6+
import io
67
import unittest
78
from test import support
89
from test.support import import_helper
910
from test.support import os_helper
11+
from test.support import threading_helper
1012
from test.support import _2G
1113
import weakref
1214
import pickle
1315
import operator
16+
import random
1417
import struct
1518
import sys
19+
import sysconfig
20+
import threading
1621
import warnings
1722

1823
import array
@@ -1673,5 +1678,266 @@ def test_gh_128961(self):
16731678
self.assertRaises(StopIteration, next, it)
16741679

16751680

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+
16761942
if __name__ == "__main__":
16771943
unittest.main()

Lib/test/test_bytes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,12 +2380,22 @@ def ass_subscript(b, a): # MODIFIES!
23802380
b.wait()
23812381
a[:] = c
23822382

2383+
def ass_subscript2(b, a, c): # MODIFIES!
2384+
b.wait()
2385+
a[:] = c
2386+
assert b'\xdd' not in a
2387+
23832388
def mod(b, a):
23842389
c = tuple(range(4096))
23852390
b.wait()
23862391
try: a % c
23872392
except TypeError: pass
23882393

2394+
def mod2(b, a, c):
2395+
b.wait()
2396+
d = a % c
2397+
assert b'\xdd' not in d
2398+
23892399
def repr_(b, a):
23902400
b.wait()
23912401
repr(a)
@@ -2503,7 +2513,9 @@ def check(funcs, a=None, *args):
25032513

25042514
check([clear] + [contains] * 10)
25052515
check([clear] + [subscript] * 10)
2516+
check([clear2] + [ass_subscript2] * 10, None, bytearray(b'0' * 0x400000))
25062517
check([clear] + [mod] * 10, bytearray(b'%d' * 4096))
2518+
check([clear2] + [mod2] * 10, bytearray(b'%s'), bytearray(b'0' * 0x400000))
25072519

25082520
check([clear] + [capitalize] * 10, bytearray(b'a' * 0x40000))
25092521
check([clear] + [center] * 10, bytearray(b'a' * 0x40000))

Lib/test/test_grammar.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,6 +1972,18 @@ async def foo():
19721972
with self.assertRaises(Done):
19731973
foo().send(None)
19741974

1975+
def test_complex_lambda(self):
1976+
def test1(foo, bar):
1977+
return ""
1978+
1979+
def test2():
1980+
return f"{test1(
1981+
foo=lambda: '、、、、、、、、、、、、、、、、、',
1982+
bar=lambda: 'abcdefghijklmnopqrstuvwxyz 123456789 123456789',
1983+
)}"
1984+
1985+
self.assertEqual(test2(), "")
1986+
19751987

19761988
if __name__ == '__main__':
19771989
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix two more :class:`bytearray` functions for :term:`free threading`.

0 commit comments

Comments
 (0)