1
- import ipdb
2
1
import threading
3
2
import pandas as pd
4
3
import inspect
5
4
6
5
from . import wb_stack
7
- from . import fstriplestore
8
6
from . import obj_tracking
9
7
from . import obj_utils
8
+ from . import method_call_rdf
9
+ from . import rdf_io
10
10
11
11
from .nested_call import NestedCall
12
12
13
- from . import method_call_rdf
13
+ # NB: should be better way to count method calls
14
+ method_counter = 0
14
15
15
- from . import rdf_io
16
16
17
- method_counter = 0 # NB: should be better way to count method calls
18
17
class MethodCall (wb_stack .WithBlock ):
19
18
def __init__ (self , method_name ):
20
19
super ().__init__ (method_name )
@@ -23,27 +22,29 @@ def __init__(self, method_name):
23
22
self .method_bound_args = None
24
23
25
24
self .args_l = None
26
-
25
+
27
26
def add_args_l_entry__ (self , arg_name , arg_obj ):
28
- if arg_name is None : arg_name = f"arg_{ len (self .args_l )} "
29
-
27
+ if arg_name is None :
28
+ arg_name = f"arg_{ len (self .args_l )} "
29
+
30
30
if type (arg_obj ).__name__ == "NestedCall" :
31
31
self .args_l .append ((arg_name , arg_obj ))
32
- elif isinstance (arg_obj , pd .DataFrame ) or isinstance (arg_obj , pd .Series ):
32
+ elif isinstance (arg_obj , pd .DataFrame ) \
33
+ or isinstance (arg_obj , pd .Series ):
33
34
arg_obj_id , found = obj_tracking .get_tracking_obj (arg_obj )
34
- #print("arg id:", id(arg_obj), found)
35
+
35
36
if found :
36
37
arg_obj_state = arg_obj_id .last_obj_state
37
38
else :
38
39
arg_obj_state = obj_utils .ObjState (arg_obj , arg_obj_id )
39
-
40
+
40
41
self .args_l .append ((arg_name , arg_obj_state ))
41
42
else :
42
43
self .args_l .append ((arg_name , arg_obj ))
43
-
44
+
44
45
def build_args_l__ (self ):
45
46
self .args_l = []
46
- for arg_name , arg_obj in self .method_bound_args .arguments .items ():
47
+ for arg_name , arg_obj in self .method_bound_args .arguments .items ():
47
48
arg_kind = self .method_signature .parameters .get (arg_name ).kind
48
49
if arg_kind == inspect .Parameter .VAR_KEYWORD :
49
50
for kwarg_name , kwarg_obj in arg_obj .items ():
@@ -54,7 +55,7 @@ def build_args_l__(self):
54
55
self .add_args_l_entry__ (None , p_arg_obj )
55
56
else :
56
57
self .add_args_l_entry__ (arg_name , arg_obj )
57
-
58
+
58
59
def handle_start_method_call (self , method_name , method_signature , method_args , method_kwargs ):
59
60
if method_name == "pin" :
60
61
arg0_obj = method_args [0 ]
@@ -64,47 +65,54 @@ def handle_start_method_call(self, method_name, method_signature, method_args, m
64
65
else :
65
66
raise Exception ("logical error: expected to have obj state created before" )
66
67
return method_args , method_kwargs
67
-
68
+
68
69
self .thread_id = threading .get_native_id ()
69
70
70
71
all_args = method_args
71
72
self .method_signature = method_signature
72
73
self .method_bound_args = self .method_signature .bind (* all_args , ** method_kwargs )
73
74
args_w_specified_values = self .method_bound_args .arguments .keys ()
74
75
# NB:
75
- # according to python doc default values are evaluated and saved only once when function is defined
76
- # apply_defaults method is to be used to put default values to method_bound_args.arguments
77
- # decision to call or not to call apply_defaults could affect program execution since we could modify arguments
78
- # of real method call which will happen after this method returns new args and kwargs.
76
+ # according to python doc default values are evaluated and saved only
77
+ # once when function is defined. apply_defaults method is to be used to
78
+ # put default values to `method_bound_args.arguments`. decision to call
79
+ # or not to call apply_defaults could affect program execution since we
80
+ # could modify arguments of real method call which will happen after this
81
+ # method returns new args and kwargs.
79
82
# E.g. loop over all arguments will be affected
80
- # since apply_defaults will add new entries which were skipped by method_signature.bind since they are omit and use default values
83
+ # since apply_defaults will add new entries which were skipped by
84
+ # method_signature.bind since they are omit and use default values
81
85
# --- >>>> commented out ---> self.method_bound_args.apply_defaults()
82
86
83
87
# NB:
84
- # loop over args_w_specified_values will skip the args where func value should be supplied and default func value is used.
85
- # purpose of the loop is to replace such func arg values with equivalent obj of class NestedCall which suppose to collect
86
- # call tracking information for visualization. so no such information will be collected for fund args where default value is used
88
+ # loop over args_w_specified_values will skip the args where func value
89
+ # should be supplied and default func value is used.
90
+ # purpose of the loop is to replace such func arg values with
91
+ # equivalent obj of class NestedCall which suppose to collect call
92
+ # tracking information for visualization. so no such information will
93
+ # be collected for fund args where default value is used
87
94
for arg_name in args_w_specified_values :
88
95
arg_value = self .method_bound_args .arguments .get (arg_name )
89
96
arg_kind = method_signature .parameters .get (arg_name ).kind
90
97
91
- #print(method_name, arg_name, arg_kind)
92
98
if arg_kind == inspect .Parameter .VAR_KEYWORD :
93
99
# case for lambda args of assign
94
100
updates_d = {}
95
101
for kwarg_name , kwarg_value in arg_value .items ():
96
102
if inspect .isfunction (kwarg_value ):
97
- # create empty nested call obj as placeholder for future results
103
+ # create empty nested call obj
104
+ # as placeholder for future results
98
105
new_kwarg_value = NestedCall (kwarg_name , kwarg_value )
99
106
updates_d [kwarg_name ] = new_kwarg_value
100
107
self .method_bound_args .arguments [arg_name ].update (updates_d )
101
108
102
109
self .build_args_l__ ()
103
-
110
+
104
111
new_args = self .method_bound_args .args
105
112
new_kwargs = self .method_bound_args .kwargs
106
-
107
- # NB: since apply_defaults is not called then no tracking of args with default values will take place
113
+
114
+ # NB: since apply_defaults is not called then no tracking of args
115
+ # with default values will take place
108
116
self .back .dump_rdf_method_call_in ()
109
117
110
118
return new_args , new_kwargs
@@ -114,14 +122,16 @@ def handle_end_method_call(self, ret):
114
122
return
115
123
116
124
if ret is None :
117
- raise Exception (f"method call of { self .method_name } returned None, can't use it chained method calls" )
118
-
125
+ msg = f"method call of { self .method_name } returned None,"
126
+ " can't use it chained method calls"
127
+ raise Exception (msg )
128
+
119
129
ret_obj_id , found = obj_tracking .get_tracking_obj (ret )
120
130
if found :
121
131
ret_obj_id .last_version_num += 1
122
132
123
133
# since we don't know was object state changed or not
124
134
# we create new object state and set it as last obj state in obj id
125
135
self .ret_obj_state = obj_utils .ObjState (ret , ret_obj_id )
126
-
136
+
127
137
self .back .dump_rdf_method_call_out ()
0 commit comments