From 8c8bfd51a4fc1691c17e2d7787167e9dce05d1cc Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 3 Feb 2026 08:55:11 +0100 Subject: [PATCH 01/11] [Feature] Improve plotting by using short names --- .../interactive/dependency_plot.py | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index 53e44b9c..cff27cfb 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -218,7 +218,7 @@ def plot_dependency_graph_function( graph = nx.DiGraph() for node in node_lst: if node["type"] == "input": - graph.add_node(node["id"], label=str(node["value"]), shape=node["shape"]) + graph.add_node(node["id"], label=_short_object_name(node=node["value"]), shape=node["shape"]) else: graph.add_node(node["id"], label=str(node["name"]), shape=node["shape"]) for edge in edge_lst: @@ -306,3 +306,24 @@ def export_dependency_graph_function( } with open(file_name, "w") as f: json.dump(pwd_dict, f, indent=4) + + +def _short_object_name(node): + if isinstance(node, tuple): + return str(tuple(_short_object_name(node=el) for el in node)) + elif isinstance(node, list): + return str([_short_object_name(node=el) for el in node]) + elif isinstance(node, dict): + return str({_short_object_name(node=key): _short_object_name(node=value) for key, value in node.items()}) + else: + node_value_str = str(node) + if "object at" in node_value_str: + return node_value_str[1:-1].split()[0] + "()" + elif " 20: + return node_value_str[:21] + "..." + else: + return node_value_str From 57e8d5c75e9f922f01e036b15cb8864c9eb801ae Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 07:58:28 +0000 Subject: [PATCH 02/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../task_scheduler/interactive/dependency_plot.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index cff27cfb..d8d01e98 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -218,7 +218,11 @@ def plot_dependency_graph_function( graph = nx.DiGraph() for node in node_lst: if node["type"] == "input": - graph.add_node(node["id"], label=_short_object_name(node=node["value"]), shape=node["shape"]) + graph.add_node( + node["id"], + label=_short_object_name(node=node["value"]), + shape=node["shape"], + ) else: graph.add_node(node["id"], label=str(node["name"]), shape=node["shape"]) for edge in edge_lst: @@ -314,7 +318,12 @@ def _short_object_name(node): elif isinstance(node, list): return str([_short_object_name(node=el) for el in node]) elif isinstance(node, dict): - return str({_short_object_name(node=key): _short_object_name(node=value) for key, value in node.items()}) + return str( + { + _short_object_name(node=key): _short_object_name(node=value) + for key, value in node.items() + } + ) else: node_value_str = str(node) if "object at" in node_value_str: From 22a2291c73f330a04db50347816f248da4f32e88 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 3 Feb 2026 09:04:57 +0100 Subject: [PATCH 03/11] add a test --- .../interactive/test_dependency_plot.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/unit/task_scheduler/interactive/test_dependency_plot.py diff --git a/tests/unit/task_scheduler/interactive/test_dependency_plot.py b/tests/unit/task_scheduler/interactive/test_dependency_plot.py new file mode 100644 index 00000000..d9805cfc --- /dev/null +++ b/tests/unit/task_scheduler/interactive/test_dependency_plot.py @@ -0,0 +1,21 @@ +import unittest +from executorlib.task_scheduler.interactive.dependency_plot import _short_object_name + + +class MyClass: + def __init__(self, i): + self._i = i + + +def my_function(i): + return i + + +class TestShortObjectName(unittest.TestCase): + def test_short_object_name(self): + result = _short_object_name(node=[MyClass("a"), MyClass("b")]) + self.assertEqual("['__main__.MyClass()', '__main__.MyClass()']", result) + result = _short_object_name(node=(MyClass("a"), MyClass("b"))) + self.assertEqual("('__main__.MyClass()', '__main__.MyClass()')", result) + result = _short_object_name(node={"this is a very long string far too long for a dictionary key": my_function}) + self.assertEqual("{'this is a very long s...': 'my_function()'}", result) From 4acf187326a73a76122dd402fa05caebbecd36f3 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 3 Feb 2026 09:07:36 +0100 Subject: [PATCH 04/11] handle cases all on one level --- .../interactive/dependency_plot.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index d8d01e98..2cbd242e 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -313,26 +313,26 @@ def export_dependency_graph_function( def _short_object_name(node): + node_value_str = str(node) if isinstance(node, tuple): - return str(tuple(_short_object_name(node=el) for el in node)) + short_name = str(tuple(_short_object_name(node=el) for el in node)) elif isinstance(node, list): - return str([_short_object_name(node=el) for el in node]) + short_name =str([_short_object_name(node=el) for el in node]) elif isinstance(node, dict): - return str( + short_name =str( { _short_object_name(node=key): _short_object_name(node=value) for key, value in node.items() } ) + elif "object at" in node_value_str: + short_name =node_value_str[1:-1].split()[0] + "()" + elif " 20: + short_name =node_value_str[:21] + "..." else: - node_value_str = str(node) - if "object at" in node_value_str: - return node_value_str[1:-1].split()[0] + "()" - elif " 20: - return node_value_str[:21] + "..." - else: - return node_value_str + short_name =node_value_str + return short_name From c5cec1be46cba0dabf37c6b169fe6a7340629873 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 08:07:46 +0000 Subject: [PATCH 05/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../task_scheduler/interactive/dependency_plot.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index 2cbd242e..fd273bb3 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -317,22 +317,22 @@ def _short_object_name(node): if isinstance(node, tuple): short_name = str(tuple(_short_object_name(node=el) for el in node)) elif isinstance(node, list): - short_name =str([_short_object_name(node=el) for el in node]) + short_name = str([_short_object_name(node=el) for el in node]) elif isinstance(node, dict): - short_name =str( + short_name = str( { _short_object_name(node=key): _short_object_name(node=value) for key, value in node.items() } ) elif "object at" in node_value_str: - short_name =node_value_str[1:-1].split()[0] + "()" + short_name = node_value_str[1:-1].split()[0] + "()" elif " 20: - short_name =node_value_str[:21] + "..." + short_name = node_value_str[:21] + "..." else: - short_name =node_value_str + short_name = node_value_str return short_name From 46e345c2d934c811a2303add6ea255ba2e9ec1c7 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 3 Feb 2026 09:13:40 +0100 Subject: [PATCH 06/11] Always shorten name --- .../task_scheduler/interactive/dependency_plot.py | 7 ++++--- .../task_scheduler/interactive/test_dependency_plot.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index fd273bb3..7b400502 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -331,8 +331,9 @@ def _short_object_name(node): short_name = node_value_str.split()[1] + "()" elif "(" in node_value_str and ")" in node_value_str: short_name = node_value_str.split("(")[0] + "()" - elif len(node_value_str) > 20: - short_name = node_value_str[:21] + "..." else: short_name = node_value_str - return short_name + if len(short_name) > 20: + return short_name[:21] + "..." + else: + return short_name diff --git a/tests/unit/task_scheduler/interactive/test_dependency_plot.py b/tests/unit/task_scheduler/interactive/test_dependency_plot.py index d9805cfc..ebd124e3 100644 --- a/tests/unit/task_scheduler/interactive/test_dependency_plot.py +++ b/tests/unit/task_scheduler/interactive/test_dependency_plot.py @@ -14,8 +14,8 @@ def my_function(i): class TestShortObjectName(unittest.TestCase): def test_short_object_name(self): result = _short_object_name(node=[MyClass("a"), MyClass("b")]) - self.assertEqual("['__main__.MyClass()', '__main__.MyClass()']", result) + self.assertEqual("['unit.task_scheduler.interactive.test_dependency_plot.MyClass()', 'unit.task_scheduler.interactive.test_dependency_plot.MyClass()']", result) result = _short_object_name(node=(MyClass("a"), MyClass("b"))) - self.assertEqual("('__main__.MyClass()', '__main__.MyClass()')", result) + self.assertEqual("('unit.task_scheduler.interactive.test_dependency_plot.MyClass()', 'unit.task_scheduler.interactive.test_dependency_plot.MyClass()')", result) result = _short_object_name(node={"this is a very long string far too long for a dictionary key": my_function}) self.assertEqual("{'this is a very long s...': 'my_function()'}", result) From de437cbf2ae66292f84c679d67fe5a0313997b3a Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 3 Feb 2026 09:18:30 +0100 Subject: [PATCH 07/11] reduce classes --- .../task_scheduler/interactive/dependency_plot.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index 7b400502..12c5df15 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -326,14 +326,13 @@ def _short_object_name(node): } ) elif "object at" in node_value_str: - short_name = node_value_str[1:-1].split()[0] + "()" + short_name = node_value_str[1:-1].split()[0].split(".")[-1] + "()" elif " 20: + short_name = node_value_str[:21] + "..." else: short_name = node_value_str - if len(short_name) > 20: - return short_name[:21] + "..." - else: - return short_name + return short_name From a17df2867d353db11fa6c2c902479af9ecb35f48 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 3 Feb 2026 09:26:08 +0100 Subject: [PATCH 08/11] fix tests --- tests/unit/task_scheduler/interactive/test_dependency_plot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/task_scheduler/interactive/test_dependency_plot.py b/tests/unit/task_scheduler/interactive/test_dependency_plot.py index ebd124e3..0bba1cb9 100644 --- a/tests/unit/task_scheduler/interactive/test_dependency_plot.py +++ b/tests/unit/task_scheduler/interactive/test_dependency_plot.py @@ -14,8 +14,8 @@ def my_function(i): class TestShortObjectName(unittest.TestCase): def test_short_object_name(self): result = _short_object_name(node=[MyClass("a"), MyClass("b")]) - self.assertEqual("['unit.task_scheduler.interactive.test_dependency_plot.MyClass()', 'unit.task_scheduler.interactive.test_dependency_plot.MyClass()']", result) + self.assertEqual("['MyClass()', 'MyClass()']", result) result = _short_object_name(node=(MyClass("a"), MyClass("b"))) - self.assertEqual("('unit.task_scheduler.interactive.test_dependency_plot.MyClass()', 'unit.task_scheduler.interactive.test_dependency_plot.MyClass()')", result) + self.assertEqual("('MyClass()', 'MyClass()')", result) result = _short_object_name(node={"this is a very long string far too long for a dictionary key": my_function}) self.assertEqual("{'this is a very long s...': 'my_function()'}", result) From 2b426c551824eaaa73b31c562950304841b1ce8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 7 Feb 2026 13:39:14 +0100 Subject: [PATCH 09/11] Convert multi line entries to class string --- src/executorlib/task_scheduler/interactive/dependency_plot.py | 2 ++ tests/unit/task_scheduler/interactive/test_dependency_plot.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index 12c5df15..b01f4e59 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -331,6 +331,8 @@ def _short_object_name(node): short_name = node_value_str.split()[1] + "()" elif "(" in node_value_str and ")" in node_value_str: short_name = node_value_str.split("(")[0] + "()" + elif "\n" in node_value_str: + short_name = str(type(node)).split("'")[1].split(".")[-1] + "()" elif len(node_value_str) > 20: short_name = node_value_str[:21] + "..." else: diff --git a/tests/unit/task_scheduler/interactive/test_dependency_plot.py b/tests/unit/task_scheduler/interactive/test_dependency_plot.py index 0bba1cb9..2e48ff43 100644 --- a/tests/unit/task_scheduler/interactive/test_dependency_plot.py +++ b/tests/unit/task_scheduler/interactive/test_dependency_plot.py @@ -1,4 +1,5 @@ import unittest +import numpy as np from executorlib.task_scheduler.interactive.dependency_plot import _short_object_name @@ -17,5 +18,7 @@ def test_short_object_name(self): self.assertEqual("['MyClass()', 'MyClass()']", result) result = _short_object_name(node=(MyClass("a"), MyClass("b"))) self.assertEqual("('MyClass()', 'MyClass()')", result) + result = _short_object_name(node=[np.array([[1,2], [4,3]]), np.array([[1,2], [4,3]])]) + self.assertEqual("['ndarray()', 'ndarray()']", result) result = _short_object_name(node={"this is a very long string far too long for a dictionary key": my_function}) self.assertEqual("{'this is a very long s...': 'my_function()'}", result) From a7710c9199f598e6c932e49256ec59fc540dffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 7 Feb 2026 13:49:06 +0100 Subject: [PATCH 10/11] cover all lines of new function --- .../task_scheduler/interactive/test_dependency_plot.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/task_scheduler/interactive/test_dependency_plot.py b/tests/unit/task_scheduler/interactive/test_dependency_plot.py index 2e48ff43..489d97b1 100644 --- a/tests/unit/task_scheduler/interactive/test_dependency_plot.py +++ b/tests/unit/task_scheduler/interactive/test_dependency_plot.py @@ -8,6 +8,14 @@ def __init__(self, i): self._i = i +class MyClassStr: + def __init__(self, i): + self._i = i + + def __str__(self): + return "MyClassStr(i=" + str(self._i) + ")" + + def my_function(i): return i @@ -18,6 +26,8 @@ def test_short_object_name(self): self.assertEqual("['MyClass()', 'MyClass()']", result) result = _short_object_name(node=(MyClass("a"), MyClass("b"))) self.assertEqual("('MyClass()', 'MyClass()')", result) + result = _short_object_name(node=[MyClassStr("a"), MyClassStr("b")]) + self.assertEqual("['MyClassStr()', 'MyClassStr()']", result) result = _short_object_name(node=[np.array([[1,2], [4,3]]), np.array([[1,2], [4,3]])]) self.assertEqual("['ndarray()', 'ndarray()']", result) result = _short_object_name(node={"this is a very long string far too long for a dictionary key": my_function}) From ada8e5afa861f3fdebcf6611617be7d385b66201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 7 Feb 2026 13:54:52 +0100 Subject: [PATCH 11/11] Catch multi line first --- src/executorlib/task_scheduler/interactive/dependency_plot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/executorlib/task_scheduler/interactive/dependency_plot.py b/src/executorlib/task_scheduler/interactive/dependency_plot.py index b01f4e59..589d75ed 100644 --- a/src/executorlib/task_scheduler/interactive/dependency_plot.py +++ b/src/executorlib/task_scheduler/interactive/dependency_plot.py @@ -329,10 +329,10 @@ def _short_object_name(node): short_name = node_value_str[1:-1].split()[0].split(".")[-1] + "()" elif " 20: short_name = node_value_str[:21] + "..." else: