Skip to content

Commit dd1846f

Browse files
committed
try to report the child relationship params properly for both t1 and t2
1 parent 2063331 commit dd1846f

File tree

4 files changed

+185
-14
lines changed

4 files changed

+185
-14
lines changed

deepdiff/delta.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -963,13 +963,6 @@ def _from_flat_dicts(flat_dict_list):
963963

964964
return result
965965

966-
def _flatten_iterable_opcodes(self):
967-
result = []
968-
for path, opcodes in self.diff['_iterable_opcodes']:
969-
for opcode in opcodes:
970-
if opcode.tag == '':
971-
pass
972-
973966
def to_flat_dicts(self, include_action_in_path=False, report_type_changes=True) -> List[FlatDeltaRow]:
974967
"""
975968
Returns a flat list of actions that is easily machine readable.

deepdiff/diff.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -839,15 +839,19 @@ def _diff_by_forming_pairs_and_comparing_one_by_one(
839839
x,
840840
notpresent,
841841
child_relationship_class=child_relationship_class,
842-
child_relationship_param=i)
842+
child_relationship_param=i,
843+
child_relationship_param2=j,
844+
)
843845
self._report_result('iterable_item_removed', change_level, local_tree=local_tree)
844846

845847
elif x is ListItemRemovedOrAdded: # new item added
846848
change_level = level.branch_deeper(
847849
notpresent,
848850
y,
849851
child_relationship_class=child_relationship_class,
850-
child_relationship_param=j)
852+
child_relationship_param=i,
853+
child_relationship_param2=j,
854+
)
851855
self._report_result('iterable_item_added', change_level, local_tree=local_tree)
852856

853857
else: # check if item value has changed
@@ -898,8 +902,8 @@ def _diff_by_forming_pairs_and_comparing_one_by_one(
898902
x,
899903
y,
900904
child_relationship_class=child_relationship_class,
901-
child_relationship_param=i
902-
# child_relationship_param=j # wrong
905+
child_relationship_param=i,
906+
child_relationship_param2=j,
903907
)
904908
self._diff(next_level, parents_ids_added, local_tree=local_tree)
905909

@@ -1339,11 +1343,14 @@ def get_other_pair(hash_value, in_t1=True):
13391343
other = get_other_pair(hash_value)
13401344
item_id = id(other.item)
13411345
index = t2_hashtable[hash_value].indexes[0] if other.item is notpresent else other.indexes[0]
1346+
index2 = t2_hashtable[hash_value].indexes[0]
13421347
change_level = level.branch_deeper(
13431348
other.item,
13441349
t2_hashtable[hash_value].item,
13451350
child_relationship_class=SubscriptableIterableRelationship,
1346-
child_relationship_param=index)
1351+
child_relationship_param=index,
1352+
child_relationship_param2=index2,
1353+
)
13471354
if other.item is notpresent:
13481355
self._report_result('iterable_item_added', change_level, local_tree=local_tree)
13491356
else:
@@ -1355,12 +1362,15 @@ def get_other_pair(hash_value, in_t1=True):
13551362
return # pragma: no cover. This is already covered for addition.
13561363
other = get_other_pair(hash_value, in_t1=False)
13571364
item_id = id(other.item)
1365+
index = t1_hashtable[hash_value].indexes[0]
1366+
index2 = t1_hashtable[hash_value].indexes[0] if other.item is notpresent else other.indexes[0]
13581367
change_level = level.branch_deeper(
13591368
t1_hashtable[hash_value].item,
13601369
other.item,
13611370
child_relationship_class=SubscriptableIterableRelationship,
1362-
child_relationship_param=t1_hashtable[hash_value].indexes[
1363-
0])
1371+
child_relationship_param=index,
1372+
child_relationship_param2=index2,
1373+
)
13641374
if other.item is notpresent:
13651375
self._report_result('iterable_item_removed', change_level, local_tree=local_tree)
13661376
else:

tests/test_delta.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,3 +2394,100 @@ def test_delta_flat_rows(self):
23942394
# the path to the leaf node.
23952395
delta2 = Delta(flat_rows_list=flat_rows, bidirectional=True, force=True)
23962396
assert t1 + delta2 == t2
2397+
2398+
def test_flat_dict_and_deeply_nested_dict(self):
2399+
beforeImage = [
2400+
{
2401+
"usage": "Mailing",
2402+
"standardization": "YES",
2403+
"primaryIndicator": True,
2404+
"addressIdentifier": "Z8PDWBG42YC",
2405+
"addressLines": ["871 PHILLIPS FERRY RD"],
2406+
},
2407+
{
2408+
"usage": "Residence",
2409+
"standardization": "YES",
2410+
"primaryIndicator": False,
2411+
"addressIdentifier": "Z8PDWBG42YC",
2412+
"addressLines": ["871 PHILLIPS FERRY RD"],
2413+
},
2414+
{
2415+
"usage": "Mailing",
2416+
"standardization": None,
2417+
"primaryIndicator": False,
2418+
"addressIdentifier": "MHPP3BY0BYC",
2419+
"addressLines": ["871 PHILLIPS FERRY RD", "APT RV92"],
2420+
},
2421+
]
2422+
allAfterImage = [
2423+
{
2424+
"usage": "Residence",
2425+
"standardization": "NO",
2426+
"primaryIndicator": False,
2427+
"addressIdentifier": "Z8PDWBG42YC",
2428+
"addressLines": ["871 PHILLIPS FERRY RD"],
2429+
},
2430+
{
2431+
"usage": "Mailing",
2432+
"standardization": None,
2433+
"primaryIndicator": False,
2434+
"addressIdentifier": "MHPP3BY0BYC",
2435+
"addressLines": ["871 PHILLIPS FERRY RD", "APT RV92"],
2436+
},
2437+
{
2438+
"usage": "Mailing",
2439+
"standardization": "NO",
2440+
"primaryIndicator": True,
2441+
"addressIdentifier": "Z8PDWBG42YC",
2442+
"addressLines": ["871 PHILLIPS FERRY RD"],
2443+
},
2444+
]
2445+
2446+
diff = DeepDiff(
2447+
beforeImage,
2448+
allAfterImage,
2449+
ignore_order=True,
2450+
report_repetition=True,
2451+
)
2452+
reverse_diff = DeepDiff(
2453+
allAfterImage,
2454+
beforeImage,
2455+
ignore_order=True,
2456+
report_repetition=True,
2457+
)
2458+
delta = Delta(
2459+
diff, always_include_values=True, bidirectional=True
2460+
)
2461+
reverse_delta = Delta(
2462+
reverse_diff, always_include_values=True, bidirectional=True
2463+
)
2464+
allAfterImageAgain = beforeImage + delta
2465+
diff2 = DeepDiff(allAfterImage, allAfterImageAgain, ignore_order=True)
2466+
assert not diff2
2467+
2468+
from pprint import pprint
2469+
print("\ndelta.diff")
2470+
pprint(delta.diff)
2471+
print("\ndelta._get_reverse_diff()")
2472+
pprint(delta._get_reverse_diff())
2473+
print("\nreverse_delta.diff")
2474+
pprint(reverse_delta.diff)
2475+
# import pytest; pytest.set_trace()
2476+
beforeImageAgain = allAfterImage - delta
2477+
diff3 = DeepDiff(beforeImage, beforeImageAgain, ignore_order=True)
2478+
assert not diff3
2479+
2480+
# ------ now let's recreate the delta from flat dicts -------
2481+
2482+
flat_dict_list = delta.to_flat_dicts()
2483+
2484+
delta2 = Delta(
2485+
flat_dict_list=flat_dict_list,
2486+
always_include_values=True,
2487+
bidirectional=True,
2488+
raise_errors=False,
2489+
force=True,
2490+
)
2491+
2492+
assert allAfterImage == beforeImage + delta2
2493+
assert beforeImage == allAfterImage - delta2

tests/test_model.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import pytest
55
from tests import CustomClass, CustomClassMisleadingRepr
6+
from deepdiff import DeepDiff
67
from deepdiff.model import (DiffLevel, ChildRelationship, DictRelationship,
78
SubscriptableIterableRelationship,
89
AttributeRelationship)
@@ -170,6 +171,76 @@ def test_path_when_both_children_empty(self):
170171
assert path == 'root'
171172
assert down.path(output_format='list') == []
172173

174+
def test_t2_path_when_nested(self):
175+
t1 = {
176+
"type": "struct",
177+
"fields": [
178+
{"name": "Competition", "metadata": {}, "nullable": True, "type": "string"},
179+
{"name": "TeamName", "metadata": {}, "nullable": True, "type": "string"},
180+
{
181+
"name": "Contents",
182+
"metadata": {},
183+
"nullable": True,
184+
"type": {
185+
"type": "struct",
186+
"fields": [
187+
{"name": "Date", "metadata": {}, "nullable": True, "type": "string"},
188+
{"name": "Player1", "metadata": {}, "nullable": True, "type": "string"}
189+
]
190+
}
191+
}
192+
]
193+
}
194+
195+
t2 = {
196+
"type": "struct",
197+
"fields": [
198+
{"name": "Competition", "metadata": {}, "nullable": True, "type": "string"},
199+
{"name": "GlobalId", "metadata": {}, "nullable": True, "type": "string"},
200+
{"name": "TeamName", "metadata": {}, "nullable": True, "type": "string"},
201+
{
202+
"name": "Contents",
203+
"metadata": {},
204+
"nullable": True,
205+
"type": {
206+
"type": "struct",
207+
"fields": [
208+
{"name": "Date", "metadata": {}, "nullable": True, "type": "string"},
209+
{"name": "Player1", "metadata": {}, "nullable": True, "type": "string"},
210+
{"name": "Player2", "metadata": {}, "nullable": True, "type": "string"}
211+
]
212+
}
213+
}
214+
]
215+
}
216+
217+
diff = DeepDiff(t1=t1, t2=t2, ignore_order=True, verbose_level=2, view='tree')
218+
219+
expected_diff = {
220+
"iterable_item_added": {
221+
"root['fields'][1]": {
222+
"name": "GlobalId",
223+
"metadata": {},
224+
"nullable": True,
225+
"type": "string",
226+
},
227+
"root['fields'][2]['type']['fields'][2]": {
228+
"name": "Player2",
229+
"metadata": {},
230+
"nullable": True,
231+
"type": "string",
232+
},
233+
}
234+
}
235+
236+
path = diff['iterable_item_added'][1].path()
237+
assert "root['fields'][2]['type']['fields'][2]" == path
238+
239+
path_t2 = diff['iterable_item_added'][1].path(use_t2=True)
240+
assert "root['fields'][3]['type']['fields'][2]" == path_t2
241+
242+
243+
173244
def test_repr_short(self):
174245
level = self.lowest.verbose_level
175246
try:

0 commit comments

Comments
 (0)