From 3444ef9d30e0d4160357ab93109407d1ed377635 Mon Sep 17 00:00:00 2001 From: Karolina Surma <33810531+befeleme@users.noreply.github.com> Date: Tue, 11 Aug 2026 20:07:59 +0200 Subject: [PATCH 1/2] gh-110167: Document the increase of `test.support.LOOPBACK_TIMEOUT` to 10 seconds (#155571) --- Doc/library/test.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index f3b5383658b5ac..72ffc2a0b760ea 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -285,7 +285,7 @@ The :mod:`!test.support` module defines the following constants: :meth:`~socket.socket.recv` and :meth:`~socket.socket.send` methods of :class:`socket.socket`. - Its default value is 5 seconds. + Its default value is 10 seconds. See also :data:`INTERNET_TIMEOUT`. From ee68f5f46a14e2bbf22d72796e45e5f467951792 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Wed, 12 Aug 2026 00:16:05 +0100 Subject: [PATCH 2/2] gh-154059: Fix Tachyon flame graph time units (#154036) --- .../sampling/_flamegraph_assets/flamegraph.js | 20 +++++++++++-------- Lib/profiling/sampling/stack_collector.py | 2 +- .../test_sampling_profiler/test_collectors.py | 5 ++++- ...-07-19-00-00-00.gh-issue-154059.JiBcOM.rst | 2 ++ 4 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2026-07-19-00-00-00.gh-issue-154059.JiBcOM.rst diff --git a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js index f1cdf5142fa394..e055801a405e36 100644 --- a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js +++ b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js @@ -99,6 +99,10 @@ function getDisplayName(moduleName, filename) { return filename; } +function samplesToMilliseconds(samples, data) { + return (samples * data.stats.sample_interval_usec / 1000).toFixed(2); +} + function selectFlamegraphData(selectedThreadId = null) { let baseData = isShowingElided ? elidedFlamegraphData : normalData; @@ -255,12 +259,12 @@ function setupLogos() { // Status Bar // ============================================================================ -function updateStatusBar(nodeData, rootValue) { +function updateStatusBar(nodeData, rootValue, data) { const funcname = resolveString(nodeData.funcname) || resolveString(nodeData.name) || "--"; const filename = resolveString(nodeData.filename) || ""; const moduleName = resolveString(nodeData.module) || ""; const lineno = nodeData.lineno; - const timeMs = (nodeData.value / 1000).toFixed(2); + const timeMs = samplesToMilliseconds(nodeData.value, data); const percent = rootValue > 0 ? ((nodeData.value / rootValue) * 100).toFixed(1) : "0.0"; const brandEl = document.getElementById('status-brand'); @@ -322,9 +326,9 @@ function createPythonTooltip(data) { .style("opacity", 0); } - const timeMs = (d.data.value / 1000).toFixed(2); + const timeMs = samplesToMilliseconds(d.data.value, data); const selfSamples = d.data.self || 0; - const selfMs = (selfSamples / 1000).toFixed(2); + const selfMs = samplesToMilliseconds(selfSamples, data); const percentage = ((d.data.value / data.value) * 100).toFixed(2); const relativePercentage = Math.min(100, ((d.data.value / (zoomedNodeValue ?? data.value)) * 100)).toFixed(2); const calls = d.data.calls || 0; @@ -408,9 +412,9 @@ function createPythonTooltip(data) { // Differential stats section let diffSection = ""; if (d.data.diff !== undefined && d.data.baseline !== undefined) { - const baselineSelf = (d.data.baseline / 1000).toFixed(2); - const currentSelf = ((d.data.self_time || 0) / 1000).toFixed(2); - const diffMs = (d.data.diff / 1000).toFixed(2); + const baselineSelf = samplesToMilliseconds(d.data.baseline, data); + const currentSelf = samplesToMilliseconds(d.data.self_time || 0, data); + const diffMs = samplesToMilliseconds(d.data.diff, data); const diffPct = d.data.diff_pct; const sign = d.data.diff >= 0 ? "+" : ""; const diffClass = d.data.diff > 0 ? "regression" : (d.data.diff < 0 ? "improvement" : "neutral"); @@ -508,7 +512,7 @@ function createPythonTooltip(data) { .style("opacity", 1); // Update status bar - updateStatusBar(d.data, data.value); + updateStatusBar(d.data, data.value, data); }; pythonTooltip.hide = function () { diff --git a/Lib/profiling/sampling/stack_collector.py b/Lib/profiling/sampling/stack_collector.py index ace0e1a1229013..796a900e084676 100644 --- a/Lib/profiling/sampling/stack_collector.py +++ b/Lib/profiling/sampling/stack_collector.py @@ -70,7 +70,7 @@ def export(self, filename): class FlamegraphCollector(StackTraceCollector): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.stats = {} + self.stats = {"sample_interval_usec": self.sample_interval_usec} self._root = { "samples": 0, "children": {}, diff --git a/Lib/test/test_profiling/test_sampling_profiler/test_collectors.py b/Lib/test/test_profiling/test_sampling_profiler/test_collectors.py index 1aba1572cc89d3..c27ad6663df1c8 100644 --- a/Lib/test/test_profiling/test_sampling_profiler/test_collectors.py +++ b/Lib/test/test_profiling/test_sampling_profiler/test_collectors.py @@ -505,6 +505,7 @@ def test_flamegraph_collector_basic(self): self.assertIn("func1 (file.py:10)", resolve_name(child, strings)) self.assertEqual(child["value"], 1) self.assertEqual(child["self"], 1) # leaf: all time is self + self.assertEqual(data["stats"]["sample_interval_usec"], 1000) def test_flamegraph_collector_export(self): """Test flamegraph HTML export functionality.""" @@ -513,7 +514,7 @@ def test_flamegraph_collector_export(self): ) self.addCleanup(close_and_unlink, flamegraph_out) - collector = FlamegraphCollector(1000) + collector = FlamegraphCollector(10000) # Create some test data (use Interpreter/Thread objects like runtime) test_frames1 = [ @@ -569,6 +570,8 @@ def test_flamegraph_collector_export(self): self.assertIn('"name":', content) self.assertIn('"value":', content) self.assertIn('"children":', content) + self.assertIn('"sample_interval_usec": 10000', content) + self.assertIn("samples * data.stats.sample_interval_usec / 1000", content) def test_flamegraph_collector_empty_export_fails(self): """Test empty flamegraph export reports no output.""" diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-07-19-00-00-00.gh-issue-154059.JiBcOM.rst b/Misc/NEWS.d/next/Tools-Demos/2026-07-19-00-00-00.gh-issue-154059.JiBcOM.rst new file mode 100644 index 00000000000000..92e047067e97bd --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2026-07-19-00-00-00.gh-issue-154059.JiBcOM.rst @@ -0,0 +1,2 @@ +Fix the time units in Tachyon flame graph tooltips by accounting for the +sampling interval when converting samples to milliseconds.