summaryrefslogtreecommitdiff
path: root/jsonpatch.py
diff options
context:
space:
mode:
authorStefan Kögl <stefan@skoegl.net>2013-10-09 18:38:58 +0200
committerStefan Kögl <stefan@skoegl.net>2013-10-09 18:38:58 +0200
commitbd90a7a39d1307f78ad89103e960d249aafacacb (patch)
tree75dc4e2c365386973d9ccb3ad3cd6b6bc57f6219 /jsonpatch.py
parentc5a5b4864da5a71a2f35d9d59b1406f2241339c9 (diff)
downloadpython-json-patch-bd90a7a39d1307f78ad89103e960d249aafacacb.tar.gz
exception if patch has multiple "op"s
Diffstat (limited to 'jsonpatch.py')
-rw-r--r--jsonpatch.py21
1 files changed, 20 insertions, 1 deletions
diff --git a/jsonpatch.py b/jsonpatch.py
index bff1d50..7601248 100644
--- a/jsonpatch.py
+++ b/jsonpatch.py
@@ -43,6 +43,7 @@ __license__ = 'Modified BSD License'
import copy
import sys
import operator
+import collections
import json
@@ -70,6 +71,20 @@ class JsonPatchTestFailed(JsonPatchException, AssertionError):
""" A Test operation failed """
+def multidict(ordered_pairs):
+ """Convert duplicate keys values to lists."""
+ # read all values into lists
+ d = collections.defaultdict(list)
+ for k, v in ordered_pairs:
+ d[k].append(v)
+
+ # unpack lists that have only 1 item
+ for k, v in d.items():
+ if len(v) == 1:
+ d[k] = v[0]
+ return dict(d)
+
+
def apply_patch(doc, patch, in_place=False):
"""Apply list of patches to specified json document.
@@ -216,7 +231,7 @@ class JsonPatch(object):
:return: :class:`JsonPatch` instance.
"""
- patch = json.loads(patch_str)
+ patch = json.loads(patch_str, object_pairs_hook=multidict)
return cls(patch)
@classmethod
@@ -314,6 +329,10 @@ class JsonPatch(object):
raise JsonPatchException("Operation does not contain 'op' member")
op = operation['op']
+
+ if not isinstance(op, basestring):
+ raise JsonPatchException("Operation must be a string")
+
if op not in self.operations:
raise JsonPatchException("Unknown operation '%s'" % op)