@@ -26,15 +26,40 @@ def __init__(self, ip):
26
26
self .bifrost_table = {}
27
27
self .plot_output = ""
28
28
self .bifrost_input = ""
29
+ self .bifrost_input_url = ""
30
+ self .chart_var = ""
29
31
self .visitor = None
30
32
33
+ def pre_run_cell (self , info ):
34
+ ast_tree = ast .parse (info .raw_cell )
35
+ assignVisitor = AssignVisitor (self .chart_var )
36
+ assignVisitor .visit (ast_tree )
37
+ output_var = assignVisitor .output_var
38
+ bifrost_input = assignVisitor .bifrost_input
39
+ bifrost_input_url = assignVisitor .bifrost_input_url
40
+ chart_var = assignVisitor .chart_var
41
+ if chart_var :
42
+ self .chart_var = chart_var
43
+ if output_var :
44
+ self .plot_output = output_var
45
+ if bifrost_input :
46
+ self .bifrost_input = bifrost_input
47
+ self .bifrost_input_url = ""
48
+ elif bifrost_input_url :
49
+ self .bifrost_input = ""
50
+ self .bifrost_input_url = bifrost_input_url
51
+ self .visitor = assignVisitor
52
+ # print(self.plot_output)
53
+ # print(self.bifrost_input)
54
+ # print(self.bifrost_input_url)
55
+
31
56
def post_run_cell (self , result ):
32
57
if not result .error_in_exec :
33
58
ast_tree = ast .parse (result .info .raw_cell )
34
59
35
60
callVisitor = CallVisitor ()
36
61
callVisitor .visit (ast_tree )
37
- print (f"args={ callVisitor .args } " )
62
+ # print(f"args={callVisitor.args}")
38
63
39
64
for arg in callVisitor .args :
40
65
key , value = arg .split ("." )
@@ -44,19 +69,6 @@ def post_run_cell(self, result):
44
69
self .bifrost_table [key ][value ] = 1
45
70
else :
46
71
self .bifrost_table [key ] = {value : 1 }
47
- # assignVisitor = AssignVisitor()
48
- # assignVisitor.visit(ast_tree)
49
-
50
- # for new_df in assignVisitor.new_dfs:
51
- # columns = get_ipython().run_cell(new_df + '.columns').result
52
- # print(columns)
53
- # if new_df in self.bifrost_table:
54
- # columns_set = set(columns)
55
- # table_set = set(self.bifrost_table[new_df].keys())
56
- # for new_col in (columns_set - table_set):
57
- # self.bifrost_table[new_df][new_col] = 0
58
- # else:
59
- # self.bifrost_table[new_df] = {col: 0 for col in columns}
60
72
61
73
62
74
class AttributeVisitor (ast .NodeVisitor ):
@@ -82,10 +94,12 @@ def visit_Name(self, node):
82
94
83
95
84
96
class AssignVisitor (ast .NodeVisitor ):
85
- def __init__ (self ):
86
- self .new_dfs = []
97
+ def __init__ (self , chart_var ):
98
+ self .new_dfs = set ()
87
99
self .output_var = None
88
100
self .bifrost_input = None
101
+ self .bifrost_input_url = None
102
+ self .chart_var = chart_var
89
103
90
104
def visit_Module (self , node ):
91
105
self .generic_visit (node )
@@ -97,16 +111,30 @@ def visit_Assign(self, node):
97
111
names = nameVisitor .names
98
112
attributeVisitor = AttributeVisitor ()
99
113
attributeVisitor .visit (node .value )
100
- attributes = attributeVisitor .attributes
101
- df_mask = [ call == "pd.DataFrame" for call in attributes ]
102
- plot_mask = "bifrost.plot" in attributes
114
+ attributes = "." . join ( attributeVisitor .attributes )
115
+ # df_mask = "pd.DataFrame" in attributes
116
+ # plot_mask = "bifrost.plot" in attributes
103
117
if "DataFrame" in attributes :
104
- self .new_dfs .extend (names )
105
- if "bifrost.plot" in attributes :
118
+ self .new_dfs .add (* names )
119
+
120
+ if (
121
+ isinstance (node .value , ast .Call )
122
+ and isinstance (node .value .func , ast .Name )
123
+ and node .value .func .id == "Chart"
124
+ ):
125
+ self .chart_var = node .targets [0 ].id
126
+ if isinstance (node .value .args [0 ], ast .Constant ):
127
+ self .bifrost_input_url = node .value .args [0 ].value
128
+ elif isinstance (node .value .args [0 ], ast .Name ):
129
+ self .bifrost_input = node .value .args [0 ].id
130
+ if (
131
+ isinstance (node .value , ast .Call )
132
+ and isinstance (node .value .func , ast .Attribute )
133
+ and isinstance (node .value .func .value , ast .Name )
134
+ and node .value .func .value .id == self .chart_var
135
+ and "plot" in attributes
136
+ ):
106
137
self .output_var = names [- 1 ] if len (names ) else None
107
- nameVisitor = NameVisitor ()
108
- nameVisitor .visit (node )
109
- self .bifrost_input = nameVisitor .names [- 1 ]
110
138
111
139
112
140
class SubscriptVisitor (ast .NodeVisitor ):
@@ -122,7 +150,7 @@ def visit_Subscript(self, node: ast.Subscript):
122
150
self .visit_Subscript (left )
123
151
else :
124
152
self .subscripts .append ([left .value .id , left .attr ])
125
- else :
153
+ elif isinstance ( node . value , ast . Name ) and isinstance ( node . slice , ast . Constant ) :
126
154
self .subscripts .append ([node .value .id , node .slice .value ])
127
155
128
156
@@ -198,9 +226,11 @@ def get_args(self, value, dataframe=None):
198
226
if isinstance (value , ast .Subscript ):
199
227
subscriptVisitor = SubscriptVisitor ()
200
228
subscriptVisitor .visit (value )
201
- self .args .append (
202
- f"{ subscriptVisitor .subscripts [0 ][0 ]} .{ subscriptVisitor .subscripts [0 ][1 ]} "
203
- )
229
+ if len (subscriptVisitor .subscripts ) != 0 :
230
+ self .args .append (
231
+ f"{ subscriptVisitor .subscripts [0 ][0 ]} .{ subscriptVisitor .subscripts [0 ][1 ]} "
232
+ )
233
+
204
234
# case arg is df.one
205
235
elif isinstance (value , ast .Attribute ):
206
236
attributeVisitor = AttributeVisitor ()
@@ -237,6 +267,7 @@ def isnotebook():
237
267
def load_ipython_extension (ipython ):
238
268
ipython .register_magics (BifrostTracing )
239
269
vw = BifrostWatcher (ipython )
270
+ ipython .events .register ("pre_run_cell" , vw .pre_run_cell )
240
271
ipython .events .register ("post_run_cell" , vw .post_run_cell )
241
272
return vw
242
273
0 commit comments