diff options
author | Kenn Knowles <kenn@kennknowles.com> | 2016-10-04 20:55:03 -0700 |
---|---|---|
committer | Kenn Knowles <kenn@kennknowles.com> | 2016-10-04 20:55:03 -0700 |
commit | 270fcbf99cc5770fe545f12fa93d4930d3929481 (patch) | |
tree | 8025e26c243d348de38da28316d181584c633f2e /jsonpath_rw/jsonpath.py | |
parent | 1235defdb679bdf4f91ba408548b7ff3e27a6b1e (diff) | |
download | jsonpath-rw-270fcbf99cc5770fe545f12fa93d4930d3929481.tar.gz |
Add tests and fixes for update
Diffstat (limited to 'jsonpath_rw/jsonpath.py')
-rw-r--r-- | jsonpath_rw/jsonpath.py | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/jsonpath_rw/jsonpath.py b/jsonpath_rw/jsonpath.py index 395516e..93d7b81 100644 --- a/jsonpath_rw/jsonpath.py +++ b/jsonpath_rw/jsonpath.py @@ -26,7 +26,11 @@ class JSONPath(object): raise NotImplementedError() def update(self, data, val): - "Returns `data` with the specified path replaced by `val`" + """ + Returns `data` with the specified path replaced by `val`. Only updates + if the specified path exists. + """ + raise NotImplementedError() def child(self, child): @@ -340,8 +344,30 @@ class Descendants(JSONPath): return False def update(self, data, val): - for datum in self.left.find(data): - self.right.update(datum.value, val) + # Get all left matches into a list + left_matches = self.left.find(data) + if not isinstance(left_matches, list): + left_matches = [left_matches] + + def update_recursively(data): + # Update only mutable values corresponding to JSON types + if not (isinstance(data, list) or isinstance(data, dict)): + return + + self.right.update(data, val) + + # Manually do the * or [*] to avoid coercion and recurse just the right-hand pattern + if isinstance(data, list): + for i in range(0, len(data)): + update_recursively(data[i]) + + elif isinstance(data, dict): + for field in data.keys(): + update_recursively(data[field]) + + for submatch in left_matches: + update_recursively(submatch.value) + return data def __str__(self): @@ -432,7 +458,8 @@ class Fields(JSONPath): def update(self, data, val): for field in self.reified_fields(DatumInContext.wrap(data)): - data[field] = val + if field in data: + data[field] = val return data def __str__(self): @@ -466,7 +493,8 @@ class Index(JSONPath): return [] def update(self, data, val): - data[self.index] = val + if len(data) > self.index: + data[self.index] = val return data def __eq__(self, other): |