From 4e1375a1e5db62b71c8f7d2da6322b444ad1726e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Wed, 13 Oct 2021 20:00:12 +0200 Subject: [PATCH 1/6] fix import issue with py36 --- azure-pipelines.yml | 2 ++ src/pyquickhelper/pycode/profiling.py | 40 +++++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 135719a1..90f8f176 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,6 +6,8 @@ jobs: matrix: Python39: python.version: '3.9' + Python39: + python.version: '3.6' maxParallel: 3 steps: diff --git a/src/pyquickhelper/pycode/profiling.py b/src/pyquickhelper/pycode/profiling.py index 786e73fb..07e40b30 100644 --- a/src/pyquickhelper/pycode/profiling.py +++ b/src/pyquickhelper/pycode/profiling.py @@ -9,7 +9,17 @@ import os import site import cProfile -from pstats import SortKey, Stats +from pstats import Stats + +try: + from pstarts import SortKey +except ImportError: # pragma: no cover + # Python < 3.7 + + class SortKey: + LINE = 'line' + CUMULATIVE = 'cumulative' + TIME = 'time' class ProfileNode: @@ -53,9 +63,7 @@ def add_calls_to(self, pnode, time_elements): @staticmethod def _key(filename, line, fct): - key = "%s:%d" % (filename, line) - if key == "~:0": - key += ":%s" % fct + key = "%s:%d:%s" % (filename, line, fct) return key @property @@ -68,11 +76,13 @@ def get_root(self): "Returns the root of the graph." done = set() - def _get_root(node): + def _get_root(node, stor=None): + if stor is not None: + stor.append(node) if len(node.called_by) == 0: return node if len(node.called_by) == 1: - return _get_root(node.called_by[0]) + return _get_root(node.called_by[0], stor=stor) res = None for ct in node.called_by: k = id(node), id(ct) @@ -81,12 +91,20 @@ def _get_root(node): res = ct break if res is None: - raise RuntimeError( # pragma: no cover - "All paths have been explored and no entry point was found.") + # All paths have been explored and no entry point was found. + # Choosing the most consuming function. + return None done.add((id(node), id(res))) - return _get_root(res) + return _get_root(res, stor=stor) - return _get_root(self) + root = _get_root(self) + if root is None: + candidates = [] + _get_root(self, stor=candidates) + tall = [(n.tall, n) for n in candidates] + tall.sort() + root = tall[-1][-1] + return root def __repr__(self): "usual" @@ -537,7 +555,7 @@ def better_name(row): return ps, res if as_df: raise ValueError( # pragma: no cover - "as_df is not a compatible option with pyinst_format") + "as_df is not a compatible option with pyinst_format.") try: from pyinstrument import Profiler From 3642af51f75666f0915d2e0b1064eacc77b0c9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Wed, 13 Oct 2021 21:45:18 +0200 Subject: [PATCH 2/6] ci --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 90f8f176..376f53ac 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,7 +6,7 @@ jobs: matrix: Python39: python.version: '3.9' - Python39: + Python36: python.version: '3.6' maxParallel: 3 From 68b8c58b960a523a0436b92f329f8c42d317e543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Wed, 13 Oct 2021 22:05:38 +0200 Subject: [PATCH 3/6] update requirements --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 12d901a8..3c64a2c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -51,7 +51,6 @@ sphinx-gallery sphinxcontrib-imagesvg sphinx_rtd_theme tabulate -thebe tqdm traitlets>=5.0 unify From b0689a0ef0aafad0747644e5c4fbde021ba72d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Wed, 13 Oct 2021 22:13:21 +0200 Subject: [PATCH 4/6] ci --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3c64a2c3..5efdfd36 100644 --- a/requirements.txt +++ b/requirements.txt @@ -52,7 +52,7 @@ sphinxcontrib-imagesvg sphinx_rtd_theme tabulate tqdm -traitlets>=5.0 +traitlets unify virtualenv wheel From 5ede47b84f63f1fa1f6b546b60c6d1fabd1820b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Wed, 13 Oct 2021 22:23:14 +0200 Subject: [PATCH 5/6] py36 --- _unittests/ut_pycode/test_profiling.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_unittests/ut_pycode/test_profiling.py b/_unittests/ut_pycode/test_profiling.py index 211c1663..9f5b9023 100644 --- a/_unittests/ut_pycode/test_profiling.py +++ b/_unittests/ut_pycode/test_profiling.py @@ -6,7 +6,11 @@ import unittest import warnings import time -from pstats import SortKey +try: + from pstats import SortKey +except ImportError: + # python < 3.7 + from pyquickhelper.pycode.profiling import SortKey import pandas from pyquickhelper.pycode import ExtTestCase from pyquickhelper.pandashelper import df2rst From 5c77d3ab29e40653031baf88dce98c5ddf4d8e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?xavier=20dupr=C3=A9?= Date: Wed, 13 Oct 2021 22:39:14 +0200 Subject: [PATCH 6/6] py362 --- _unittests/ut_pycode/test_profiling.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_unittests/ut_pycode/test_profiling.py b/_unittests/ut_pycode/test_profiling.py index 9f5b9023..fa87aa9a 100644 --- a/_unittests/ut_pycode/test_profiling.py +++ b/_unittests/ut_pycode/test_profiling.py @@ -123,6 +123,8 @@ def simple(): self.assertIn('"start_time"', res) self.assertNotEmpty(ps) + @unittest.skipIf(sys.version_info[:2] < (3, 7), + reason="not supported") def test_profile_graph(self): calls = [0]