Skip to content

Commit 9d95d41

Browse files
authored
Merge branch 'main' into mac-info-plist-fix
2 parents 75db633 + a273bc9 commit 9d95d41

File tree

63 files changed

+7293
-894
lines changed

Some content is hidden

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

63 files changed

+7293
-894
lines changed

.github/workflows/tail-call.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,17 @@ jobs:
7979
with:
8080
python-version: '3.11'
8181

82-
- name: Native Windows (debug)
82+
- name: Native Windows MSVC (release)
8383
if: runner.os == 'Windows' && matrix.architecture != 'ARM64'
8484
shell: cmd
8585
run: |
86-
choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}.1.0
87-
set PlatformToolset=clangcl
88-
set LLVMToolsVersion=${{ matrix.llvm }}.1.0
89-
set LLVMInstallDir=C:\Program Files\LLVM
90-
call ./PCbuild/build.bat --tail-call-interp -d -p ${{ matrix.architecture }}
91-
call ./PCbuild/rt.bat -d -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
86+
choco install visualstudio2026buildtools --no-progress -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive"
87+
$env:PATH = "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;$env:PATH"
88+
./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} "/p:PlatformToolset=v145"
89+
./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3
9290
9391
# No tests (yet):
94-
- name: Emulated Windows (release)
92+
- name: Emulated Windows Clang (release)
9593
if: runner.os == 'Windows' && matrix.architecture == 'ARM64'
9694
shell: cmd
9795
run: |

Doc/library/profiling.sampling.rst

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,36 @@ On most systems, attaching to another process requires appropriate permissions.
200200
See :ref:`profiling-permissions` for platform-specific requirements.
201201

202202

203+
.. _replay-command:
204+
205+
The ``replay`` command
206+
----------------------
207+
208+
The ``replay`` command converts binary profile files to other output formats::
209+
210+
python -m profiling.sampling replay profile.bin
211+
python -m profiling.sampling replay --flamegraph -o profile.html profile.bin
212+
213+
This command is useful when you have captured profiling data in binary format
214+
and want to analyze it later or convert it to a visualization format. Binary
215+
profiles can be replayed multiple times to different formats without
216+
re-profiling.
217+
218+
::
219+
220+
# Convert binary to pstats (default, prints to stdout)
221+
python -m profiling.sampling replay profile.bin
222+
223+
# Convert binary to flame graph
224+
python -m profiling.sampling replay --flamegraph -o output.html profile.bin
225+
226+
# Convert binary to gecko format for Firefox Profiler
227+
python -m profiling.sampling replay --gecko -o profile.json profile.bin
228+
229+
# Convert binary to heatmap
230+
python -m profiling.sampling replay --heatmap -o my_heatmap profile.bin
231+
232+
203233
Profiling in production
204234
-----------------------
205235

@@ -1041,6 +1071,59 @@ intuitive view that shows exactly where time is spent without requiring
10411071
interpretation of hierarchical visualizations.
10421072

10431073

1074+
Binary format
1075+
-------------
1076+
1077+
Binary format (:option:`--binary`) produces a compact binary file for efficient
1078+
storage of profiling data::
1079+
1080+
python -m profiling.sampling run --binary -o profile.bin script.py
1081+
python -m profiling.sampling attach --binary -o profile.bin 12345
1082+
1083+
The :option:`--compression` option controls data compression:
1084+
1085+
- ``auto`` (default): Use zstd compression if available, otherwise no
1086+
compression
1087+
- ``zstd``: Force zstd compression (requires :mod:`compression.zstd` support)
1088+
- ``none``: Disable compression
1089+
1090+
::
1091+
1092+
python -m profiling.sampling run --binary --compression=zstd -o profile.bin script.py
1093+
1094+
To analyze binary profiles, use the :ref:`replay-command` to convert them to
1095+
other formats like flame graphs or pstats output.
1096+
1097+
1098+
Record and replay workflow
1099+
==========================
1100+
1101+
The binary format combined with the replay command enables a record-and-replay
1102+
workflow that separates data capture from analysis. Rather than generating
1103+
visualizations during profiling, you capture raw data to a compact binary file
1104+
and convert it to different formats later.
1105+
1106+
This approach has three main benefits:
1107+
1108+
- Sampling runs faster because the work of building data structures for
1109+
visualization is deferred until replay.
1110+
- A single binary capture can be converted to multiple output formats
1111+
without re-profiling: pstats for a quick overview, flame graph for visual
1112+
exploration, heatmap for line-level detail.
1113+
- Binary files are compact and easy to share with colleagues who can convert
1114+
them to their preferred format.
1115+
1116+
A typical workflow::
1117+
1118+
# Capture profile in production or during tests
1119+
python -m profiling.sampling attach --binary -o profile.bin 12345
1120+
1121+
# Later, analyze with different formats
1122+
python -m profiling.sampling replay profile.bin
1123+
python -m profiling.sampling replay --flamegraph -o profile.html profile.bin
1124+
python -m profiling.sampling replay --heatmap -o heatmap profile.bin
1125+
1126+
10441127
Live mode
10451128
=========
10461129

