11
11
strings , short_repr , numbers ,
12
12
np_ndarray , np_array_factory , numpy_dtypes , get_doc ,
13
13
not_found , numpy_dtype_string_to_type , dict_ ,
14
- Opcode , FlatDeltaRow , UnkownValueCode ,
14
+ Opcode , FlatDeltaRow , UnkownValueCode , FlatDataAction ,
15
+ OPCODE_TAG_TO_FLAT_DATA_ACTION ,
16
+ FLAT_DATA_ACTION_TO_OPCODE_TAG ,
15
17
)
16
18
from deepdiff .path import (
17
19
_path_to_elements , _get_nested_obj , _get_nested_obj_and_force ,
@@ -877,8 +879,33 @@ def dumps(self):
877
879
def to_dict (self ):
878
880
return dict (self .diff )
879
881
882
+ def _flatten_iterable_opcodes (self , _parse_path ):
883
+ """
884
+ Converts op_codes to FlatDeltaRows
885
+ """
886
+ result = []
887
+ for path , op_codes in self .diff ['_iterable_opcodes' ].items ():
888
+ for op_code in op_codes :
889
+ result .append (
890
+ FlatDeltaRow (
891
+ path = _parse_path (path ),
892
+ action = OPCODE_TAG_TO_FLAT_DATA_ACTION [op_code .tag ],
893
+ value = op_code .new_values ,
894
+ old_value = op_code .old_values ,
895
+ type = type (op_code .new_values ),
896
+ old_type = type (op_code .old_values ),
897
+ new_path = None ,
898
+ t1_from_index = op_code .t1_from_index ,
899
+ t1_to_index = op_code .t1_to_index ,
900
+ t2_from_index = op_code .t2_from_index ,
901
+ t2_to_index = op_code .t2_to_index ,
902
+
903
+ )
904
+ )
905
+ return result
906
+
880
907
@staticmethod
881
- def _get_flat_row (action , info , _parse_path , keys_and_funcs ):
908
+ def _get_flat_row (action , info , _parse_path , keys_and_funcs , report_type_changes = True ):
882
909
for path , details in info .items ():
883
910
row = {'path' : _parse_path (path ), 'action' : action }
884
911
for key , new_key , func in keys_and_funcs :
@@ -887,6 +914,11 @@ def _get_flat_row(action, info, _parse_path, keys_and_funcs):
887
914
row [new_key ] = func (details [key ])
888
915
else :
889
916
row [new_key ] = details [key ]
917
+ if report_type_changes :
918
+ if 'value' in row and 'type' not in row :
919
+ row ['type' ] = type (row ['value' ])
920
+ if 'old_value' in row and 'old_type' not in row :
921
+ row ['old_type' ] = type (row ['old_value' ])
890
922
yield FlatDeltaRow (** row )
891
923
892
924
@staticmethod
@@ -918,28 +950,44 @@ def _from_flat_dicts(flat_dict_list):
918
950
if action in FLATTENING_NEW_ACTION_MAP :
919
951
action = FLATTENING_NEW_ACTION_MAP [action ]
920
952
index = path .pop ()
921
- if action in {'attribute_added' , 'attribute_removed' }:
953
+ if action in {
954
+ FlatDataAction .attribute_added ,
955
+ FlatDataAction .attribute_removed ,
956
+ }:
922
957
root_element = ('root' , GETATTR )
923
958
else :
924
959
root_element = ('root' , GET )
925
- path_str = stringify_path (path , root_element = root_element ) # We need the string path
960
+ if isinstance (path , str ):
961
+ path_str = path
962
+ else :
963
+ path_str = stringify_path (path , root_element = root_element ) # We need the string path
926
964
if new_path and new_path != path :
927
965
new_path = stringify_path (new_path , root_element = root_element )
928
966
else :
929
967
new_path = None
930
968
if action not in result :
931
969
result [action ] = {}
932
- if action in {'iterable_items_added_at_indexes' , 'iterable_items_removed_at_indexes' }:
970
+ if action in {
971
+ 'iterable_items_added_at_indexes' ,
972
+ 'iterable_items_removed_at_indexes' ,
973
+ }:
933
974
if path_str not in result [action ]:
934
975
result [action ][path_str ] = {}
935
976
result [action ][path_str ][index ] = value
936
- elif action in {'set_item_added' , 'set_item_removed' }:
977
+ elif action in {
978
+ FlatDataAction .set_item_added ,
979
+ FlatDataAction .set_item_removed
980
+ }:
937
981
if path_str not in result [action ]:
938
982
result [action ][path_str ] = set ()
939
983
result [action ][path_str ].add (value )
940
984
elif action in {
941
- 'dictionary_item_added' , 'dictionary_item_removed' ,
942
- 'attribute_removed' , 'attribute_added' , 'iterable_item_added' , 'iterable_item_removed' ,
985
+ FlatDataAction .dictionary_item_added ,
986
+ FlatDataAction .dictionary_item_removed ,
987
+ FlatDataAction .attribute_removed ,
988
+ FlatDataAction .attribute_added ,
989
+ FlatDataAction .iterable_item_added ,
990
+ FlatDataAction .iterable_item_removed ,
943
991
}:
944
992
result [action ][path_str ] = value
945
993
elif action == 'values_changed' :
@@ -959,8 +1007,29 @@ def _from_flat_dicts(flat_dict_list):
959
1007
]:
960
1008
if elem_value != UnkownValueCode :
961
1009
result [action ][path_str ][elem ] = elem_value
962
- elif action == ' iterable_item_moved' :
1010
+ elif action == FlatDataAction . iterable_item_moved :
963
1011
result [action ][path_str ] = {'value' : value }
1012
+ elif action in {
1013
+ FlatDataAction .iterable_items_inserted ,
1014
+ FlatDataAction .iterable_items_deleted ,
1015
+ FlatDataAction .iterable_items_replaced ,
1016
+ FlatDataAction .iterable_items_equal ,
1017
+ }:
1018
+ if '_iterable_opcodes' not in result :
1019
+ result ['_iterable_opcodes' ] = {}
1020
+ if path_str not in result ['_iterable_opcodes' ]:
1021
+ result ['_iterable_opcodes' ][path_str ] = []
1022
+ result ['_iterable_opcodes' ][path_str ].append (
1023
+ Opcode (
1024
+ tag = FLAT_DATA_ACTION_TO_OPCODE_TAG [action ],
1025
+ t1_from_index = flat_dict .get ('t1_from_index' ),
1026
+ t1_to_index = flat_dict .get ('t1_to_index' ),
1027
+ t2_from_index = flat_dict .get ('t2_from_index' ),
1028
+ t2_to_index = flat_dict .get ('t2_to_index' ),
1029
+ new_values = flat_dict .get ('value' ),
1030
+ old_values = flat_dict .get ('old_value' ),
1031
+ )
1032
+ )
964
1033
if new_path :
965
1034
result [action ][path_str ]['new_path' ] = new_path
966
1035
@@ -1060,6 +1129,9 @@ def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) -
1060
1129
'iterable_items_removed_at_indexes' : 'unordered_iterable_item_removed' ,
1061
1130
}
1062
1131
for action , info in self .diff .items ():
1132
+ if action == '_iterable_opcodes' :
1133
+ result .extend (self ._flatten_iterable_opcodes (_parse_path = _parse_path ))
1134
+ continue
1063
1135
if action .startswith ('_' ):
1064
1136
continue
1065
1137
if action in FLATTENING_NEW_ACTION_MAP :
@@ -1072,12 +1144,20 @@ def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) -
1072
1144
path2 .append ((index , 'GET' ))
1073
1145
else :
1074
1146
path2 .append (index )
1075
- result .append (FlatDeltaRow (path = path2 , value = value , action = new_action ))
1147
+ if report_type_changes :
1148
+ row = FlatDeltaRow (path = path2 , value = value , action = new_action , type = type (value ))
1149
+ else :
1150
+ row = FlatDeltaRow (path = path2 , value = value , action = new_action )
1151
+ result .append (row )
1076
1152
elif action in {'set_item_added' , 'set_item_removed' }:
1077
1153
for path , values in info .items ():
1078
1154
path = _parse_path (path )
1079
1155
for value in values :
1080
- result .append (FlatDeltaRow (path = path , value = value , action = action ))
1156
+ if report_type_changes :
1157
+ row = FlatDeltaRow (path = path , value = value , action = action , type = type (value ))
1158
+ else :
1159
+ row = FlatDeltaRow (path = path , value = value , action = action )
1160
+ result .append (row )
1081
1161
elif action == 'dictionary_item_added' :
1082
1162
for path , value in info .items ():
1083
1163
path = _parse_path (path )
@@ -1092,14 +1172,22 @@ def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) -
1092
1172
elif isinstance (value , set ) and len (value ) == 1 :
1093
1173
value = value .pop ()
1094
1174
action = 'set_item_added'
1095
- result .append (FlatDeltaRow (path = path , value = value , action = action ))
1175
+ if report_type_changes :
1176
+ row = FlatDeltaRow (path = path , value = value , action = action , type = type (value ))
1177
+ else :
1178
+ row = FlatDeltaRow (path = path , value = value , action = action )
1179
+ result .append (row )
1096
1180
elif action in {
1097
1181
'dictionary_item_removed' , 'iterable_item_added' ,
1098
1182
'iterable_item_removed' , 'attribute_removed' , 'attribute_added'
1099
1183
}:
1100
1184
for path , value in info .items ():
1101
1185
path = _parse_path (path )
1102
- result .append (FlatDeltaRow (path = path , value = value , action = action ))
1186
+ if report_type_changes :
1187
+ row = FlatDeltaRow (path = path , value = value , action = action , type = type (value ))
1188
+ else :
1189
+ row = FlatDeltaRow (path = path , value = value , action = action )
1190
+ result .append (row )
1103
1191
elif action == 'type_changes' :
1104
1192
if not report_type_changes :
1105
1193
action = 'values_changed'
@@ -1109,16 +1197,16 @@ def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) -
1109
1197
info = info ,
1110
1198
_parse_path = _parse_path ,
1111
1199
keys_and_funcs = keys_and_funcs ,
1200
+ report_type_changes = report_type_changes ,
1112
1201
):
1113
1202
result .append (row )
1114
- elif action == '_iterable_opcodes' :
1115
- result .extend (self ._flatten_iterable_opcodes ())
1116
1203
else :
1117
1204
for row in self ._get_flat_row (
1118
1205
action = action ,
1119
1206
info = info ,
1120
1207
_parse_path = _parse_path ,
1121
1208
keys_and_funcs = keys_and_funcs ,
1209
+ report_type_changes = report_type_changes ,
1122
1210
):
1123
1211
result .append (row )
1124
1212
return result
0 commit comments