Skip to content

Commit 2d930df

Browse files
committed
Use ABCs instead of list/dict, fixes #33
1 parent c2e0cfa commit 2d930df

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

jsonpatch.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
import json
4343
import sys
4444

45+
try:
46+
from collections.abc import MutableMapping, MutableSequence
47+
except ImportError:
48+
from collections import MutableMapping, MutableSequence
49+
4550
from jsonpointer import JsonPointer, JsonPointerException
4651

4752
# Will be parsed by setup.py to determine package metadata
@@ -283,10 +288,12 @@ def from_diff(cls, src, dst):
283288
def compare_values(path, value, other):
284289
if value == other:
285290
return
286-
if isinstance(value, dict) and isinstance(other, dict):
291+
if isinstance(value, MutableMapping) and \
292+
isinstance(other, MutableMapping):
287293
for operation in compare_dicts(path, value, other):
288294
yield operation
289-
elif isinstance(value, list) and isinstance(other, list):
295+
elif isinstance(value, MutableSequence) and \
296+
isinstance(other, MutableSequence):
290297
for operation in compare_lists(path, value, other):
291298
yield operation
292299
else:
@@ -409,7 +416,7 @@ def apply(self, obj):
409416

410417
subobj, part = self.pointer.to_last(obj)
411418

412-
if isinstance(subobj, list):
419+
if isinstance(subobj, MutableSequence):
413420
if part == '-':
414421
subobj.append(value) # pylint: disable=E1103
415422

@@ -419,7 +426,7 @@ def apply(self, obj):
419426
else:
420427
subobj.insert(part, value) # pylint: disable=E1103
421428

422-
elif isinstance(subobj, dict):
429+
elif isinstance(subobj, MutableMapping):
423430
if part is None:
424431
obj = value # we're replacing the root
425432
else:
@@ -446,11 +453,11 @@ def apply(self, obj):
446453
if part is None:
447454
return value
448455

449-
if isinstance(subobj, list):
456+
if isinstance(subobj, MutableSequence):
450457
if part > len(subobj) or part < 0:
451458
raise JsonPatchConflict("can't replace outside of list")
452459

453-
elif isinstance(subobj, dict):
460+
elif isinstance(subobj, MutableMapping):
454461
if not part in subobj:
455462
msg = "can't replace non-existent object '{0}'".format(part)
456463
raise JsonPatchConflict(msg)
@@ -477,7 +484,8 @@ def apply(self, obj):
477484
except (KeyError, IndexError) as ex:
478485
raise JsonPatchConflict(str(ex))
479486

480-
if isinstance(subobj, dict) and self.pointer.contains(from_ptr):
487+
if isinstance(subobj, MutableMapping) and \
488+
self.pointer.contains(from_ptr):
481489
raise JsonPatchConflict('Cannot move values into its own children')
482490

483491
obj = RemoveOperation({
@@ -651,15 +659,15 @@ def _compare_with_shift(path, src, dst, left, right, shift):
651659
652660
Yields JSON patch operations and list index shift.
653661
"""
654-
if isinstance(left, list):
662+
if isinstance(left, MutableSequence):
655663
for item, shift in _compare_with_shift(path, src, dst, *left,
656664
shift=shift):
657665
yield item, shift
658666
elif left is not None:
659667
for item, shift in _compare_left(path, src, left, shift):
660668
yield item, shift
661669

662-
if isinstance(right, list):
670+
if isinstance(right, MutableSequence):
663671
for item, shift in _compare_with_shift(path, src, dst, *right,
664672
shift=shift):
665673
yield item, shift
@@ -721,7 +729,8 @@ def _optimize(operations):
721729
add_remove = set(['add', 'remove'])
722730
for item in operations:
723731
# could we apply "move" optimization for dict values?
724-
hashable_value = not isinstance(item['value'], (dict, list))
732+
hashable_value = not isinstance(item['value'],
733+
(MutableMapping, MutableSequence))
725734
if item['path'] in ops_by_path:
726735
_optimize_using_replace(ops_by_path[item['path']], item)
727736
continue

0 commit comments

Comments
 (0)