Skip to content

Commit 3416e57

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Sync pre-release CPython 3.15 branch from GitHub (2026-08-26)
Summary: Imported python/cpython `3.15.0rc1+dev` from upstream rev [`1c826a4`](https://www.github.com/python/cpython/commit/1c826a40a2f9606e284fd3d6d5f7c7c6732327ed) (committed 2026-08-26 00:59:49+00:00). # Commit Info - Base: (`3.15.0rc1+dev`) - [`c32b891`](https://www.github.com/python/cpython/commit/c32b891de6421e7943eec441144f14986af07507) (commit date: 2026-08-25 00:39:52+00:00) - Imported: (`3.15.0rc1+dev`) - [`1c826a4`](https://www.github.com/python/cpython/commit/1c826a40a2f9606e284fd3d6d5f7c7c6732327ed) (commit date: 2026-08-26 00:59:49+00:00) # Noteworthy file changes - Low-signal files (2 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GD2foS7Vl3rB6xoIAPXuY5YEhq4Dbr0LAAAz Reviewed By: itamaro Differential Revision: D117473160 fbshipit-source-id: 84aaf4643c242744e7a5b9772cc796fc89da7327
1 parent 2a36ac2 commit 3416e57

16 files changed

Lines changed: 193 additions & 45 deletions

File tree

.github/workflows/build.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,13 @@ jobs:
332332
# unsupported as it most resembles other 1.1.1-work-a-like ssl APIs
333333
# supported by important vendors such as AWS-LC.
334334
- { name: openssl, version: 1.1.1w }
335-
- { name: openssl, version: 3.0.21 }
336-
- { name: openssl, version: 3.4.6 }
337-
- { name: openssl, version: 3.5.7 }
338-
- { name: openssl, version: 3.6.3 }
339-
- { name: openssl, version: 4.0.1 }
335+
- { name: openssl, version: 3.0.22 }
336+
- { name: openssl, version: 3.4.7 }
337+
- { name: openssl, version: 3.5.8 }
338+
- { name: openssl, version: 3.6.4 }
339+
- { name: openssl, version: 4.0.2 }
340340
## AWS-LC
341-
- { name: aws-lc, version: 5.0.0 }
341+
- { name: aws-lc, version: 5.5.0 }
342342
env:
343343
SSLLIB_VER: ${{ matrix.ssllib.version }}
344344
MULTISSL_DIR: ${{ github.workspace }}/multissl
@@ -443,7 +443,7 @@ jobs:
443443
needs: build-context
444444
if: needs.build-context.outputs.run-ubuntu == 'true'
445445
env:
446-
OPENSSL_VER: 3.5.7
446+
OPENSSL_VER: 3.5.8
447447
PYTHONSTRICTEXTENSIONBUILD: 1
448448
steps:
449449
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -551,7 +551,7 @@ jobs:
551551
matrix:
552552
os: [ubuntu-26.04]
553553
env:
554-
OPENSSL_VER: 3.5.7
554+
OPENSSL_VER: 3.5.8
555555
PYTHONSTRICTEXTENSIONBUILD: 1
556556
ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
557557
steps:

.github/workflows/reusable-san.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ permissions:
1717

1818
env:
1919
FORCE_COLOR: 1
20-
OPENSSL_VER: 3.5.7
20+
OPENSSL_VER: 3.5.8
2121

2222
jobs:
2323
build-san-reusable:

.github/workflows/reusable-ubuntu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
runs-on: ${{ inputs.os }}
3636
timeout-minutes: 60
3737
env:
38-
OPENSSL_VER: 3.5.7
38+
OPENSSL_VER: 3.5.8
3939
PYTHONSTRICTEXTENSIONBUILD: 1
4040
TERM: linux
4141
steps:

Doc/library/csv.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ The :mod:`!csv` module defines the following constants:
369369
Instructs :class:`writer` objects to only quote those fields which contain
370370
special characters such as *delimiter*, *quotechar*, ``'\r'``, ``'\n'``
371371
or any of the characters in *lineterminator*.
372+
If *doublequote* is :const:`False` and *escapechar* is set,
373+
the *quotechar* is escaped instead of causing the field to be quoted.
372374

373375

374376
.. data:: QUOTE_NONNUMERIC

Doc/library/stdtypes.rst

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2594,7 +2594,8 @@ expression support in the :mod:`re` module).
25942594

