42
42
import json
43
43
import sys
44
44
45
+ try :
46
+ from collections .abc import MutableMapping , MutableSequence
47
+ except ImportError :
48
+ from collections import MutableMapping , MutableSequence
49
+
45
50
from jsonpointer import JsonPointer , JsonPointerException
46
51
47
52
# Will be parsed by setup.py to determine package metadata
@@ -283,10 +288,12 @@ def from_diff(cls, src, dst):
283
288
def compare_values (path , value , other ):
284
289
if value == other :
285
290
return
286
- if isinstance (value , dict ) and isinstance (other , dict ):
291
+ if isinstance (value , MutableMapping ) and \
292
+ isinstance (other , MutableMapping ):
287
293
for operation in compare_dicts (path , value , other ):
288
294
yield operation
289
- elif isinstance (value , list ) and isinstance (other , list ):
295
+ elif isinstance (value , MutableSequence ) and \
296
+ isinstance (other , MutableSequence ):
290
297
for operation in compare_lists (path , value , other ):
291
298
yield operation
292
299
else :
@@ -409,7 +416,7 @@ def apply(self, obj):
409
416
410
417
subobj , part = self .pointer .to_last (obj )
411
418
412
- if isinstance (subobj , list ):
419
+ if isinstance (subobj , MutableSequence ):
413
420
if part == '-' :
414
421
subobj .append (value ) # pylint: disable=E1103
415
422
@@ -419,7 +426,7 @@ def apply(self, obj):
419
426
else :
420
427
subobj .insert (part , value ) # pylint: disable=E1103
421
428
422
- elif isinstance (subobj , dict ):
429
+ elif isinstance (subobj , MutableMapping ):
423
430
if part is None :
424
431
obj = value # we're replacing the root
425
432
else :
@@ -446,11 +453,11 @@ def apply(self, obj):
446
453
if part is None :
447
454
return value
448
455
449
- if isinstance (subobj , list ):
456
+ if isinstance (subobj , MutableSequence ):
450
457
if part > len (subobj ) or part < 0 :
451
458
raise JsonPatchConflict ("can't replace outside of list" )
452
459
453
- elif isinstance (subobj , dict ):
460
+ elif isinstance (subobj , MutableMapping ):
454
461
if not part in subobj :
455
462
msg = "can't replace non-existent object '{0}'" .format (part )
456
463
raise JsonPatchConflict (msg )
@@ -477,7 +484,8 @@ def apply(self, obj):
477
484
except (KeyError , IndexError ) as ex :
478
485
raise JsonPatchConflict (str (ex ))
479
486
480
- if isinstance (subobj , dict ) and self .pointer .contains (from_ptr ):
487
+ if isinstance (subobj , MutableMapping ) and \
488
+ self .pointer .contains (from_ptr ):
481
489
raise JsonPatchConflict ('Cannot move values into its own children' )
482
490
483
491
obj = RemoveOperation ({
@@ -651,15 +659,15 @@ def _compare_with_shift(path, src, dst, left, right, shift):
651
659
652
660
Yields JSON patch operations and list index shift.
653
661
"""
654
- if isinstance (left , list ):
662
+ if isinstance (left , MutableSequence ):
655
663
for item , shift in _compare_with_shift (path , src , dst , * left ,
656
664
shift = shift ):
657
665
yield item , shift
658
666
elif left is not None :
659
667
for item , shift in _compare_left (path , src , left , shift ):
660
668
yield item , shift
661
669
662
- if isinstance (right , list ):
670
+ if isinstance (right , MutableSequence ):
663
671
for item , shift in _compare_with_shift (path , src , dst , * right ,
664
672
shift = shift ):
665
673
yield item , shift
@@ -721,7 +729,8 @@ def _optimize(operations):
721
729
add_remove = set (['add' , 'remove' ])
722
730
for item in operations :
723
731
# 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 ))
725
734
if item ['path' ] in ops_by_path :
726
735
_optimize_using_replace (ops_by_path [item ['path' ]], item )
727
736
continue
0 commit comments