Skip to content

Commit 60702f3

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Sync pre-release CPython main branch from GitHub (2026-06-13)
Summary: Imported python/cpython `3.16.0a0` from upstream rev [`6ce088e`](https://www.github.com/python/cpython/commit/6ce088e20a13ac25320d94c5775bb1a4edc75ba4) (committed 2026-06-13 23:10:56+00:00). # Commit Info - Base: (`3.16.0a0`) - [`f4f1020`](https://www.github.com/python/cpython/commit/f4f102027a9b0edc72a048f17b696aa92d2e6893) (commit date: 2026-06-12 16:02:33+00:00) - Imported: (`3.16.0a0`) - [`6ce088e`](https://www.github.com/python/cpython/commit/6ce088e20a13ac25320d94c5775bb1a4edc75ba4) (commit date: 2026-06-13 23:10:56+00:00) # Noteworthy file changes - Low-signal files (3 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GLz10CGUHEycsYcEAEL3X518xt8Sbr0LAAAz Differential Revision: D108538185 fbshipit-source-id: faafbff06a5815fdedf5187b94c8bd32f9405adb
1 parent 6e3aa88 commit 60702f3

11 files changed

Lines changed: 74 additions & 16 deletions

File tree

Doc/library/enum.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ Data types
629629
>>> white in purple
630630
False
631631

632-
.. method:: __iter__(self):
632+
.. method:: __iter__(self)
633633

634634
Returns all contained non-alias members::
635635

@@ -640,7 +640,7 @@ Data types
640640

641641
.. versionadded:: 3.11
642642

643-
.. method:: __len__(self):
643+
.. method:: __len__(self)
644644

645645
Returns number of members in flag::
646646

@@ -651,7 +651,7 @@ Data types
651651

652652
.. versionadded:: 3.11
653653

654-
.. method:: __bool__(self):
654+
.. method:: __bool__(self)
655655

656656
Returns *True* if any members in flag, *False* otherwise::
657657

@@ -688,7 +688,7 @@ Data types
688688
>>> purple ^ Color.GREEN
689689
<Color.RED|GREEN|BLUE: 7>
690690

691-
.. method:: __invert__(self):
691+
.. method:: __invert__(self)
692692

693693
Returns all the flags in *type(self)* that are not in *self*::
694694

Doc/library/unittest.mock.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2539,7 +2539,7 @@ Alternatively you can just use ``vars(my_mock)`` (instance members) and
25392539
mock_open
25402540
~~~~~~~~~
25412541

2542-
.. function:: mock_open(mock=None, read_data=None)
2542+
.. function:: mock_open(mock=None, read_data='')
25432543

25442544
A helper function to create a mock to replace the use of :func:`open`. It works
25452545
for :func:`open` called directly or used as a context manager.

Lib/base64.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Base16, Base32, Base64 (RFC 3548), Base85 and Ascii85 data encodings"""
1+
"""Base16, Base32, Base64 (RFC 4648), Base85 and Ascii85 data encodings"""
22

33
# Modified 04-Oct-1995 by Jack Jansen to use binascii module
44
# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support
@@ -219,7 +219,7 @@ def urlsafe_b64decode(s, *, padded=False):
219219
characters present in the input.
220220
'''
221221
_B32_DECODE_MAP01_DOCSTRING = '''
222-
RFC 3548 allows for optional mapping of the digit 0 (zero) to the
222+
RFC 4648 allows for optional mapping of the digit 0 (zero) to the
223223
letter O (oh), and for optional mapping of the digit 1 (one) to
224224
either the letter I (eye) or letter L (el). The optional argument
225225
map01 when not None, specifies which letter the digit 1 should be
@@ -266,7 +266,7 @@ def b32hexdecode(s, casefold=False, *, padded=True, ignorechars=b'',
266266
extra_args='')
267267

268268

269-
# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
269+
# RFC 4648, Base 16 Alphabet specifies uppercase, but hexlify() returns
270270
# lowercase. The RFC also recommends against accepting input case
271271
# insensitively.
272272
def b16encode(s, *, wrapcol=0):

Lib/concurrent/futures/process.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -469,11 +469,9 @@ def _terminate_broken(self, cause):
469469
executor._shutdown_thread = True
470470
executor = None
471471

472-
# All pending tasks are to be marked failed with the following
473-
# BrokenProcessPool error
474-
bpe = BrokenProcessPool("A process in the process pool was "
475-
"terminated abruptly while the future was "
476-
"running or pending.")
472+
# All pending tasks are to be marked failed with a
473+
# BrokenProcessPool error, as separate instances to avoid sharing
474+
# a traceback (gh-101267).
477475
cause_str = None
478476
if cause is not None:
479477
cause_str = ''.join(cause)
@@ -489,11 +487,15 @@ def _terminate_broken(self, cause):
489487
f"with exit code {p.exitcode}")
490488
if errors:
491489
cause_str = "\n".join(errors)
492-
if cause_str:
493-
bpe.__cause__ = _RemoteTraceback(f"\n'''\n{cause_str}'''")
490+
cause_tb = f"\n'''\n{cause_str}'''" if cause_str else None
494491

495492
# Mark pending tasks as failed.
496493
for work_id, work_item in self.pending_work_items.items():
494+
bpe = BrokenProcessPool("A process in the process pool was "
495+
"terminated abruptly while the future was "
496+
"running or pending.")
497+
if cause_tb is not None:
498+
bpe.__cause__ = _RemoteTraceback(cause_tb)
497499
try:
498500
work_item.future.set_exception(bpe)
499501
except _base.InvalidStateError:

Lib/test/test_concurrent_futures/test_process_pool.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import sys
44
import threading
55
import time
6+
import traceback
67
import unittest
78
import unittest.mock
89
from concurrent import futures
@@ -62,6 +63,32 @@ def test_killed_child(self):
6263
# Submitting other jobs fails as well.
6364
self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8)
6465

66+
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
67+
def test_broken_process_pool_traceback(self):
68+
# When a child process is abruptly terminated, the whole pool gets
69+
# "broken", and a BrokenProcessPool exception should be created
70+
# for each future instead of sharing one exception among all futures.
71+
event = self.create_event()
72+
futures = [self.executor.submit(event.wait) for _ in range(3)]
73+
p = next(iter(self.executor._processes.values()))
74+
p.terminate()
75+
for fut in futures:
76+
# Don't use assertRaises(): it clears the traceback off exc.
77+
try:
78+
fut.result()
79+
except BrokenProcessPool as exc:
80+
tb = exc.__traceback__
81+
else:
82+
self.fail("BrokenProcessPool not raised")
83+
count = sum(
84+
1
85+
for frame_summary in traceback.extract_tb(tb)
86+
if frame_summary.filename == __file__
87+
)
88+
# This code file should appear exactly once in the traceback.
89+
# A shared exception would accumulate a frame per result() call.
90+
self.assertEqual(count, 1)
91+
6592
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
6693
def test_map_chunksize(self):
6794
def bad_map():

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,7 @@ Charlie Shepherd
17631763
Bruce Sherwood
17641764
Gregory Shevchenko
17651765
Hai Shi
1766+
Daniel Shields
17661767
Alexander Shigin
17671768
Pete Shinners
17681769
Michael Shiplett
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
When a worker process terminates unexpectedly,
2+
:class:`concurrent.futures.ProcessPoolExecutor` now sets a separate
3+
:exc:`~concurrent.futures.process.BrokenProcessPool` exception on each pending
4+
future instead of sharing a single instance among them all. Sharing one
5+
exception produced malformed tracebacks: each
6+
:meth:`Future.result() <concurrent.futures.Future.result>` call re-raised the
7+
same object, appending another copy of the traceback to it.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed a crash in :class:`subprocess.Popen` (and ``_posixsubprocess.fork_exec``)
2+
when an ``argv`` item's :meth:`~os.PathLike.__fspath__` concurrently mutates the
3+
``args`` sequence being converted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix impossible stack traces (callers and callees cross called, orphans and
2+
incorrect lines) in the Tachyon profiler when caching frames, by snapshotting
3+
the stack chunks before walking the frame chain on a cache miss. Patch by
4+
Maurycy Pawłowski-Wieroński.

Modules/_posixsubprocess.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,8 +1090,14 @@ subprocess_fork_exec_impl(PyObject *module, PyObject *process_args,
10901090
goto cleanup;
10911091
}
10921092
borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
1093-
if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
1093+
/* borrowed_arg is only borrowed; its __fspath__() may run Python
1094+
that drops fast_args' last reference to it. */
1095+
Py_INCREF(borrowed_arg);
1096+
if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) {
1097+
Py_DECREF(borrowed_arg);
10941098
goto cleanup;
1099+
}
1100+
Py_DECREF(borrowed_arg);
10951101
PyTuple_SET_ITEM(converted_args, arg_num, converted_arg);
10961102
}
10971103

0 commit comments

Comments
 (0)