25952595
Return a list of the words in the string, using *sep* as the delimiter string.
25962596
If *maxsplit* is given, at most *maxsplit* splits are done, the *rightmost*
2597-
ones. If *sep* is not specified or ``None``, any whitespace string is a
2597+
ones. If *sep* is not specified or ``None``, any
2598+
:meth:`whitespace <str.isspace>` string is a
25982599
separator. Except for splitting from the right, :meth:`rsplit` behaves like
25992600
:meth:`split` which is described in detail below.
26002601

@@ -2654,7 +2655,8 @@ expression support in the :mod:`re` module).
26542655
['1', '2', '3<4']
26552656

26562657
If *sep* is not specified or is ``None``, a different splitting algorithm is
2657-
applied: runs of consecutive whitespace are regarded as a single separator,
2658+
applied: runs of consecutive :meth:`whitespace <str.isspace>` are regarded
2659+
as a single separator,
26582660
and the result will contain no empty strings at the start or end if the
26592661
string has leading or trailing whitespace. Consequently, splitting an empty
26602662
string or a string consisting of just whitespace with a ``None`` separator
@@ -3920,7 +3922,8 @@ produce new objects.
39203922
Return a copy of the sequence with specified leading bytes removed. The
39213923
*bytes* argument is a binary sequence specifying the set of byte values to
39223924
be removed. If omitted or ``None``, the *bytes* argument defaults
3923-
to removing ASCII whitespace. The *bytes* argument is not a prefix;
3925+
to removing :meth:`ASCII whitespace <bytes.isspace>`.
3926+
The *bytes* argument is not a prefix;
39243927
rather, all combinations of its values are stripped::
39253928

39263929
>>> b' spacious '.lstrip()
@@ -3964,7 +3967,8 @@ produce new objects.
39643967
Split the binary sequence into subsequences of the same type, using *sep*
39653968
as the delimiter string. If *maxsplit* is given, at most *maxsplit* splits
39663969
are done, the *rightmost* ones. If *sep* is not specified or ``None``,
3967-
any subsequence consisting solely of ASCII whitespace is a separator.
3970+
any subsequence consisting solely of
3971+
:meth:`ASCII whitespace <bytes.isspace>` is a separator.
39683972
Except for splitting from the right, :meth:`rsplit` behaves like
39693973
:meth:`split` which is described in detail below.
39703974

@@ -3975,7 +3979,8 @@ produce new objects.
39753979
Return a copy of the sequence with specified trailing bytes removed. The
39763980
*bytes* argument is a binary sequence specifying the set of byte values to
39773981
be removed. If omitted or ``None``, the *bytes* argument defaults to
3978-
removing ASCII whitespace. The *bytes* argument is not a suffix; rather,
3982+
removing :meth:`ASCII whitespace <bytes.isspace>`.
3983+
The *bytes* argument is not a suffix; rather,
39793984
all combinations of its values are stripped::
39803985

39813986
>>> b' spacious '.rstrip()
@@ -4028,7 +4033,8 @@ produce new objects.
40284033
[b'1', b'2', b'3<4']
40294034

40304035
If *sep* is not specified or is ``None``, a different splitting algorithm
4031-
is applied: runs of consecutive ASCII whitespace are regarded as a single
4036+
is applied: runs of consecutive :meth:`ASCII whitespace <bytes.isspace>`
4037+
are regarded as a single
40324038
separator, and the result will contain no empty strings at the start or
40334039
end if the sequence has leading or trailing whitespace. Consequently,
40344040
splitting an empty sequence or a sequence consisting solely of ASCII
@@ -4051,7 +4057,8 @@ produce new objects.
40514057
Return a copy of the sequence with specified leading and trailing bytes
40524058
removed. The *bytes* argument is a binary sequence specifying the set of
40534059
byte values to be removed. If omitted or ``None``, the *bytes*
4054-
argument defaults to removing ASCII whitespace. The *bytes* argument is
4060+
argument defaults to removing :meth:`ASCII whitespace <bytes.isspace>`.
4061+
The *bytes* argument is
40554062
not a prefix or suffix; rather, all combinations of its values are
40564063
stripped::
40574064

