@@ -60,6 +60,10 @@ class JsonPatchException(Exception):
6060 """Base Json Patch exception"""
6161
6262
63+ class InvalidJsonPatch (JsonPatchException ):
64+ """ Raised if an invalid JSON Patch is created """
65+
66+
6367class JsonPatchConflict (JsonPatchException ):
6468 """Raised if patch could not be applied due to conflict situation such as:
6569 - attempt to add object key then it already exists;
@@ -341,15 +345,15 @@ def apply(self, obj, in_place=False):
341345
342346 def _get_operation (self , operation ):
343347 if 'op' not in operation :
344- raise JsonPatchException ("Operation does not contain 'op' member" )
348+ raise InvalidJsonPatch ("Operation does not contain 'op' member" )
345349
346350 op = operation ['op' ]
347351
348352 if not isinstance (op , basestring ):
349- raise JsonPatchException ("Operation must be a string" )
353+ raise InvalidJsonPatch ("Operation must be a string" )
350354
351355 if op not in self .operations :
352- raise JsonPatchException ("Unknown operation {0!r}" .format (op ))
356+ raise InvalidJsonPatch ("Unknown operation {0!r}" .format (op ))
353357
354358 cls = self .operations [op ]
355359 return cls (operation )
@@ -397,7 +401,12 @@ class AddOperation(PatchOperation):
397401 """Adds an object property or an array element."""
398402
399403 def apply (self , obj ):
400- value = self .operation ["value" ]
404+ try :
405+ value = self .operation ["value" ]
406+ except KeyError as ex :
407+ raise InvalidJsonPatch (
408+ "The operation does not contain a 'value' member" )
409+
401410 subobj , part = self .pointer .to_last (obj )
402411
403412 if isinstance (subobj , list ):
@@ -426,7 +435,12 @@ class ReplaceOperation(PatchOperation):
426435 """Replaces an object property or an array element by new value."""
427436
428437 def apply (self , obj ):
429- value = self .operation ["value" ]
438+ try :
439+ value = self .operation ["value" ]
440+ except KeyError as ex :
441+ raise InvalidJsonPatch (
442+ "The operation does not contain a 'value' member" )
443+
430444 subobj , part = self .pointer .to_last (obj )
431445
432446 if part is None :
@@ -451,15 +465,20 @@ class MoveOperation(PatchOperation):
451465 """Moves an object property or an array element to new location."""
452466
453467 def apply (self , obj ):
454- from_ptr = JsonPointer (self .operation ['from' ])
468+ try :
469+ from_ptr = JsonPointer (self .operation ['from' ])
470+ except KeyError as ex :
471+ raise InvalidJsonPatch (
472+ "The operation does not contain a 'from' member" )
473+
455474 subobj , part = from_ptr .to_last (obj )
456475 try :
457476 value = subobj [part ]
458477 except (KeyError , IndexError ) as ex :
459478 raise JsonPatchConflict (str (ex ))
460479
461480 if isinstance (subobj , dict ) and self .pointer .contains (from_ptr ):
462- raise JsonPatchException ('Cannot move values into its own children' )
481+ raise JsonPatchConflict ('Cannot move values into its own children' )
463482
464483 obj = RemoveOperation ({
465484 'op' : 'remove' ,
@@ -488,12 +507,16 @@ def apply(self, obj):
488507 except JsonPointerException as ex :
489508 raise JsonPatchTestFailed (str (ex ))
490509
491- if 'value' in self . operation :
510+ try :
492511 value = self .operation ['value' ]
493- if val != value :
494- msg = '{0} ({1}) is not equal to tested value {2} ({3})'
495- raise JsonPatchTestFailed (msg .format (val , type (val ),
496- value , type (value )))
512+ except KeyError as ex :
513+ raise InvalidJsonPatch (
514+ "The operation does not contain a 'value' member" )
515+
516+ if val != value :
517+ msg = '{0} ({1}) is not equal to tested value {2} ({3})'
518+ raise JsonPatchTestFailed (msg .format (val , type (val ),
519+ value , type (value )))
497520
498521 return obj
499522
@@ -502,7 +525,12 @@ class CopyOperation(PatchOperation):
502525 """ Copies an object property or an array element to a new location """
503526
504527 def apply (self , obj ):
505- from_ptr = JsonPointer (self .operation ['from' ])
528+ try :
529+ from_ptr = JsonPointer (self .operation ['from' ])
530+ except KeyError as ex :
531+ raise InvalidJsonPatch (
532+ "The operation does not contain a 'from' member" )
533+
506534 subobj , part = from_ptr .to_last (obj )
507535 try :
508536 value = copy .deepcopy (subobj [part ])
0 commit comments