From 1e80fa36ad88ed8ba08b5bab66f7af3636866049 Mon Sep 17 00:00:00 2001 From: Miroslav Shubernetskiy Date: Tue, 29 May 2018 18:35:15 -0400 Subject: [PATCH 1/5] using six to import cPickle --- linesman/backends/pickle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linesman/backends/pickle.py b/linesman/backends/pickle.py index 77038ab..8d73bc4 100644 --- a/linesman/backends/pickle.py +++ b/linesman/backends/pickle.py @@ -13,9 +13,9 @@ # You should have received a copy of the GNU General Public License along # with linesman. If not, see . # -import cPickle import logging +from six.moves import cPickle from linesman.backends.base import Backend From 85eb4682e31640bea8572cb1e90803c0b390b01e Mon Sep 17 00:00:00 2001 From: Miroslav Shubernetskiy Date: Tue, 29 May 2018 18:35:41 -0400 Subject: [PATCH 2/5] using six to import cPickle --- linesman/backends/sqlite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linesman/backends/sqlite.py b/linesman/backends/sqlite.py index 8f996a1..7c028cd 100644 --- a/linesman/backends/sqlite.py +++ b/linesman/backends/sqlite.py @@ -13,11 +13,11 @@ # You should have received a copy of the GNU General Public License along # with linesman. If not, see . # -import cPickle import logging import sqlite3 import time +from six.moves import cPickle from linesman.backends.base import Backend From a3f291c90a72dc5ed430681374da6d11133de3db Mon Sep 17 00:00:00 2001 From: Miroslav Shubernetskiy Date: Tue, 29 May 2018 18:36:42 -0400 Subject: [PATCH 3/5] added six as a dep --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1b19344..a1cae59 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ import sys -install_requires = ["mako", "networkx==1.7", "pillow", "pygraphviz", 'Paste', 'WebOb'] +install_requires = ["mako", "networkx==1.7", "pillow", "pygraphviz", 'Paste', 'WebOb', 'six'] # ordereddict is required for versions < 2.7; its included in collections in # versions 2.7+ and 3.0+ From a5daec7cfaf2f46a83881590e539b89097d7588e Mon Sep 17 00:00:00 2001 From: Wolfgang Schnerring Date: Thu, 16 Jun 2022 15:11:36 +0200 Subject: [PATCH 4/5] Update to current networkx API --- linesman/__init__.py | 7 ++++--- linesman/middleware.py | 17 ++++++++++++----- linesman/templates/tree.tmpl | 2 +- linesman/tests/test_graphs.py | 2 +- setup.py | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/linesman/__init__.py b/linesman/__init__.py index e87a5a6..93d8e5b 100644 --- a/linesman/__init__.py +++ b/linesman/__init__.py @@ -18,6 +18,7 @@ from inspect import getmodule import networkx as nx +import networkx.drawing.nx_agraph log = logging.getLogger(__name__) @@ -48,7 +49,7 @@ def draw_graph(graph, output_path): ``output_path``: Location to store the rendered output. """ - nx.to_agraph(graph).draw(output_path, prog="dot") + networkx.drawing.nx_agraph.to_agraph(graph).draw(output_path, prog="dot") log.info("Wrote output to `%s'" % output_path) @@ -85,7 +86,7 @@ def create_graph(stats): 'reccallcount': stat.reccallcount, 'totaltime': stat.totaltime, } - g.add_node(caller_key, attr_dict=attrs) + g.add_node(caller_key, **attrs) # Add all the calls as edges for call in stat.calls or []: @@ -102,7 +103,7 @@ def create_graph(stats): g.add_edge(caller_key, callee_key, weight=call.totaltime, label=call.totaltime, - attr_dict=call_attrs) + **call_attrs) return g diff --git a/linesman/middleware.py b/linesman/middleware.py index 58bdbe7..610d11a 100644 --- a/linesman/middleware.py +++ b/linesman/middleware.py @@ -20,6 +20,7 @@ from tempfile import gettempdir from PIL import Image +from networkx.classes.reportviews import InDegreeView import networkx as nx from mako.lookup import TemplateLookup from paste.urlparser import StaticURLParser @@ -438,13 +439,19 @@ def prepare_graph(source_graph, cutoff_time, break_cycles=False): # Break cycles if break_cycles: for cycle in nx.simple_cycles(graph): - u, v = cycle[0], cycle[1] - if graph.has_edge(u, v): - graph.remove_edge(u, v) - cyclic_breaks.append((u, v)) + end = len(cycle) - 1 if len(cycle) > 1 else 1 + for i in range(end): + u = cycle[i] + if len(cycle) == 1: + v = u + else: + v = cycle[i + 1] + if graph.has_edge(u, v): + graph.remove_edge(u, v) + cyclic_breaks.append((u, v)) root_nodes = [node - for node, degree in graph.in_degree_iter() + for node, degree in InDegreeView(graph) if degree == 0] return graph, root_nodes, cyclic_breaks diff --git a/linesman/templates/tree.tmpl b/linesman/templates/tree.tmpl index 22193d5..3848d73 100644 --- a/linesman/templates/tree.tmpl +++ b/linesman/templates/tree.tmpl @@ -1,6 +1,6 @@ <%def name="print_tree(node)"> <% - node_obj = graph.node[node] + node_obj = graph._node[node] total_time_percentage = round(node_obj.get('totaltime') / session.duration * 100, 2) inline_time_percentage = round(node_obj.get('inlinetime') / session.duration * 100, 2) open_or_leaf = 'open' if graph.neighbors(node) else 'leaf' diff --git a/linesman/tests/test_graphs.py b/linesman/tests/test_graphs.py index 4d93f0a..c8bb383 100644 --- a/linesman/tests/test_graphs.py +++ b/linesman/tests/test_graphs.py @@ -9,7 +9,7 @@ class TestGraphUtils(unittest.TestCase): - @patch("networkx.to_agraph") + @patch("networkx.drawing.nx_agraph.to_agraph") def test_draw_graph(self, mock_to_agraph): """ Test that the graph gets converted to an agraph """ mock_draw = Mock() diff --git a/setup.py b/setup.py index a1cae59..b42d28c 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ import sys -install_requires = ["mako", "networkx==1.7", "pillow", "pygraphviz", 'Paste', 'WebOb', 'six'] +install_requires = ["mako", "networkx>=2.0", "pillow", "pygraphviz", 'Paste', 'WebOb', 'six'] # ordereddict is required for versions < 2.7; its included in collections in # versions 2.7+ and 3.0+ From fbbdee41d69775315ab0d43d8a2a45f8494990a4 Mon Sep 17 00:00:00 2001 From: Colin Goutte Date: Thu, 18 Apr 2024 10:42:55 +0200 Subject: [PATCH 5/5] Fix for recent pillow version --- linesman/middleware.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/linesman/middleware.py b/linesman/middleware.py index 610d11a..16a2ac5 100644 --- a/linesman/middleware.py +++ b/linesman/middleware.py @@ -31,6 +31,13 @@ from linesman import ProfilingSession, draw_graph +_pil_major = int(Image.__version__.split(".")[0]) +if _pil_major >= 10: + ANTIALIAS = Image.Resampling.LANCZOS +else: + ANTIALIAS = Image.ANTIALIAS + + log = logging.getLogger(__name__) # Graphs @@ -251,7 +258,7 @@ def render_graph(self, req): log.debug("Creating thumbnail for %s at %s.", session_uuid, thumbnail_path) im = Image.open(path, 'r') - im.thumbnail((600, 600), Image.ANTIALIAS) + im.thumbnail((600, 600), ANTIALIAS) im.save(thumbnail_path) return StaticURLParser(GRAPH_DIR)