4242import json
4343import sys
4444
45+ try :
46+ from collections .abc import MutableMapping , MutableSequence
47+ except ImportError :
48+ from collections import MutableMapping , MutableSequence
49+
4550from 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