Skip to content

Commit 25f14a2

Browse files
authored
support for 3.14.0a5, 3.13.2, 3.12.9, pypy v7.3.18 (#211)
1 parent af537d1 commit 25f14a2

File tree

119 files changed

+24121
-79
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+24121
-79
lines changed

py3.12/Modules/_multiprocess/semaphore.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ typedef struct {
2323
char *name;
2424
} SemLockObject;
2525

26+
#define _SemLockObject_CAST(op) ((SemLockObject *)(op))
27+
2628
/*[python input]
2729
class SEM_HANDLE_converter(CConverter):
2830
type = "SEM_HANDLE"
@@ -567,8 +569,9 @@ _multiprocess_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle,
567569
}
568570

569571
static void
570-
semlock_dealloc(SemLockObject* self)
572+
semlock_dealloc(PyObject *op)
571573
{
574+
SemLockObject *self = _SemLockObject_CAST(op);
572575
PyTypeObject *tp = Py_TYPE(self);
573576
PyObject_GC_UnTrack(self);
574577
if (self->handle != SEM_FAILED)
@@ -706,7 +709,7 @@ _multiprocess_SemLock___exit___impl(SemLockObject *self,
706709
}
707710

708711
static int
709-
semlock_traverse(SemLockObject *s, visitproc visit, void *arg)
712+
semlock_traverse(PyObject *s, visitproc visit, void *arg)
710713
{
711714
Py_VISIT(Py_TYPE(s));
712715
return 0;

py3.12/README_MODS

+61
Original file line numberDiff line numberDiff line change
@@ -1896,3 +1896,64 @@ diff Python-3.12.5/Lib/test/_test_multiprocessing.py Python-3.12.8/Lib/test/_tes
18961896
> continue # class not intended for this start method.
18971897
6254a6457
18981898
> Temp.start_method = start_method
1899+
# ----------------------------------------------------------------------
1900+
diff Python-3.12.8/Modules/_multiprocessing/semaphore.c Python-3.12.9/Modules/_multiprocessing/semaphore.c
1901+
25a26,27
1902+
> #define _SemLockObject_CAST(op) ((SemLockObject *)(op))
1903+
>
1904+
570c572
1905+
< semlock_dealloc(SemLockObject* self)
1906+
---
1907+
> semlock_dealloc(PyObject *op)
1908+
571a574
1909+
> SemLockObject *self = _SemLockObject_CAST(op);
1910+
709c712
1911+
< semlock_traverse(SemLockObject *s, visitproc visit, void *arg)
1912+
---
1913+
> semlock_traverse(PyObject *s, visitproc visit, void *arg)
1914+
diff Python-3.12.8/Lib/multiprocessing/connection.py Python-3.12.9/Lib/multiprocessing/connection.py
1915+
849c849
1916+
< def _get_digest_name_and_payload(message: bytes) -> (str, bytes):
1917+
---
1918+
> def _get_digest_name_and_payload(message): # type: (bytes) -> tuple[str, bytes]
1919+
diff Python-3.12.8/Lib/multiprocessing/resource_tracker.py Python-3.12.9/Lib/multiprocessing/resource_tracker.py
1920+
144a145
1921+
> prev_sigmask = None
1922+
147c148
1923+
< signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
1924+
---
1925+
> prev_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
1926+
150,151c151,152
1927+
< if _HAVE_SIGMASK:
1928+
< signal.pthread_sigmask(signal.SIG_UNBLOCK, _IGNORED_SIGNALS)
1929+
---
1930+
> if prev_sigmask is not None:
1931+
> signal.pthread_sigmask(signal.SIG_SETMASK, prev_sigmask)
1932+
diff Python-3.12.8/Lib/multiprocessing/synchronize.py Python-3.12.9/Lib/multiprocessing/synchronize.py
1933+
363c363
1934+
< def __repr__(self) -> str:
1935+
---
1936+
> def __repr__(self):
1937+
diff Python-3.12.8/Lib/test/_test_multiprocessing.py Python-3.12.9/Lib/test/_test_multiprocessing.py
1938+
5828a5829,5849
1939+
> @unittest.skipUnless(hasattr(signal, "pthread_sigmask"), "pthread_sigmask is not available")
1940+
> def test_resource_tracker_blocked_signals(self):
1941+
> #
1942+
> # gh-127586: Check that resource_tracker does not override blocked signals of caller.
1943+
> #
1944+
> from multiprocessing.resource_tracker import ResourceTracker
1945+
> orig_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, set())
1946+
> signals = {signal.SIGTERM, signal.SIGINT, signal.SIGUSR1}
1947+
>
1948+
> try:
1949+
> for sig in signals:
1950+
> signal.pthread_sigmask(signal.SIG_SETMASK, {sig})
1951+
> self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
1952+
> tracker = ResourceTracker()
1953+
> tracker.ensure_running()
1954+
> self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
1955+
> tracker._stop()
1956+
> finally:
1957+
> # restore sigmask to what it was before executing test
1958+
> signal.pthread_sigmask(signal.SIG_SETMASK, orig_sigmask)
1959+
>

py3.12/multiprocess/connection.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ def PipeClient(address):
850850
_LEGACY_LENGTHS = (_MD5ONLY_MESSAGE_LENGTH, _MD5_DIGEST_LEN)
851851

852852

853-
def _get_digest_name_and_payload(message: bytes) -> (str, bytes):
853+
def _get_digest_name_and_payload(message): # type: (bytes) -> tuple[str, bytes]
854854
"""Returns a digest name and the payload for a response hash.
855855
856856
If a legacy protocol is detected based on the message length

py3.12/multiprocess/resource_tracker.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,15 @@ def ensure_running(self):
145145
# that can make the child die before it registers signal handlers
146146
# for SIGINT and SIGTERM. The mask is unregistered after spawning
147147
# the child.
148+
prev_sigmask = None
148149
try:
149150
if _HAVE_SIGMASK:
150-
signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
151+
prev_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
151152
pid = util.spawnv_passfds(exe, args, fds_to_pass)
152153
finally:
153-
if _HAVE_SIGMASK:
154-
signal.pthread_sigmask(signal.SIG_UNBLOCK, _IGNORED_SIGNALS)
154+
if prev_sigmask is not None:
155+
signal.pthread_sigmask(signal.SIG_SETMASK, prev_sigmask)
156+
155157
except:
156158
os.close(w)
157159
raise

py3.12/multiprocess/synchronize.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def wait(self, timeout=None):
366366
return True
367367
return False
368368

369-
def __repr__(self) -> str:
369+
def __repr__(self):
370370
set_status = 'set' if self.is_set() else 'unset'
371371
return f"<{type(self).__qualname__} at {id(self):#x} {set_status}>"
372372
#

py3.12/multiprocess/tests/__init__.py

+21
Original file line numberDiff line numberDiff line change
@@ -5838,6 +5838,27 @@ def test_too_long_name_resource(self):
58385838
resource_tracker.register(too_long_name_resource, rtype)
58395839

58405840

5841+
@unittest.skipUnless(hasattr(signal, "pthread_sigmask"), "pthread_sigmask is not available")
5842+
def test_resource_tracker_blocked_signals(self):
5843+
#
5844+
# gh-127586: Check that resource_tracker does not override blocked signals of caller.
5845+
#
5846+
from multiprocess.resource_tracker import ResourceTracker
5847+
orig_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, set())
5848+
signals = {signal.SIGTERM, signal.SIGINT, signal.SIGUSR1}
5849+
5850+
try:
5851+
for sig in signals:
5852+
signal.pthread_sigmask(signal.SIG_SETMASK, {sig})
5853+
self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
5854+
tracker = ResourceTracker()
5855+
tracker.ensure_running()
5856+
self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
5857+
tracker._stop()
5858+
finally:
5859+
# restore sigmask to what it was before executing test
5860+
signal.pthread_sigmask(signal.SIG_SETMASK, orig_sigmask)
5861+
58415862
class TestSimpleQueue(unittest.TestCase):
58425863

58435864
@classmethod

py3.13/Modules/_multiprocess/semaphore.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ typedef struct {
2727
char *name;
2828
} SemLockObject;
2929

30+
#define _SemLockObject_CAST(op) ((SemLockObject *)(op))
31+
3032
/*[python input]
3133
class SEM_HANDLE_converter(CConverter):
3234
type = "SEM_HANDLE"
@@ -575,8 +577,9 @@ _multiprocess_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle,
575577
}
576578

577579
static void
578-
semlock_dealloc(SemLockObject* self)
580+
semlock_dealloc(PyObject *op)
579581
{
582+
SemLockObject *self = _SemLockObject_CAST(op);
580583
PyTypeObject *tp = Py_TYPE(self);
581584
PyObject_GC_UnTrack(self);
582585
if (self->handle != SEM_FAILED)
@@ -717,7 +720,7 @@ _multiprocess_SemLock___exit___impl(SemLockObject *self,
717720
}
718721

719722
static int
720-
semlock_traverse(SemLockObject *s, visitproc visit, void *arg)
723+
semlock_traverse(PyObject *s, visitproc visit, void *arg)
721724
{
722725
Py_VISIT(Py_TYPE(s));
723726
return 0;

py3.13/README_MODS

+61
Original file line numberDiff line numberDiff line change
@@ -1709,3 +1709,64 @@ diff Python-3.13.0rc1/Lib/test/_test_multiprocessing.py Python-3.13.1/Lib/test/_
17091709
> continue # class not intended for this start method.
17101710
6419a6622
17111711
> Temp.start_method = start_method
1712+
# ----------------------------------------------------------------------
1713+
diff Python-3.13.1/Modules/_multiprocessing/semaphore.c Python-3.13.2/Modules/_multiprocessing/semaphore.c
1714+
29a30,31
1715+
> #define _SemLockObject_CAST(op) ((SemLockObject *)(op))
1716+
>
1717+
578c580
1718+
< semlock_dealloc(SemLockObject* self)
1719+
---
1720+
> semlock_dealloc(PyObject *op)
1721+
579a582
1722+
> SemLockObject *self = _SemLockObject_CAST(op);
1723+
720c723
1724+
< semlock_traverse(SemLockObject *s, visitproc visit, void *arg)
1725+
---
1726+
> semlock_traverse(PyObject *s, visitproc visit, void *arg)
1727+
diff Python-3.13.1/Lib/multiprocessing/connection.py Python-3.13.2/Lib/multiprocessing/connection.py
1728+
849c849
1729+
< def _get_digest_name_and_payload(message: bytes) -> (str, bytes):
1730+
---
1731+
> def _get_digest_name_and_payload(message): # type: (bytes) -> tuple[str, bytes]
1732+
diff Python-3.13.1/Lib/multiprocessing/resource_tracker.py Python-3.13.2/Lib/multiprocessing/resource_tracker.py
1733+
157a158
1734+
> prev_sigmask = None
1735+
160c161
1736+
< signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
1737+
---
1738+
> prev_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
1739+
163,164c164,165
1740+
< if _HAVE_SIGMASK:
1741+
< signal.pthread_sigmask(signal.SIG_UNBLOCK, _IGNORED_SIGNALS)
1742+
---
1743+
> if prev_sigmask is not None:
1744+
> signal.pthread_sigmask(signal.SIG_SETMASK, prev_sigmask)
1745+
diff Python-3.13.1/Lib/multiprocessing/synchronize.py Python-3.13.2/Lib/multiprocessing/synchronize.py
1746+
363c363
1747+
< def __repr__(self) -> str:
1748+
---
1749+
> def __repr__(self):
1750+
diff Python-3.13.1/Lib/test/_test_multiprocessing.py Python-3.13.2/Lib/test/_test_multiprocessing.py
1751+
5952a5953,5973
1752+
> @unittest.skipUnless(hasattr(signal, "pthread_sigmask"), "pthread_sigmask is not available")
1753+
> def test_resource_tracker_blocked_signals(self):
1754+
> #
1755+
> # gh-127586: Check that resource_tracker does not override blocked signals of caller.
1756+
> #
1757+
> from multiprocessing.resource_tracker import ResourceTracker
1758+
> orig_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, set())
1759+
> signals = {signal.SIGTERM, signal.SIGINT, signal.SIGUSR1}
1760+
>
1761+
> try:
1762+
> for sig in signals:
1763+
> signal.pthread_sigmask(signal.SIG_SETMASK, {sig})
1764+
> self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
1765+
> tracker = ResourceTracker()
1766+
> tracker.ensure_running()
1767+
> self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
1768+
> tracker._stop()
1769+
> finally:
1770+
> # restore sigmask to what it was before executing test
1771+
> signal.pthread_sigmask(signal.SIG_SETMASK, orig_sigmask)
1772+
>

py3.13/multiprocess/connection.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ def PipeClient(address):
850850
_LEGACY_LENGTHS = (_MD5ONLY_MESSAGE_LENGTH, _MD5_DIGEST_LEN)
851851

852852

853-
def _get_digest_name_and_payload(message: bytes) -> (str, bytes):
853+
def _get_digest_name_and_payload(message): # type: (bytes) -> tuple[str, bytes]
854854
"""Returns a digest name and the payload for a response hash.
855855
856856
If a legacy protocol is detected based on the message length

py3.13/multiprocess/resource_tracker.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,14 @@ def ensure_running(self):
158158
# that can make the child die before it registers signal handlers
159159
# for SIGINT and SIGTERM. The mask is unregistered after spawning
160160
# the child.
161+
prev_sigmask = None
161162
try:
162163
if _HAVE_SIGMASK:
163-
signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
164+
prev_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS)
164165
pid = util.spawnv_passfds(exe, args, fds_to_pass)
165166
finally:
166-
if _HAVE_SIGMASK:
167-
signal.pthread_sigmask(signal.SIG_UNBLOCK, _IGNORED_SIGNALS)
167+
if prev_sigmask is not None:
168+
signal.pthread_sigmask(signal.SIG_SETMASK, prev_sigmask)
168169
except:
169170
os.close(w)
170171
raise

py3.13/multiprocess/synchronize.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def wait(self, timeout=None):
366366
return True
367367
return False
368368

369-
def __repr__(self) -> str:
369+
def __repr__(self):
370370
set_status = 'set' if self.is_set() else 'unset'
371371
return f"<{type(self).__qualname__} at {id(self):#x} {set_status}>"
372372
#

py3.13/multiprocess/tests/__init__.py

+21
Original file line numberDiff line numberDiff line change
@@ -5962,6 +5962,27 @@ def test_resource_tracker_exit_code(self):
59625962
cleanup=cleanup,
59635963
)
59645964

5965+
@unittest.skipUnless(hasattr(signal, "pthread_sigmask"), "pthread_sigmask is not available")
5966+
def test_resource_tracker_blocked_signals(self):
5967+
#
5968+
# gh-127586: Check that resource_tracker does not override blocked signals of caller.
5969+
#
5970+
from multiprocess.resource_tracker import ResourceTracker
5971+
orig_sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, set())
5972+
signals = {signal.SIGTERM, signal.SIGINT, signal.SIGUSR1}
5973+
5974+
try:
5975+
for sig in signals:
5976+
signal.pthread_sigmask(signal.SIG_SETMASK, {sig})
5977+
self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
5978+
tracker = ResourceTracker()
5979+
tracker.ensure_running()
5980+
self.assertEqual(signal.pthread_sigmask(signal.SIG_BLOCK, set()), {sig})
5981+
tracker._stop()
5982+
finally:
5983+
# restore sigmask to what it was before executing test
5984+
signal.pthread_sigmask(signal.SIG_SETMASK, orig_sigmask)
5985+
59655986
class TestSimpleQueue(unittest.TestCase):
59665987

59675988
@classmethod

0 commit comments

Comments
 (0)