Skip to content

Commit dafc528

Browse files
mokeyishmichaelmior
authored andcommitted
Add support for DatumInContext inplace updating
1 parent 13981ac commit dafc528

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

jsonpath_ng/jsonpath.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,20 @@ def wrap(cls, data):
102102
return cls(data)
103103

104104
def __init__(self, value, path: Optional[JSONPath]=None, context: Optional[DatumInContext]=None):
105-
self.value = value
105+
self.__value__ = value
106106
self.path = path or This()
107107
self.context = None if context is None else DatumInContext.wrap(context)
108108

109+
@property
110+
def value(self):
111+
return self.__value__
112+
113+
@value.setter
114+
def value(self, value):
115+
if self.context is not None and self.context.value is not None:
116+
self.path.update(self.context.value, value)
117+
self.__value__ = value
118+
109119
def in_context(self, context, path):
110120
context = DatumInContext.wrap(context)
111121

@@ -694,7 +704,7 @@ def _find_base(self, datum, create):
694704
for index in self.indices:
695705
# invalid indices do not crash, return [] instead
696706
if datum.value and len(datum.value) > index:
697-
rv += [DatumInContext(datum.value[index], path=self, context=datum)]
707+
rv += [DatumInContext(datum.value[index], path=Index(index), context=datum)]
698708
return rv
699709

700710
def update(self, data, val):

tests/test_jsonpath.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import copy
22

33
import pytest
4-
4+
from typing import Callable
55
from jsonpath_ng.ext.parser import parse as ext_parse
66
from jsonpath_ng.jsonpath import DatumInContext, Fields, Root, This
77
from jsonpath_ng.lexer import JsonPathLexerError
88
from jsonpath_ng.parser import parse as base_parse
9+
from jsonpath_ng import JSONPath
910

1011
from .helpers import assert_full_path_equality, assert_value_equality
1112

@@ -166,12 +167,26 @@ def test_datumincontext_in_context_nested():
166167
update_test_cases,
167168
)
168169
@parsers
169-
def test_update(parse, expression, data, update_value, expected_value):
170+
def test_update(parse: Callable[[str], JSONPath], expression: str, data, update_value, expected_value):
170171
data_copy = copy.deepcopy(data)
171172
update_value_copy = copy.deepcopy(update_value)
172173
result = parse(expression).update(data_copy, update_value_copy)
173174
assert result == expected_value
174175

176+
# inplace update testing
177+
data_copy2 = copy.deepcopy(data)
178+
update_value_copy2 = copy.deepcopy(update_value)
179+
datums = parse(expression).find(data_copy2)
180+
batch_update = isinstance(update_value, list) and len(datums) == len(update_value)
181+
for i, datum in enumerate(datums):
182+
if batch_update:
183+
datum.value = update_value_copy2[i]
184+
else:
185+
datum.value = update_value_copy2
186+
if isinstance(datum.full_path, (Root, This)): # when the type of `data` is str, int, float etc.
187+
data_copy2 = datum.value
188+
assert data_copy2 == expected_value
189+
175190

176191
find_test_cases = (
177192
#

0 commit comments

Comments
 (0)