diff --git a/jsonpatch.py b/jsonpatch.py index d3fc26d..df6e3c1 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -797,7 +797,8 @@ def _item_added(self, path, key, item): index = self.take_index(item, _ST_REMOVE) if index is not None: op = index[2] - if type(op.key) == int and type(key) == int: + parent_collection = op.pointer.to_last(self.dst_doc)[0] + if isinstance(parent_collection, MutableSequence): for v in self.iter_from(index): op.key = v._on_undo_remove(op.path, op.key) @@ -827,12 +828,8 @@ def _item_removed(self, path, key, item): new_index = self.insert(new_op) if index is not None: op = index[2] - # We can't rely on the op.key type since PatchOperation casts - # the .key property to int and this path wrongly ends up being taken - # for numeric string dict keys while the intention is to only handle lists. - # So we do an explicit check on the item affected by the op instead. - added_item = op.pointer.to_last(self.dst_doc)[0] - if type(added_item) == list: + parent_collection = op.pointer.to_last(self.dst_doc)[0] + if isinstance(parent_collection, MutableSequence): for v in self.iter_from(index): op.key = v._on_undo_add(op.path, op.key) diff --git a/tests.py b/tests.py index d9eea92..32239dc 100755 --- a/tests.py +++ b/tests.py @@ -566,6 +566,14 @@ def test_issue120(self): res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst) + def test_issue_160(self): + """Removal of an operation to an array should trigger _on_undo_add.""" + old = {'a': [{'id': [1]}, {'id': [2]}], 'b': [{'id': 5}]} + new = {'a': [{'id': []}, {'id': [1]}], 'b': [{'id': 5, 'newKey': 2}]} + patch = jsonpatch.make_patch(old, new) + result = jsonpatch.apply_patch(old, patch) + self.assertEqual(result, new) + def test_custom_types_diff(self): old = {'value': decimal.Decimal('1.0')} new = {'value': decimal.Decimal('1.00')}