From 2a7a0020c9d006d268b839320979364498a5f0e6 Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Fri, 16 Feb 2024 15:03:46 +0300 Subject: [PATCH] gh-69990: Make Profile.print_stats support sorting by multiple values (GH-104590) Co-authored-by: Chiu-Hsiang Hsu --- Doc/library/profile.rst | 7 +++++++ Lib/cProfile.py | 4 +++- Lib/profile.py | 5 +++-- Lib/test/test_profile.py | 7 ++++++- .../Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst | 1 + 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index cc059b66fcb..3ca802e024b 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -299,6 +299,13 @@ functions: Create a :class:`~pstats.Stats` object based on the current profile and print the results to stdout. + The *sort* parameter specifies the sorting order of the displayed + statistics. It accepts a single key or a tuple of keys to enable + multi-level sorting, as in :func:`Stats.sort_stats `. + + .. versionadded:: 3.13 + :meth:`~Profile.print_stats` now accepts a tuple of keys. + .. method:: dump_stats(filename) Write the results of the current profile to *filename*. diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 135a12c3965..9c132372dc4 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -41,7 +41,9 @@ class Profile(_lsprof.Profiler): def print_stats(self, sort=-1): import pstats - pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats() + if not isinstance(sort, tuple): + sort = (sort,) + pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() def dump_stats(self, file): import marshal diff --git a/Lib/profile.py b/Lib/profile.py index 4b82523b03d..f2f8c2f2133 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -387,8 +387,9 @@ class Profile: def print_stats(self, sort=-1): import pstats - pstats.Stats(self).strip_dirs().sort_stats(sort). \ - print_stats() + if not isinstance(sort, tuple): + sort = (sort,) + pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() def dump_stats(self, file): with open(file, 'wb') as f: diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index a1dfc9abbb8..0f16b923349 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -7,7 +7,7 @@ import os from difflib import unified_diff from io import StringIO from test.support.os_helper import TESTFN, unlink, temp_dir, change_cwd -from contextlib import contextmanager +from contextlib import contextmanager, redirect_stdout import profile from test.profilee import testfunc, timer @@ -92,6 +92,11 @@ class ProfileTest(unittest.TestCase): self.profilermodule.run("int('1')", filename=TESTFN) self.assertTrue(os.path.exists(TESTFN)) + def test_run_with_sort_by_values(self): + with redirect_stdout(StringIO()) as f: + self.profilermodule.run("int('1')", sort=('tottime', 'stdname')) + self.assertIn("Ordered by: internal time, standard name", f.getvalue()) + def test_runctx(self): with silent(): self.profilermodule.runctx("testfunc()", globals(), locals()) diff --git a/Misc/NEWS.d/next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst b/Misc/NEWS.d/next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst new file mode 100644 index 00000000000..b0cdf44f7b9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst @@ -0,0 +1 @@ +:meth:`Profile.print_stats` has been improved to accept multiple sort arguments. Patched by Chiu-Hsiang Hsu and Furkan Onder.