gh-152409: Save the trace --file counts when --no-report is used (GH-152410)

serhiy-storchaka <[email protected]>
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/7f6389f48ee46df91e562d33564d02747b3f7ca3
commit: 7f6389f48ee46df91e562d33564d02747b3f7ca3
branch: main
author: tonghuaroot (童话) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-20T11:40:26+03:00
summary:

gh-152409: Save the trace --file counts when --no-report is used (GH-152410)

The counts were only persisted at the end of CoverageResults.write_results(),
which main() skips when --no-report is given, so --no-report --file silently
discarded them.

files:
A Misc/NEWS.d/next/Library/2026-06-27-10-30-00.gh-issue-152409.Tr8cE2.rst
M Lib/test/test_trace.py
M Lib/trace.py

diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py
index 19eee19bdea6d5..241e841d732f5e 100644
--- a/Lib/test/test_trace.py
+++ b/Lib/test/test_trace.py
@@ -1,5 +1,5 @@
 import os
-from pickle import dump
+from pickle import dump, load
 import sys
 from test.support import captured_stdout, requires_resource
 from test.support.os_helper import (TESTFN, rmtree, unlink)
@@ -561,6 +561,28 @@ def f():
         self.assertIn('lines   cov%   module   (path)', stdout)
         self.assertIn(f'6   100.0%   {modulename}   ({filename})', stdout)
 
+    def test_count_no_report_accumulates_counts(self):
+        # --no-report must still save the --file counts so they accumulate.
+        filename = f'{TESTFN}.py'
+        countsfile = f'{TESTFN}.counts'
+        with open(filename, 'w', encoding='utf-8') as fd:
+            self.addCleanup(unlink, filename)
+            self.addCleanup(unlink, countsfile)
+            fd.write('for i in range(3):\n    pass\n')
+        argv = ('-m', 'trace', '--count', '--no-report',
+                '--file', countsfile, filename)
+        assert_python_ok(*argv, PYTHONIOENCODING='utf-8')
+        self.assertTrue(os.path.exists(countsfile))
+        with open(countsfile, 'rb') as fd:
+            counts = load(fd)[0]
+        self.assertTrue(counts)
+        # A second run accumulates into the same file.
+        assert_python_ok(*argv, PYTHONIOENCODING='utf-8')
+        with open(countsfile, 'rb') as fd:
+            accumulated = load(fd)[0]
+        self.assertEqual(accumulated,
+                         {key: 2 * value for key, value in counts.items()})
+
     def test_run_as_module(self):
         assert_python_ok('-m', 'trace', '-l', '--module', 'timeit', '-n', '1')
         assert_python_failure('-m', 'trace', '-l', '--module', 'not_a_module_zzz')
diff --git a/Lib/trace.py b/Lib/trace.py
index 43ec201c4696d1..66471f45e1c004 100644
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -287,8 +287,11 @@ def write_results(self, show_missing=True, summary=False, coverdir=None, *,
                 n_lines, n_hits, modulename, filename = sums[m]
                 print(f"{n_lines:5d}   {n_hits/n_lines:.1%}   {modulename}   ({filename})")
 
+        self._save_counts()
+
+    def _save_counts(self):
+        """Save the accumulated counts to ``self.outfile`` if one was given."""
         if self.outfile:
-            # try and store counts and module info into self.outfile
             try:
                 with open(self.outfile, 'wb') as f:
                     pickle.dump((self.counts, self.calledfuncs, self.callers),
@@ -744,6 +747,8 @@ def parse_ignore_dir(s):
 
     if not opts.no_report:
         results.write_results(opts.missing, opts.summary, opts.coverdir)
+    else:
+        results._save_counts()
 
 if __name__=='__main__':
     main()
diff --git a/Misc/NEWS.d/next/Library/2026-06-27-10-30-00.gh-issue-152409.Tr8cE2.rst b/Misc/NEWS.d/next/Library/2026-06-27-10-30-00.gh-issue-152409.Tr8cE2.rst
new file mode 100644
index 00000000000000..2e6a759a102e66
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-06-27-10-30-00.gh-issue-152409.Tr8cE2.rst
@@ -0,0 +1,3 @@
+Fix the :mod:`trace` command-line tool not saving the ``--file`` counts
+when ``--no-report`` is used, which prevented accumulating counts over
+several runs.  Patch by tonghuaroot.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.