Skip to content

Commit 9378a5a

Browse files
committed
Merge branch 'dev' of github.com:seperman/deepdiff into dev
2 parents c6fa94f + 3d389e6 commit 9378a5a

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

deepdiff/delta.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,16 +267,23 @@ def _do_iterable_item_added(self):
267267
def _do_dictionary_item_added(self):
268268
dictionary_item_added = self.diff.get('dictionary_item_added')
269269
if dictionary_item_added:
270-
self._do_item_added(dictionary_item_added)
270+
self._do_item_added(dictionary_item_added, sort=False)
271271

272272
def _do_attribute_added(self):
273273
attribute_added = self.diff.get('attribute_added')
274274
if attribute_added:
275275
self._do_item_added(attribute_added)
276276

277-
def _do_item_added(self, items):
278-
# sorting the items by their path so that the items with smaller index are applied first.
279-
for path, new_value in sorted(items.items(), key=lambda x: x[0]):
277+
def _do_item_added(self, items, sort=True):
278+
if sort:
279+
# sorting items by their path so that the items with smaller index
280+
# are applied first (unless `sort` is `False` so that order of
281+
# added items is retained, e.g. for dicts).
282+
items = sorted(items.items(), key=lambda x: x[0])
283+
else:
284+
items = items.items()
285+
286+
for path, new_value in items:
280287
elem_and_details = self._get_elements_and_details(path)
281288
if elem_and_details:
282289
elements, parent, parent_to_obj_elem, parent_to_obj_action, obj, elem, action = elem_and_details

deepdiff/diff.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -450,16 +450,16 @@ def _diff_dict(self,
450450
rel_class = DictRelationship
451451

452452
if self.ignore_private_variables:
453-
t1_keys = {key for key in t1 if not(isinstance(key, str) and key.startswith('__'))}
454-
t2_keys = {key for key in t2 if not(isinstance(key, str) and key.startswith('__'))}
453+
t1_keys = OrderedSet([key for key in t1 if not(isinstance(key, str) and key.startswith('__'))])
454+
t2_keys = OrderedSet([key for key in t2 if not(isinstance(key, str) and key.startswith('__'))])
455455
else:
456-
t1_keys = set(t1.keys())
457-
t2_keys = set(t2.keys())
456+
t1_keys = OrderedSet(t1.keys())
457+
t2_keys = OrderedSet(t2.keys())
458458
if self.ignore_string_type_changes or self.ignore_numeric_type_changes:
459459
t1_clean_to_keys = self._get_clean_to_keys_mapping(keys=t1_keys, level=level)
460460
t2_clean_to_keys = self._get_clean_to_keys_mapping(keys=t2_keys, level=level)
461-
t1_keys = set(t1_clean_to_keys.keys())
462-
t2_keys = set(t2_clean_to_keys.keys())
461+
t1_keys = OrderedSet(t1_clean_to_keys.keys())
462+
t2_keys = OrderedSet(t2_clean_to_keys.keys())
463463
else:
464464
t1_clean_to_keys = t2_clean_to_keys = None
465465

tests/test_delta.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,41 @@ def test_list_difference_delta_raises_error_if_prev_value_changed(self):
335335
delta2 = Delta(diff, verify_symmetry=False, raise_errors=True)
336336
assert t1 + delta2 == t2
337337

338+
def test_delta_dict_items_added_retain_order(self):
339+
t1 = {
340+
6: 6
341+
}
342+
343+
t2 = {
344+
6: 6,
345+
7: 7,
346+
3: 3,
347+
5: 5,
348+
2: 2,
349+
4: 4
350+
}
351+
352+
expected_delta_dict = {
353+
'dictionary_item_added': {
354+
'root[7]': 7,
355+
'root[3]': 3,
356+
'root[5]': 5,
357+
'root[2]': 2,
358+
'root[4]': 4
359+
}
360+
}
361+
362+
diff = DeepDiff(t1, t2)
363+
delta_dict = diff._to_delta_dict()
364+
assert expected_delta_dict == delta_dict
365+
delta = Delta(diff, verify_symmetry=False, raise_errors=True)
366+
367+
result = t1 + delta
368+
assert result == t2
369+
370+
assert list(result.keys()) == [6, 7, 3, 5, 2, 4]
371+
assert list(result.keys()) == list(t2.keys())
372+
338373

339374
picklalbe_obj_without_item = PicklableClass(11)
340375
del picklalbe_obj_without_item.item

0 commit comments

Comments
 (0)