1+ def item_add (key , value ):
2+ return {
3+ 'action' : 'added' ,
4+ 'name' : key ,
5+ 'new_value' : value
6+ }
7+
8+
9+ def item_delete (key , value ):
10+ return {
11+ 'action' : 'deleted' ,
12+ 'name' : key ,
13+ 'old_value' : value
14+ }
15+
16+
17+ def items_unchanged (key , value ):
18+ return {
19+ 'action' : 'unchanged' ,
20+ 'name' : key ,
21+ 'value' : value
22+ }
23+
24+
25+ def items_modified (key , value1 , value2 ):
26+ return {
27+ 'action' : 'modified' ,
28+ 'name' : key ,
29+ 'new_value' : value2 ,
30+ 'old_value' : value1
31+ }
32+
33+
34+ def items_nested (key , value1 , value2 ):
35+ return {
36+ 'action' : 'nested' ,
37+ 'name' : key ,
38+ 'children' : find_diff (value1 , value2 )
39+ }
40+
41+
42+ def find_diff (data1 , data2 ):
43+ keys_union = data1 .keys () | data2 .keys ()
44+ keys_added = data2 .keys () - data1 .keys ()
45+ keys_deleted = data1 .keys () - data2 .keys ()
46+
47+ diff = []
48+
49+ for key in keys_union :
50+ value1 = data1 .get (key )
51+ value2 = data2 .get (key )
52+
53+ if key in keys_added :
54+ diff .append (item_add (key , value2 ))
55+ elif key in keys_deleted :
56+ diff .append (item_delete (key , value1 ))
57+ elif isinstance (value1 , dict ) and isinstance (value2 , dict ):
58+ diff .append (items_nested (key , value1 , value2 ))
59+ elif value1 != value2 :
60+ diff .append (items_modified (key , value1 , value2 ))
61+ else :
62+ diff .append (items_unchanged (key , value1 ))
63+
64+ sorted_diff = sorted (diff , key = lambda x : x ['name' ])
65+
66+ return sorted_diff
0 commit comments