@@ -306,9 +306,9 @@ def from_diff(cls, src, dst, optimization=True):
306
306
True
307
307
"""
308
308
309
- info = _compare_info ()
310
- _compare_values ('' , None , info , src , dst )
311
- ops = [ op for op in info .execute ()]
309
+ builder = DiffBuilder ()
310
+ builder . _compare_values ('' , None , src , dst )
311
+ ops = list ( builder .execute ())
312
312
return cls (ops )
313
313
314
314
def to_string (self ):
@@ -648,7 +648,7 @@ def apply(self, obj):
648
648
return obj
649
649
650
650
651
- class _compare_info (object ):
651
+ class DiffBuilder (object ):
652
652
653
653
def __init__ (self ):
654
654
self .index_storage = [{}, {}]
@@ -724,104 +724,104 @@ def execute(self):
724
724
yield curr [2 ].operation
725
725
curr = curr [1 ]
726
726
727
- def _path_join (path , key ):
728
- if key != None :
729
- return path + '/' + str (key ).replace ('~' , '~0' ).replace ('/' , '~1' )
730
- return path
731
-
732
- def _item_added (path , key , info , item ):
733
- index = info .take_index (item , _ST_REMOVE )
734
- if index != None :
735
- op = index [2 ]
736
- if type (op .key ) == int :
737
- for v in info .iter_from (index ):
738
- op .key = v ._on_undo_remove (op .path , op .key )
739
- info .remove (index )
740
- if op .location != _path_join (path , key ):
741
- new_op = MoveOperation ({
742
- 'op' : 'move' ,
743
- 'from' : op .location ,
727
+ def _item_added (self , path , key , item ):
728
+ index = self .take_index (item , _ST_REMOVE )
729
+ if index != None :
730
+ op = index [2 ]
731
+ if type (op .key ) == int :
732
+ for v in self .iter_from (index ):
733
+ op .key = v ._on_undo_remove (op .path , op .key )
734
+ self .remove (index )
735
+ if op .location != _path_join (path , key ):
736
+ new_op = MoveOperation ({
737
+ 'op' : 'move' ,
738
+ 'from' : op .location ,
739
+ 'path' : _path_join (path , key ),
740
+ })
741
+ self .insert (new_op )
742
+ else :
743
+ new_op = AddOperation ({
744
+ 'op' : 'add' ,
744
745
'path' : _path_join (path , key ),
746
+ 'value' : item ,
745
747
})
746
- info .insert (new_op )
747
- else :
748
- new_op = AddOperation ({
749
- 'op' : 'add' ,
748
+ new_index = self .insert (new_op )
749
+ self .store_index (item , new_index , _ST_ADD )
750
+
751
+ def _item_removed (self , path , key , item ):
752
+ new_op = RemoveOperation ({
753
+ 'op' : 'remove' ,
750
754
'path' : _path_join (path , key ),
751
755
'value' : item ,
752
756
})
753
- new_index = info .insert (new_op )
754
- info .store_index (item , new_index , _ST_ADD )
755
-
756
- def _item_removed (path , key , info , item ):
757
- new_op = RemoveOperation ({
758
- 'op' : 'remove' ,
759
- 'path' : _path_join (path , key ),
760
- 'value' : item ,
761
- })
762
- index = info .take_index (item , _ST_ADD )
763
- new_index = info .insert (new_op )
764
- if index != None :
765
- op = index [2 ]
766
- if type (op .key ) == int :
767
- for v in info .iter_from (index ):
768
- op .key = v ._on_undo_add (op .path , op .key )
769
- info .remove (index )
770
- if new_op .location != op .location :
771
- new_op = MoveOperation ({
772
- 'op' : 'move' ,
773
- 'from' : new_op .location ,
774
- 'path' : op .location ,
775
- })
776
- new_index [2 ] = new_op
757
+ index = self .take_index (item , _ST_ADD )
758
+ new_index = self .insert (new_op )
759
+ if index != None :
760
+ op = index [2 ]
761
+ if type (op .key ) == int :
762
+ for v in self .iter_from (index ):
763
+ op .key = v ._on_undo_add (op .path , op .key )
764
+ self .remove (index )
765
+ if new_op .location != op .location :
766
+ new_op = MoveOperation ({
767
+ 'op' : 'move' ,
768
+ 'from' : new_op .location ,
769
+ 'path' : op .location ,
770
+ })
771
+ new_index [2 ] = new_op
772
+ else :
773
+ self .remove (new_index )
777
774
else :
778
- info .remove (new_index )
779
- else :
780
- info .store_index (item , new_index , _ST_REMOVE )
781
-
782
- def _item_replaced (path , key , info , item ):
783
- info .insert (ReplaceOperation ({
784
- 'op' : 'replace' ,
785
- 'path' : _path_join (path , key ),
786
- 'value' : item ,
787
- }))
788
-
789
- def _compare_dicts (path , info , src , dst ):
790
- src_keys = _viewkeys (src )
791
- dst_keys = _viewkeys (dst )
792
- added_keys = dst_keys - src_keys
793
- removed_keys = src_keys - dst_keys
794
- for key in removed_keys :
795
- _item_removed (path , str (key ), info , src [key ])
796
- for key in added_keys :
797
- _item_added (path , str (key ), info , dst [key ])
798
- for key in src_keys & dst_keys :
799
- _compare_values (path , key , info , src [key ], dst [key ])
800
-
801
- def _compare_lists (path , info , src , dst ):
802
- len_src , len_dst = len (src ), len (dst )
803
- max_len = max (len_src , len_dst )
804
- min_len = min (len_src , len_dst )
805
- for key in _range (max_len ):
806
- if key < min_len :
807
- old , new = src [key ], dst [key ]
808
- if old == new :
809
- continue
810
- _item_removed (path , key , info , old )
811
- _item_added (path , key , info , new )
812
- elif len_src > len_dst :
813
- _item_removed (path , len_dst , info , src [key ])
775
+ self .store_index (item , new_index , _ST_REMOVE )
776
+
777
+ def _item_replaced (self , path , key , item ):
778
+ self .insert (ReplaceOperation ({
779
+ 'op' : 'replace' ,
780
+ 'path' : _path_join (path , key ),
781
+ 'value' : item ,
782
+ }))
783
+
784
+ def _compare_dicts (self , path , src , dst ):
785
+ src_keys = _viewkeys (src )
786
+ dst_keys = _viewkeys (dst )
787
+ added_keys = dst_keys - src_keys
788
+ removed_keys = src_keys - dst_keys
789
+ for key in removed_keys :
790
+ self ._item_removed (path , str (key ), src [key ])
791
+ for key in added_keys :
792
+ self ._item_added (path , str (key ), dst [key ])
793
+ for key in src_keys & dst_keys :
794
+ self ._compare_values (path , key , src [key ], dst [key ])
795
+
796
+ def _compare_lists (self , path , src , dst ):
797
+ len_src , len_dst = len (src ), len (dst )
798
+ max_len = max (len_src , len_dst )
799
+ min_len = min (len_src , len_dst )
800
+ for key in _range (max_len ):
801
+ if key < min_len :
802
+ old , new = src [key ], dst [key ]
803
+ if old == new :
804
+ continue
805
+ self ._item_removed (path , key , old )
806
+ self ._item_added (path , key , new )
807
+ elif len_src > len_dst :
808
+ self ._item_removed (path , len_dst , src [key ])
809
+ else :
810
+ self ._item_added (path , key , dst [key ])
811
+
812
+ def _compare_values (self , path , key , src , dst ):
813
+ if src == dst :
814
+ return
815
+ elif isinstance (src , dict ) and \
816
+ isinstance (dst , dict ):
817
+ self ._compare_dicts (_path_join (path , key ), src , dst )
818
+ elif isinstance (src , list ) and \
819
+ isinstance (dst , list ):
820
+ self ._compare_lists (_path_join (path , key ), src , dst )
814
821
else :
815
- _item_added (path , key , info , dst [key ])
816
-
817
- def _compare_values (path , key , info , src , dst ):
818
- if src == dst :
819
- return
820
- elif isinstance (src , dict ) and \
821
- isinstance (dst , dict ):
822
- _compare_dicts (_path_join (path , key ), info , src , dst )
823
- elif isinstance (src , list ) and \
824
- isinstance (dst , list ):
825
- _compare_lists (_path_join (path , key ), info , src , dst )
826
- else :
827
- _item_replaced (path , key , info , dst )
822
+ self ._item_replaced (path , key , dst )
823
+
824
+ def _path_join (path , key ):
825
+ if key != None :
826
+ return path + '/' + str (key ).replace ('~' , '~0' ).replace ('/' , '~1' )
827
+ return path
0 commit comments