@@ -1252,6 +1335,10 @@ Global options
12521335

12531336
Attach to and profile a running process by PID.
12541337

1338+
.. option:: replay
1339+
1340+
Convert a binary profile file to another output format.
1341+
12551342

12561343
Sampling options
12571344
----------------
@@ -1335,12 +1422,22 @@ Output options
13351422

13361423
Generate HTML heatmap with line-level sample counts.
13371424

1425+
.. option:: --binary
1426+
1427+
Generate high-performance binary format for later conversion with the
1428+
``replay`` command.
1429+
1430+
.. option:: --compression <type>
1431+
1432+
Compression for binary format: ``auto`` (use zstd if available, default),
1433+
``zstd``, or ``none``.
1434+
13381435
.. option:: -o <path>, --output <path>
13391436

13401437
Output file or directory path. Default behavior varies by format:
1341-
``--pstats`` writes to stdout, ``--flamegraph`` and ``--gecko`` generate
1342-
files like ``flamegraph.PID.html``, and ``--heatmap`` creates a directory
1343-
named ``heatmap_PID``.
1438+
:option:`--pstats` writes to stdout, while other formats generate a file
1439+
named ``<format>_<PID>.<ext>`` (for example, ``flamegraph_12345.html``).
1440+
:option:`--heatmap` creates a directory named ``heatmap_<PID>``.
13441441

13451442

13461443
pstats display options

Doc/library/stdtypes.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ Any object can be tested for truth value, for use in an :keyword:`if` or
4646
By default, an object is considered true unless its class defines either a
4747
:meth:`~object.__bool__` method that returns ``False`` or a
4848
:meth:`~object.__len__` method that
49-
returns zero, when called with the object. [1]_ Here are most of the built-in
50-
objects considered false:
49+
returns zero, when called with the object. [1]_ If one of the methods raises an
50+
exception when called, the exception is propagated and the object does
51+
not have a truth value (for example, :data:`NotImplemented`).
52+
Here are most of the built-in objects considered false:
5153

5254
.. index::
5355
single: None (Built-in object)

Doc/whatsnew/3.15.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,16 @@ zlib
849849
Optimizations
850850
=============
851851

