Skip to content

Commit 3e18e18

Browse files
author
sarangbishal
committed
Add feature to show or disable argument names
1 parent dfc2791 commit 3e18e18

File tree

2 files changed

+63
-50
lines changed

2 files changed

+63
-50
lines changed

examples/Visualiser/__init__.py

Whitespace-only changes.

visualiser.py

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,104 @@
1-
import inspect
2-
31
import sys
42
from functools import wraps
53
from collections import OrderedDict
64
import pydot
75

8-
96
class Visualiser(object):
107
node_count = 0
118
graph = pydot.Dot(graph_type="digraph")
12-
def __init__(self, ignore_args):
9+
def __init__(self, ignore_args, show_argument_name=True):
10+
self.show_argument_name = show_argument_name
1311
self.ignore_args = ignore_args
1412

1513
@classmethod
1614
def write_image(self, filename="out"):
1715
self.graph.write_png(f"{filename}.png")
1816

19-
20-
2117
def __call__(self, fn):
2218
@wraps(fn)
2319
def wrapper(*args, **kwargs):
24-
20+
# Order all the keyword arguments
2521
kwargs = OrderedDict(sorted(kwargs.items()))
26-
argstr = ', '.join(
22+
23+
# If show_argument flag is True(default)
24+
# Then argument_string is:
25+
# a=1, b=31, c=0
26+
argument_string = ', '.join(
2727
[repr(a) for a in args] +
28-
["%s=%s" % (a, repr(b)) for a, b in kwargs.items()])
28+
[f"{key}={repr(value)}" for key, value in kwargs.items()])
2929

30-
# Current Function
31-
current_func_name = fn.__name__
32-
current_func_args = argstr
33-
current_func_signature = f"{current_func_name}({current_func_args})"
30+
current_function_label_argument_string = ', '.join(
31+
[repr(a) for a in args] +
32+
[f"{key}={repr(value)}" for key, value in kwargs.items() if key not in self.ignore_args])
33+
34+
# If show_argument flag is False
35+
# Then argument_string is:
36+
# 1, 31, 0
37+
if self.show_argument_name == False:
38+
argument_string = ', '.join(
39+
[repr(value) for value in args] +
40+
[f"{repr(value)}" for key, value in kwargs.items()])
41+
42+
current_function_label_argument_string = ', '.join(
43+
[repr(a) for a in args] +
44+
[f"{repr(value)}" for key, value in kwargs.items() if key not in self.ignore_args])
45+
46+
# Details about current function
47+
current_function_name = fn.__name__
48+
current_function_argument_string = argument_string
49+
# Current function signature looks as follows:
50+
# foo(1, 31, 0) or foo(a=1, b=31, c=0)
51+
current_function_signature = f"{current_function_name}({current_function_argument_string})"
52+
current_function_label = f"{current_function_name}({current_function_label_argument_string})"
3453

3554
# Caller Function
36-
caller_func_name = sys._getframe(1).f_code.co_name
37-
caller_func_arg_names = sys._getframe(1).f_code.co_varnames[:fn.__code__.co_argcount]
55+
caller_function_name = sys._getframe(1).f_code.co_name
56+
# Extract the names of arguments only
57+
caller_function_argument_names = sys._getframe(1).f_code.co_varnames[:fn.__code__.co_argcount]
58+
caller_function_locals = sys._getframe(1).f_locals
3859

39-
caller_func_locals = sys._getframe(1).f_locals
40-
caller_func_locals = OrderedDict(sorted(caller_func_locals.items()))
60+
# Sort all the locals of caller function
61+
caller_function_locals = OrderedDict(sorted(caller_function_locals.items()))
4162

42-
caller_func_args = ', '.join(
43-
[f"{key}={value}" for key, value in caller_func_locals.items() if (key in caller_func_arg_names)])
44-
caller_func_signature = f"{caller_func_name}({caller_func_args})"
4563

46-
caller_func_args = ', '.join(
47-
[f"{key}={value}" for key, value in caller_func_locals.items() if
48-
(key in caller_func_arg_names and key not in self.ignore_args)])
49-
caller_func_node_label = f"{caller_func_name}({caller_func_args})"
64+
# Extract only those locals which are in function signature
65+
caller_function_argument_string = ', '.join(
66+
[f"{key}={value}" for key, value in caller_function_locals.items() if (key in caller_function_argument_names)])
67+
caller_function_label_argument_string = ', '.join(
68+
[f"{key}={value}" for key, value in caller_function_locals.items() if
69+
(key in caller_function_argument_names and key not in self.ignore_args)])
5070

51-
if caller_func_name == '<module>':
52-
print(f"Drawing for {current_func_signature}")
71+
if self.show_argument_name == False:
72+
caller_function_argument_string = ', '.join(
73+
[f"{value}" for key, value in caller_function_locals.items() if
74+
(key in caller_function_argument_names)])
75+
caller_function_label_argument_string = ', '.join(
76+
[f"{value}" for key, value in caller_function_locals.items() if
77+
(key in caller_function_argument_names and key not in self.ignore_args)])
5378

54-
result = fn(*args, **kwargs)
79+
caller_func_signature = f"{caller_function_name}({caller_function_argument_string})"
80+
caller_func_label = f"{caller_function_name}({caller_function_label_argument_string})"
5581

56-
argstr = ', '.join(
57-
[repr(a) for a in args] +
58-
["%s=%s" % (a, repr(b)) for a, b in kwargs.items() if a not in self.ignore_args])
59-
current_node_label = f"{current_func_name}({argstr})"
82+
if caller_function_name == '<module>':
83+
print(f"Drawing for {current_function_signature}")
6084

61-
# # Child Node
62-
child_label = current_node_label
63-
child_name = current_func_signature
85+
result = fn(*args, **kwargs)
86+
87+
# #Child Node
88+
child_label = current_function_label
89+
child_name = current_function_signature
6490
v = pydot.Node(name=child_name, label=child_label)
6591
self.graph.add_node(v)
6692

6793
# Parent Node
6894
u = None
6995

70-
if caller_func_name != '<module>':
71-
print(f"Called {current_func_signature} by {caller_func_signature}")
72-
u = pydot.Node(name=caller_func_signature, label=caller_func_node_label)
96+
if caller_function_name != '<module>':
97+
print(f"Called {current_function_signature} by {caller_func_signature}")
98+
u = pydot.Node(name=caller_func_signature, label=caller_func_label)
7399
self.graph.add_node(u)
74100
edge = pydot.Edge(u, v)
75101
self.graph.add_edge(edge)
76102

77103
return result
78104
return wrapper
79-
80-
81-
82-
83-
@Visualiser(ignore_args=['node_num'])
84-
def fact(n, node_num):
85-
if n == 1:
86-
Visualiser.node_count += 1
87-
return 1
88-
89-
Visualiser.node_count += 1
90-
return n * fact(n=n - 1, node_num=Visualiser.node_count)
91-

0 commit comments

Comments
 (0)