Doc/whatsnew/3.15.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,7 @@ base64
10011001

10021002
* Added the *canonical* parameter in
10031003
:func:`~base64.b32decode`, :func:`~base64.b32hexdecode`,
1004-
:func:`~base64.b64decode`, :func:`~base64.urlsafe_b64decode`,
1004+
:func:`~base64.b64decode`,
10051005
:func:`~base64.a85decode`, :func:`~base64.b85decode`, and
10061006
:func:`~base64.z85decode`,
10071007
to reject encodings with non-zero padding bits or other non-canonical

Lib/profiling/sampling/_flamegraph_assets/flamegraph.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,8 +955,8 @@ function populateProfileSummary(data) {
955955
: (stats.total_samples ?? data.value ?? 0);
956956
const duration = stats.duration_sec || 0;
957957
const sampleRate = stats.sample_rate || (duration > 0 ? totalSamples / duration : 0);
958-
const errorRate = stats.error_rate || 0;
959-
const missedSamples= stats.missed_samples || 0;
958+
const errorRate = stats.error_rate;
959+
const missedSamples = stats.missed_samples;
960960

961961
const samplesEl = document.getElementById('stat-total-samples');
962962
if (samplesEl) samplesEl.textContent = formatNumber(totalSamples);

Lib/profiling/sampling/stack_collector.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def _get_module_name(self, filename, path_info):
212212
self._module_cache[filename] = module_name
213213
return module_name
214214

215-
def _convert_to_flamegraph_format(self):
215+
def _convert_to_flamegraph_format(self, *, min_samples=None):
216216
if self._total_samples == 0:
217217
return {
218218
"name": self._string_table.intern("No Data"),
@@ -302,7 +302,8 @@ def convert_children(children, min_samples, path_info):
302302

303303
# Filter out very small functions (less than 0.1% of total samples)
304304
total_samples = self._total_samples
305-
min_samples = max(1, int(total_samples * 0.001))
305+
if min_samples is None:
306+
min_samples = max(1, int(total_samples * 0.001))
306307
path_info = get_python_path_info()
307308

308309
root_children = convert_children(self._root["children"], min_samples, path_info)
@@ -690,7 +691,15 @@ def _add_elided_flamegraph(self, current_flamegraph, current_stats, baseline_sta
690691
"""Calculate elided paths and add elided flamegraph to stats."""
691692
self._elided_paths = baseline_stats.keys() - current_stats.keys()
692693

693-
current_flamegraph["stats"]["elided_count"] = len(self._elided_paths)
694+
# A sampled stack can end at an internal path that also has elided
695+
# descendants. Count every disappeared path with self samples, not
696+
# just the leaves of the elided path tree.
697+
elided_stacks = {
698+
path
699+
for path in self._elided_paths
700+
if baseline_stats[path]["self"] > 0
701+
}
702+
current_flamegraph["stats"]["elided_count"] = len(elided_stacks)
694703

695704
if self._elided_paths:
696705
elided_flamegraph = self._build_elided_flamegraph(baseline_stats, scale)
@@ -713,7 +722,9 @@ def _build_elided_flamegraph(self, baseline_stats, scale):
713722
orig_get_source = self._baseline_collector._get_source_lines
714723
self._baseline_collector._get_source_lines = lambda func: None
715724
try:
716-
baseline_data = self._baseline_collector._convert_to_flamegraph_format()
725+
baseline_data = self._baseline_collector._convert_to_flamegraph_format(
726+
min_samples=1
727+
)
717728
finally:
718729
self._baseline_collector._get_source_lines = orig_get_source
719730

Lib/test/test_profiling/test_sampling_profiler/test_collectors.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@ def test_diff_flamegraph_elided_stacks(self):
16651665

16661666
data = diff._convert_to_flamegraph_format()
16671667

1668-
self.assertGreater(data["stats"]["elided_count"], 0)
1668+
self.assertEqual(data["stats"]["elided_count"], 1)
16691669
self.assertIn("elided_flamegraph", data["stats"])
16701670
elided = data["stats"]["elided_flamegraph"]
16711671
self.assertTrue(elided["stats"]["is_differential"])
@@ -1681,6 +1681,74 @@ def test_diff_flamegraph_elided_stacks(self):
16811681
self.assertGreater(child["baseline"], 0)
16821682
self.assertAlmostEqual(child["diff"], -child["baseline"])
16831683

1684+
def test_diff_flamegraph_counts_elided_stacks_not_paths(self):
1685+
"""Internal and leaf stack endings are counted separately."""
1686+
internal_stack = [
1687+
MockInterpreterInfo(0, [
1688+
MockThreadInfo(1, [
1689+
MockFrameInfo("file.py", 20, "old_mid"),
1690+
MockFrameInfo("file.py", 10, "root"),
1691+
])
1692+
])
1693+
]
1694+
leaf_stack = [
1695+
MockInterpreterInfo(0, [
1696+
MockThreadInfo(1, [
1697+
MockFrameInfo("file.py", 30, "old_leaf"),
1698+
MockFrameInfo("file.py", 20, "old_mid"),
1699+
MockFrameInfo("file.py", 10, "root"),
1700+
])
1701+
])
1702+
]
1703+
current_frames = [
1704+
MockInterpreterInfo(0, [
1705+
MockThreadInfo(1, [MockFrameInfo("file.py", 10, "root")])
1706+
])
1707+
]
1708+
1709+
diff = make_diff_collector_with_mock_baseline(
1710+
[internal_stack, leaf_stack]
1711+
)
1712+
diff.collect(current_frames)
1713+
1714+
data = diff._convert_to_flamegraph_format()
1715+
self.assertEqual(data["stats"]["elided_count"], 2)
1716+
1717+
def test_diff_flamegraph_renders_small_elided_stack(self):
1718+
"""Elided stacks are not removed by the significance filter."""
1719+
common_frames = [
1720+
MockInterpreterInfo(0, [
1721+
MockThreadInfo(1, [
1722+
MockFrameInfo("file.py", 20, "common"),
1723+
MockFrameInfo("file.py", 10, "root"),
1724+
])
1725+
])
1726+
]
1727+
old_frames = [
1728+
MockInterpreterInfo(0, [
1729+
MockThreadInfo(1, [
1730+
MockFrameInfo("file.py", 30, "old_tiny"),
1731+
MockFrameInfo("file.py", 10, "root"),
1732+
])
1733+
])
1734+
]
1735+
1736+
diff = make_diff_collector_with_mock_baseline(
1737+
[common_frames] * 1999 + [old_frames]
1738+
)
1739+
for _ in range(1999):
1740+
diff.collect(common_frames)
1741+
1742+
data = diff._convert_to_flamegraph_format()
1743+
self.assertEqual(data["stats"]["elided_count"], 1)
1744+
self.assertIn("elided_flamegraph", data["stats"])
1745+
1746+
elided = data["stats"]["elided_flamegraph"]
1747+
strings = elided["strings"]
1748+
self.assertIsNotNone(
1749+
find_child_by_name(elided.get("children", []), strings, "old_tiny")
1750+
)
1751+
16841752
def test_diff_flamegraph_elided_top_level_root(self):
16851753
"""Elided top-level roots do not crash metadata generation."""
16861754
baseline_frames_1 = [

Misc/NEWS.d/3.15.0b1.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,10 +1081,10 @@ Deprecate :meth:`http.cookies.Morsel.js_output` and
10811081
.. nonce: iHWO0v
10821082
.. section: Library
10831083
1084-
Add a *canonical* keyword-only parameter to the base16, base32, base64,
1085-
base85, ascii85, and Z85 decoders in :mod:`base64` and :mod:`binascii`. When
1086-
true, encodings with non-zero padding bits (base16/32/64) or non-canonical
1087-
encodings (base85/ascii85) are rejected. Single-character final groups in
1084+
Add a *canonical* keyword-only parameter to the base32, base64, base85,
1085+
ascii85, and Z85 decoders in :mod:`base64` and :mod:`binascii`. When true,
1086+
encodings with non-zero padding bits (base32/64) or non-canonical encodings
1087+
(base85/ascii85) are rejected. Single-character final groups in
10881088
:func:`binascii.a2b_ascii85` and :func:`binascii.a2b_base85` are now always
10891089
rejected as encoding violations, regardless of *canonical*; previously they
10901090
were silently ignored and produced no output bytes.

0 commit comments

Comments
 (0)