852+
* Builds using Visual Studio 2026 (MSVC 18) may now use the new
853+
:ref:`tail-calling interpreter <whatsnew314-tail-call-interpreter>`.
854+
Results on an early experimental MSVC compiler reported roughly 15% speedup
855+
on the geometric mean of pyperformance on Windows x86-64 over
856+
the switch-case interpreter. We have
857+
observed speedups ranging from 15% for large pure-Python libraries
858+
to 40% for long-running small pure-Python scripts on Windows.
859+
(Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`.
860+
Special thanks to the MSVC team including Hulon Jenkins.)
861+
852862
csv
853863
---
854864

Include/internal/pycore_ceval.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,17 @@ _Py_VectorCall_StackRefSteal(
415415
int total_args,
416416
_PyStackRef kwnames);
417417

418+
PyAPI_FUNC(PyObject*)
419+
_Py_VectorCallInstrumentation_StackRefSteal(
420+
_PyStackRef callable,
421+
_PyStackRef* arguments,
422+
int total_args,
423+
_PyStackRef kwnames,
424+
bool call_instrumentation,
425+
_PyInterpreterFrame* frame,
426+
_Py_CODEUNIT* this_instr,
427+
PyThreadState* tstate);
428+
418429
PyAPI_FUNC(PyObject *)
419430
_Py_BuiltinCallFast_StackRefSteal(
420431
_PyStackRef callable,
@@ -464,6 +475,11 @@ _Py_assert_within_stack_bounds(
464475
_PyInterpreterFrame *frame, _PyStackRef *stack_pointer,
465476
const char *filename, int lineno);
466477

478+
// Like PyMapping_GetOptionalItem, but returns the PyObject* instead of taking
479+
// it as an out parameter. This helps MSVC's escape analysis when used with
480+
// tail calling.
481+
PyAPI_FUNC(PyObject*) _PyMapping_GetOptionalItem2(PyObject* obj, PyObject* key, int* err);
482+
467483
#ifdef __cplusplus
468484
}
469485
#endif

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,11 @@ struct _Py_global_strings {
376376
STRUCT_FOR_ID(co_varnames)
377377
STRUCT_FOR_ID(code)
378378
STRUCT_FOR_ID(col_offset)
379+
STRUCT_FOR_ID(collector)
379380
STRUCT_FOR_ID(command)
380381
STRUCT_FOR_ID(comment_factory)
381382
STRUCT_FOR_ID(compile_mode)
383+
STRUCT_FOR_ID(compression)
382384
STRUCT_FOR_ID(config)
383385
STRUCT_FOR_ID(consts)
384386
STRUCT_FOR_ID(context)
@@ -441,7 +443,9 @@ struct _Py_global_strings {
441443
STRUCT_FOR_ID(event)
442444
STRUCT_FOR_ID(eventmask)
443445
STRUCT_FOR_ID(exc)
446+
STRUCT_FOR_ID(exc_tb)
444447
STRUCT_FOR_ID(exc_type)
448+
STRUCT_FOR_ID(exc_val)
445449
STRUCT_FOR_ID(exc_value)
446450
STRUCT_FOR_ID(excepthook)
447451
STRUCT_FOR_ID(exception)
@@ -697,6 +701,7 @@ struct _Py_global_strings {
697701
STRUCT_FOR_ID(print_file_and_line)
698702
STRUCT_FOR_ID(priority)
699703
STRUCT_FOR_ID(progress)
704+
STRUCT_FOR_ID(progress_callback)
700705
STRUCT_FOR_ID(progress_routine)
701706
STRUCT_FOR_ID(proto)
702707
STRUCT_FOR_ID(protocol)
@@ -737,6 +742,7 @@ struct _Py_global_strings {
737742
STRUCT_FOR_ID(reversed)
738743
STRUCT_FOR_ID(rounding)
739744
STRUCT_FOR_ID(salt)
745+
STRUCT_FOR_ID(sample_interval_us)
740746
STRUCT_FOR_ID(sched_priority)
741747
STRUCT_FOR_ID(scheduler)
742748
STRUCT_FOR_ID(script)
@@ -776,8 +782,10 @@ struct _Py_global_strings {
776782
STRUCT_FOR_ID(spam)
777783
STRUCT_FOR_ID(src)
778784
STRUCT_FOR_ID(src_dir_fd)
785+
STRUCT_FOR_ID(stack_frames)
779786
STRUCT_FOR_ID(stacklevel)
780787
STRUCT_FOR_ID(start)
788+
STRUCT_FOR_ID(start_time_us)
781789
STRUCT_FOR_ID(statement)
782790
STRUCT_FOR_ID(stats)
783791
STRUCT_FOR_ID(status)
@@ -818,6 +826,7 @@ struct _Py_global_strings {
818826
STRUCT_FOR_ID(times)
819827
STRUCT_FOR_ID(timespec)
820828
STRUCT_FOR_ID(timestamp)
829+
STRUCT_FOR_ID(timestamp_us)
821830
STRUCT_FOR_ID(timetuple)
822831
STRUCT_FOR_ID(timeunit)
823832
STRUCT_FOR_ID(top)

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_runtime_init_generated.h

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)