From bc7d43a9df18775df36cbaf1b8417109772fa298 Mon Sep 17 00:00:00 2001 From: Naascraft Date: Sun, 28 Oct 2018 13:12:45 +0100 Subject: [PATCH] WIP add methods set, create, setdefault --- jsonpath_rw/jsonpath.py | 114 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/jsonpath_rw/jsonpath.py b/jsonpath_rw/jsonpath.py index 146a960..3c8c504 100644 --- a/jsonpath_rw/jsonpath.py +++ b/jsonpath_rw/jsonpath.py @@ -25,12 +25,28 @@ def find(self, data): """ raise NotImplementedError() + def set(self, data, val, create_path=True): + """Sets `val` at the specified path in `data`. + + Will create the necessary path if `create_path` is true and `create` is + implemented. + """ + raise NotImplementedError() + + def create(self, data): + """Creates the specified path in `data`.""" + raise NotImplementedError() + + def setdefault(self, data, val, create_path=True): + """Equivalent to `set` if `find` does not return, else noop.""" + if not self.find(data): + self.set(data, val, create_path) + def update(self, data, val): """ Returns `data` with the specified path replaced by `val`. Only updates if the specified path exists. """ - raise NotImplementedError() def child(self, child): @@ -178,6 +194,25 @@ def find(self, data): else: return Root().find(data.context) + def set(self, data, val, create_path=True): + if not isinstance(data, DatumInContext): + raise NotImplementedError( + "Cannot set the root if not a `DatumInContext`." + ) + data.value = val + + def setdefault(self, data, val, create_path=True): + if not isinstance(data, DatumInContext): + raise NotImplementedError( + "Cannot set the root if not a `DatumInContext`." + ) + data.value = data.value or val + + def create(self, data): + raise NotImplementedError( + "Cannot create a root path: it always exists." + ) + def update(self, data, val): return val @@ -198,6 +233,27 @@ class This(JSONPath): def find(self, datum): return [DatumInContext.wrap(datum)] + def set(self, data, val, create_path=True): + if not isinstance(data, DatumInContext): + raise NotImplementedError( + "Cannot set %s if not a `DatumInContext`." % self + ) + data.value = val + + # NOTE: check how this updates the context and if we should worry + + def setdefault(self, data, val, create_path=True): + if not isinstance(data, DatumInContext): + raise NotImplementedError( + "Cannot set %s if not a `DatumInContext`." % self + ) + data.value = data.value or val + + def create(self, data): + raise NotImplementedError( + "Cannot create a '%r' path: it always exists." % self + ) + def update(self, data, val): return val @@ -231,6 +287,15 @@ def find(self, datum): if not isinstance(subdata, AutoIdForDatum) for submatch in self.right.find(subdata)] + def set(self, data, val, create_path=True): + pass + + def setdefault(self, data, val, create_path=True): + pass + + def create(self, data): + pass + def update(self, data, val): for datum in self.left.find(data): self.right.update(datum.value, val) @@ -283,6 +348,15 @@ def __init__(self, left, right): def find(self, data): return [subdata for subdata in self.left.find(data) if self.right.find(subdata)] + def set(self, data, val, create_path=True): + pass + + def setdefault(self, data, val, create_path=True): + pass + + def create(self, data): + pass + def update(self, data, val): for datum in self.find(data): datum.path.update(data, val) @@ -343,6 +417,15 @@ def match_recursively(datum): def is_singular(): return False + def set(self, data, val, create_path=True): + pass + + def setdefault(self, data, val, create_path=True): + pass + + def create(self, data): + pass + def update(self, data, val): # Get all left matches into a list left_matches = self.left.find(data) @@ -420,7 +503,7 @@ def find(self, data): class Fields(JSONPath): """ JSONPath referring to some field of the current object. - Concrete syntax ix comma-separated field names. + Concrete syntax is a comma-separated list of field names. WARNING: If '*' is any of the field names, then they will all be returned. @@ -456,6 +539,15 @@ def find(self, datum): for field_datum in [self.get_field_datum(datum, field) for field in self.reified_fields(datum)] if field_datum is not None] + def set(self, data, val, create_path=True): + pass + + def setdefault(self, data, val, create_path=True): + pass + + def create(self, data): + pass + def update(self, data, val): for field in self.reified_fields(DatumInContext.wrap(data)): if field in data: @@ -492,6 +584,15 @@ def find(self, datum): else: return [] + def set(self, data, val, create_path=True): + pass + + def setdefault(self, data, val, create_path=True): + pass + + def create(self, data): + pass + def update(self, data, val): if len(data) > self.index: data[self.index] = val @@ -547,6 +648,15 @@ def find(self, datum): else: return [DatumInContext(datum.value[i], path=Index(i), context=datum) for i in range(0, len(datum.value))[self.start:self.end:self.step]] + def set(self, data, val, create_path=True): + pass + + def setdefault(self, data, val, create_path=True): + pass + + def create(self, data): + pass + def update(self, data, val): for datum in self.find(data): datum.path.update(data, val)