From 212b6685a1a407036a7f92e23f8709c85fda3751 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Thu, 18 May 2023 00:29:47 +0300 Subject: [PATCH 01/19] Make Profile.print_stats support sorting by mutiple values --- Lib/cProfile.py | 5 +++-- Lib/profile.py | 6 +++--- Lib/test/test_profile.py | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 135a12c3965c00..e31d4d93edf81e 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -41,8 +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 hasattr(sort, '__iter__') or isinstance(sort, str): + sort = (sort,) + pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() def dump_stats(self, file): import marshal with open(file, 'wb') as f: diff --git a/Lib/profile.py b/Lib/profile.py index 4b82523b03d64b..4a37dfa3e54040 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -387,9 +387,9 @@ def simulate_cmd_complete(self): def print_stats(self, sort=-1): import pstats - pstats.Stats(self).strip_dirs().sort_stats(sort). \ - print_stats() - + if not hasattr(sort, '__iter__') or isinstance(sort, str): + sort = (sort,) + pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() def dump_stats(self, file): with open(file, 'wb') as f: self.create_stats() diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index a1dfc9abbb8ef7..1c8f1fd646c006 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -92,6 +92,14 @@ def test_run(self): self.profilermodule.run("int('1')", filename=TESTFN) self.assertTrue(os.path.exists(TESTFN)) + def test_run_with_sort_by_values(self): + s = StringIO() + stdout = sys.stdout + sys.stdout = s + self.profilermodule.run("int('1')", sort=('tottime', 'stdname')) + sys.stdout = stdout + self.assertIn("Ordered by: internal time, standard name", s.getvalue()) + def test_runctx(self): with silent(): self.profilermodule.runctx("testfunc()", globals(), locals()) From da1b596d90a4d49523b0130eb831096bdf2b95b8 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 21:33:23 +0000 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst 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 00000000000000..edc6567c18055c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst @@ -0,0 +1 @@ +Make the meth:`Profile.print_stats` support sorting by multiple values. Patched by Chiu-Hsiang Hsu and Furkan Onder. From f77135864d3554c1b2d8e1790eee4ecfa0023387 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Mon, 29 Jan 2024 02:55:08 +0300 Subject: [PATCH 03/19] update documentation according to the new feature --- Doc/library/profile.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 723f927135a0f4..a51d0e16fbf38a 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -457,6 +457,9 @@ Analysis of the profiler data is done using the :class:`~pstats.Stats` class. .. versionadded:: 3.7 Added the SortKey enum. + .. versionadded:: 3.13 + meth:`Profile.print_stats` can now accept multiple sort arguments. + .. method:: reverse_order() This method for the :class:`Stats` class reverses the ordering of the From 1d8c4e4a3607f006e5723549184c1537d02ee9d5 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Mon, 29 Jan 2024 02:55:26 +0300 Subject: [PATCH 04/19] fix code format --- Lib/cProfile.py | 1 + Lib/profile.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/cProfile.py b/Lib/cProfile.py index e31d4d93edf81e..d074c919438ca4 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -44,6 +44,7 @@ def print_stats(self, sort=-1): if not hasattr(sort, '__iter__') or isinstance(sort, str): sort = (sort,) pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() + def dump_stats(self, file): import marshal with open(file, 'wb') as f: diff --git a/Lib/profile.py b/Lib/profile.py index 4a37dfa3e54040..05c842e1d5304d 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -387,9 +387,10 @@ def simulate_cmd_complete(self): def print_stats(self, sort=-1): import pstats - if not hasattr(sort, '__iter__') or isinstance(sort, str): + if not hasattr(sort, "__iter__") or isinstance(sort, str): sort = (sort,) pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() + def dump_stats(self, file): with open(file, 'wb') as f: self.create_stats() From 82facb0243b3838f1922ea5effa8e02ccabd5371 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Mon, 29 Jan 2024 02:56:20 +0300 Subject: [PATCH 05/19] update the news entry --- .../next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index edc6567c18055c..b7f16a4f3686a2 100644 --- 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 @@ -1 +1 @@ -Make the meth:`Profile.print_stats` support sorting by multiple values. Patched by Chiu-Hsiang Hsu and Furkan Onder. +meth:`Profile.print_stats` has been improved to accept multiple sort arguments. Patched by Chiu-Hsiang Hsu and Furkan Onder. \ No newline at end of file From 80bb65b887aa20f11099eadabef3fc31091d9b4d Mon Sep 17 00:00:00 2001 From: furkanonder Date: Mon, 29 Jan 2024 03:39:11 +0300 Subject: [PATCH 06/19] fix code format --- Lib/cProfile.py | 3 ++- Lib/profile.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/cProfile.py b/Lib/cProfile.py index e31d4d93edf81e..11999662d49312 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -41,9 +41,10 @@ class Profile(_lsprof.Profiler): def print_stats(self, sort=-1): import pstats - if not hasattr(sort, '__iter__') or isinstance(sort, str): + if not hasattr(sort, "__iter__") or isinstance(sort, str): sort = (sort,) pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() + def dump_stats(self, file): import marshal with open(file, 'wb') as f: diff --git a/Lib/profile.py b/Lib/profile.py index 4a37dfa3e54040..05c842e1d5304d 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -387,9 +387,10 @@ def simulate_cmd_complete(self): def print_stats(self, sort=-1): import pstats - if not hasattr(sort, '__iter__') or isinstance(sort, str): + if not hasattr(sort, "__iter__") or isinstance(sort, str): sort = (sort,) pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() + def dump_stats(self, file): with open(file, 'wb') as f: self.create_stats() From 02537063be3f98ac37656c98366756a1fc405835 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Mon, 29 Jan 2024 03:42:29 +0300 Subject: [PATCH 07/19] update documentation according to the new feature --- Doc/library/profile.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 723f927135a0f4..9bcc6dc493de55 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -297,6 +297,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 sort key or a tuple of sort keys + to enable multi-level sorting. + + .. versionadded:: 3.13 + :meth:`~Profile.print_stats` can now accept multiple sort arguments. + .. method:: dump_stats(filename) Write the results of the current profile to *filename*. From 58c7e350f863ba507ef8e0e125018c830ae0b2fa Mon Sep 17 00:00:00 2001 From: furkanonder Date: Mon, 29 Jan 2024 03:42:34 +0300 Subject: [PATCH 08/19] update the news entry --- .../next/Library/2023-05-17-21-33-21.gh-issue-69990.Blvz9G.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index edc6567c18055c..b0cdf44f7b9e39 100644 --- 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 @@ -1 +1 @@ -Make the meth:`Profile.print_stats` support sorting by multiple values. Patched by Chiu-Hsiang Hsu and Furkan Onder. +:meth:`Profile.print_stats` has been improved to accept multiple sort arguments. Patched by Chiu-Hsiang Hsu and Furkan Onder. From fb4b8cb4c23998d6a6e0c89191b952f5916e0559 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Sat, 10 Feb 2024 14:53:27 +0300 Subject: [PATCH 09/19] use contextlib's redirect_stdout --- Lib/test/test_profile.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index 1c8f1fd646c006..0f16b92334999c 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -7,7 +7,7 @@ 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 @@ -93,12 +93,9 @@ def test_run(self): self.assertTrue(os.path.exists(TESTFN)) def test_run_with_sort_by_values(self): - s = StringIO() - stdout = sys.stdout - sys.stdout = s - self.profilermodule.run("int('1')", sort=('tottime', 'stdname')) - sys.stdout = stdout - self.assertIn("Ordered by: internal time, standard name", s.getvalue()) + 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(): From 66e1e821b2827382b4d5b5518bbba6879e44afa5 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Sat, 10 Feb 2024 15:04:42 +0300 Subject: [PATCH 10/19] use isinstance check for the sorting tuple --- Lib/cProfile.py | 2 +- Lib/profile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 11999662d49312..9c132372dc4ee0 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -41,7 +41,7 @@ class Profile(_lsprof.Profiler): def print_stats(self, sort=-1): import pstats - if not hasattr(sort, "__iter__") or isinstance(sort, str): + if not isinstance(sort, tuple): sort = (sort,) pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() diff --git a/Lib/profile.py b/Lib/profile.py index 05c842e1d5304d..f2f8c2f21333e0 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -387,7 +387,7 @@ def simulate_cmd_complete(self): def print_stats(self, sort=-1): import pstats - if not hasattr(sort, "__iter__") or isinstance(sort, str): + if not isinstance(sort, tuple): sort = (sort,) pstats.Stats(self).strip_dirs().sort_stats(*sort).print_stats() From dfa668d030531fd0a3a4d9720907fee1f86c6d9f Mon Sep 17 00:00:00 2001 From: furkanonder Date: Sat, 10 Feb 2024 15:09:49 +0300 Subject: [PATCH 11/19] update documentation of print_stats method --- Doc/library/profile.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 8759ceddcf576e..66de11952b2f5a 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -298,11 +298,11 @@ functions: profile and print the results to stdout. The *sort* parameter specifies the sorting order of the displayed - statistics. It accepts a single sort key or a tuple of sort keys + statistics. It accepts tuple of SortKey or accepts a tuple of SortKeys to enable multi-level sorting. .. versionadded:: 3.13 - :meth:`~Profile.print_stats` can now accept multiple sort arguments. + :meth:`~Profile.print_stats` now also accepts a tuple of SortKeys. .. method:: dump_stats(filename) @@ -464,8 +464,6 @@ Analysis of the profiler data is done using the :class:`~pstats.Stats` class. .. versionadded:: 3.7 Added the SortKey enum. - .. versionadded:: 3.13 - meth:`Profile.print_stats` can now accept multiple sort arguments. .. method:: reverse_order() From 96b1bdd27bcf3be33a140c42d1d1b51543ca2b00 Mon Sep 17 00:00:00 2001 From: furkanonder Date: Sat, 10 Feb 2024 15:10:26 +0300 Subject: [PATCH 12/19] remove whitespace --- Doc/library/profile.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 66de11952b2f5a..7c1e49acba8457 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -464,7 +464,6 @@ Analysis of the profiler data is done using the :class:`~pstats.Stats` class. .. versionadded:: 3.7 Added the SortKey enum. - .. method:: reverse_order() This method for the :class:`Stats` class reverses the ordering of the From f6b235f4d0741657658cc0c0ef75118a7b3d75e0 Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Sat, 10 Feb 2024 17:47:41 +0300 Subject: [PATCH 13/19] Update Doc/library/profile.rst Co-authored-by: Ege Akman --- Doc/library/profile.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index bf7b2d720b99de..77a433d0ba9cff 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -304,7 +304,7 @@ functions: to enable multi-level sorting. .. versionadded:: 3.13 - :meth:`~Profile.print_stats` now also accepts a tuple of SortKeys. + :meth:`~Profile.print_stats` now accepts a single key or a tuple of keys. .. method:: dump_stats(filename) From bb0507b094b1a770ff39a459efe86c8e3655236b Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Sat, 10 Feb 2024 17:47:58 +0300 Subject: [PATCH 14/19] Update Doc/library/profile.rst Co-authored-by: Ege Akman --- Doc/library/profile.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 77a433d0ba9cff..58033c871f5afb 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -300,8 +300,10 @@ functions: profile and print the results to stdout. The *sort* parameter specifies the sorting order of the displayed - statistics. It accepts tuple of SortKey or accepts a tuple of SortKeys - to enable multi-level sorting. + statistics. It accepts a single key or a tuple of keys to enable + multi-level sorting. A key can be either an integer, a string, or a + SortKey enum identifying the basis of a sort (for example: -1, + 'time', 'name', SortKey.TIME, or SortKey.NAME). .. versionadded:: 3.13 :meth:`~Profile.print_stats` now accepts a single key or a tuple of keys. From b0837167ceccd39c81a17bbdd5767172dac0275f Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Sat, 10 Feb 2024 18:10:32 +0300 Subject: [PATCH 15/19] fix the syntax of the documentation grammar in print_stats Co-authored-by: Serhiy Storchaka --- Doc/library/profile.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 58033c871f5afb..c8277be70925ea 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -302,8 +302,8 @@ functions: 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. A key can be either an integer, a string, or a - SortKey enum identifying the basis of a sort (for example: -1, - 'time', 'name', SortKey.TIME, or SortKey.NAME). + SortKey enum identifying the basis of a sort (for example: ``-1``, + ``'time'``, ``'name'``, ``SortKey.TIME``, or ``SortKey.NAME``). .. versionadded:: 3.13 :meth:`~Profile.print_stats` now accepts a single key or a tuple of keys. From 7fdbfabff74116778479cb1acc0df475e732cc60 Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Sat, 10 Feb 2024 18:34:38 +0300 Subject: [PATCH 16/19] clarify valid key types in print_stats method Co-authored-by: Ege Akman --- Doc/library/profile.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index c8277be70925ea..bd7190ca3d5a14 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -301,9 +301,12 @@ functions: 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. A key can be either an integer, a string, or a - SortKey enum identifying the basis of a sort (for example: ``-1``, - ``'time'``, ``'name'``, ``SortKey.TIME``, or ``SortKey.NAME``). + multi-level sorting. When passing a tuple of keys, each key must be + either a string or a SortKey enum, excluding integers. However, + if only a single key is provided, it can be an integer, a string, or a + SortKey enum. These keys serve to identify the basis of the sort, + such as ``'time'``, ``'name'``, ``SortKey.TIME``, or ``SortKey.NAME``, + among others." .. versionadded:: 3.13 :meth:`~Profile.print_stats` now accepts a single key or a tuple of keys. From 49ca01806416119ca5a6b9eb7f6691866a27dcaf Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Tue, 13 Feb 2024 23:26:45 +0300 Subject: [PATCH 17/19] clarify valid key types in print_stats method Co-authored-by: Serhiy Storchaka --- Doc/library/profile.rst | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index bd7190ca3d5a14..d2e1083affda6e 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -301,12 +301,7 @@ functions: 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. When passing a tuple of keys, each key must be - either a string or a SortKey enum, excluding integers. However, - if only a single key is provided, it can be an integer, a string, or a - SortKey enum. These keys serve to identify the basis of the sort, - such as ``'time'``, ``'name'``, ``SortKey.TIME``, or ``SortKey.NAME``, - among others." + multi-level sorting, as in :func:`Stats.sort_stats . .. versionadded:: 3.13 :meth:`~Profile.print_stats` now accepts a single key or a tuple of keys. From 4ea5e4ceba95c05f3e4cd6e862587892ad74c848 Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Tue, 13 Feb 2024 23:27:43 +0300 Subject: [PATCH 18/19] update versionadded section Co-authored-by: Serhiy Storchaka --- Doc/library/profile.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index d2e1083affda6e..f0b41ab06b43df 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -304,7 +304,7 @@ functions: multi-level sorting, as in :func:`Stats.sort_stats . .. versionadded:: 3.13 - :meth:`~Profile.print_stats` now accepts a single key or a tuple of keys. + :meth:`~Profile.print_stats` now accepts a tuple of keys. .. method:: dump_stats(filename) From 9978802d0ecb16ee42e4c40d28da294b24070804 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 16 Feb 2024 13:46:25 +0200 Subject: [PATCH 19/19] Update Doc/library/profile.rst --- Doc/library/profile.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index f0b41ab06b43df..3ca802e024bc27 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -301,7 +301,7 @@ functions: 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 . + multi-level sorting, as in :func:`Stats.sort_stats `. .. versionadded:: 3.13 :meth:`~Profile.print_stats` now accepts a tuple of keys.