Skip to content

Commit 4e2cab6

Browse files
committed
fix bug in element key identity
old children by key were being copied for elements. as a result we were attempting to delete elements more than once.
1 parent 03db150 commit 4e2cab6

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

src/idom/core/_fixed_jsonpatch.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""A patched version of jsonpatch
2+
3+
We need this because of: https://github.com/stefankoegl/python-json-patch/issues/138
4+
5+
The core of this patch is in `DiffBuilder._item_removed`. The rest is just boilerplate
6+
that's been copied over with little to no changes.
7+
"""
8+
9+
from jsonpatch import _ST_REMOVE
10+
from jsonpatch import DiffBuilder as _DiffBuilder
11+
from jsonpatch import JsonPatch as _JsonPatch
12+
from jsonpatch import JsonPointer, RemoveOperation, _path_join
13+
14+
15+
def apply_patch(doc, patch, in_place=False, pointer_cls=JsonPointer):
16+
if isinstance(patch, (str, bytes)):
17+
patch = JsonPatch.from_string(patch, pointer_cls=pointer_cls)
18+
else:
19+
patch = JsonPatch(patch, pointer_cls=pointer_cls)
20+
return patch.apply(doc, in_place)
21+
22+
23+
def make_patch(src, dst, pointer_cls=JsonPointer):
24+
return JsonPatch.from_diff(src, dst, pointer_cls=pointer_cls)
25+
26+
27+
class JsonPatch(_JsonPatch):
28+
@classmethod
29+
def from_diff(
30+
cls,
31+
src,
32+
dst,
33+
optimization=True,
34+
dumps=None,
35+
pointer_cls=JsonPointer,
36+
):
37+
json_dumper = dumps or cls.json_dumper
38+
builder = DiffBuilder(src, dst, json_dumper, pointer_cls=pointer_cls)
39+
builder._compare_values("", None, src, dst)
40+
ops = list(builder.execute())
41+
return cls(ops, pointer_cls=pointer_cls)
42+
43+
44+
class DiffBuilder(_DiffBuilder):
45+
def _item_removed(self, path, key, item):
46+
new_op = RemoveOperation(
47+
{
48+
"op": "remove",
49+
"path": _path_join(path, key),
50+
},
51+
pointer_cls=self.pointer_cls,
52+
)
53+
new_index = self.insert(new_op)
54+
self.store_index(item, new_index, _ST_REMOVE)

src/idom/core/dispatcher.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
from weakref import WeakSet
2020

2121
from anyio import create_task_group
22-
from jsonpatch import apply_patch, make_patch
2322

2423
from idom.utils import Ref
2524

25+
from ._fixed_jsonpatch import apply_patch, make_patch
2626
from .layout import LayoutEvent, LayoutUpdate
2727
from .proto import LayoutType, VdomJson
2828

src/idom/core/layout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ def _update_element_model_state(
538538
key=old_model_state.key,
539539
model=Ref(), # does not copy the model
540540
patch_path=old_model_state.patch_path,
541-
children_by_key=old_model_state.children_by_key.copy(),
541+
children_by_key={},
542542
targets_by_event={},
543543
)
544544

0 commit comments

Comments
 (0)