json_db: fix StoredDict.__delitem__() to work similarly to .pop()
follow-up https://github.com/spesmilo/electrum/pull/10233 ("jsondb pointers")
This commit is contained in:
@@ -222,8 +222,11 @@ class StoredDict(dict, BaseStoredObject):
|
|||||||
@locked
|
@locked
|
||||||
def __delitem__(self, key: _FLEX_KEY) -> None:
|
def __delitem__(self, key: _FLEX_KEY) -> None:
|
||||||
assert isinstance(key, _FLEX_KEY), repr(key)
|
assert isinstance(key, _FLEX_KEY), repr(key)
|
||||||
|
r = self.get(key, None)
|
||||||
dict.__delitem__(self, key)
|
dict.__delitem__(self, key)
|
||||||
self.db_remove(key)
|
self.db_remove(key)
|
||||||
|
if isinstance(r, StoredDict):
|
||||||
|
r._parent = None
|
||||||
|
|
||||||
@locked
|
@locked
|
||||||
def pop(self, key: _FLEX_KEY, v=_RaiseKeyError) -> Any:
|
def pop(self, key: _FLEX_KEY, v=_RaiseKeyError) -> Any:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import contextlib
|
|||||||
import copy
|
import copy
|
||||||
import traceback
|
import traceback
|
||||||
import json
|
import json
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import jsonpatch
|
import jsonpatch
|
||||||
from jsonpatch import JsonPatchException
|
from jsonpatch import JsonPatchException
|
||||||
@@ -88,6 +89,16 @@ class TestJsonpatch(ElectrumTestCase):
|
|||||||
fail_if_leaking_secret(ctx)
|
fail_if_leaking_secret(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
def pop1_from_dict(d: dict, key: str) -> Any:
|
||||||
|
return d.pop(key)
|
||||||
|
|
||||||
|
|
||||||
|
def pop2_from_dict(d: dict, key: str) -> Any:
|
||||||
|
val = d[key]
|
||||||
|
del d[key]
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
class TestJsonDB(ElectrumTestCase):
|
class TestJsonDB(ElectrumTestCase):
|
||||||
|
|
||||||
async def test_jsonpatch_replace_after_remove(self):
|
async def test_jsonpatch_replace_after_remove(self):
|
||||||
@@ -109,31 +120,35 @@ class TestJsonDB(ElectrumTestCase):
|
|||||||
data = jpatch.apply(data)
|
data = jpatch.apply(data)
|
||||||
|
|
||||||
async def test_jsondb_replace_after_remove(self):
|
async def test_jsondb_replace_after_remove(self):
|
||||||
data = { 'a': {'b': {'c': 0}}, 'd': 3}
|
for pop_from_dict in [pop1_from_dict, pop2_from_dict]:
|
||||||
db = JsonDB(repr(data))
|
with self.subTest(pop_from_dict):
|
||||||
a = db.get_dict('a')
|
data = { 'a': {'b': {'c': 0}}, 'd': 3}
|
||||||
# remove
|
db = JsonDB(repr(data))
|
||||||
b = a.pop('b')
|
a = db.get_dict('a')
|
||||||
self.assertEqual(len(db.pending_changes), 1)
|
# remove
|
||||||
# replace item. this must not been written to db
|
b = pop_from_dict(a, 'b')
|
||||||
b['c'] = 42
|
self.assertEqual(len(db.pending_changes), 1)
|
||||||
self.assertEqual(len(db.pending_changes), 1)
|
# replace item. this must not been written to db
|
||||||
patches = json.loads('[' + ','.join(db.pending_changes) + ']')
|
b['c'] = 42
|
||||||
jpatch = jsonpatch.JsonPatch(patches)
|
self.assertEqual(len(db.pending_changes), 1)
|
||||||
data = jpatch.apply(data)
|
patches = json.loads('[' + ','.join(db.pending_changes) + ']')
|
||||||
self.assertEqual(data, {'a': {}, 'd': 3})
|
jpatch = jsonpatch.JsonPatch(patches)
|
||||||
|
data = jpatch.apply(data)
|
||||||
|
self.assertEqual(data, {'a': {}, 'd': 3})
|
||||||
|
|
||||||
async def test_jsondb_replace_after_remove_nested(self):
|
async def test_jsondb_replace_after_remove_nested(self):
|
||||||
data = { 'a': {'b': {'c': 0}}, 'd': 3}
|
for pop_from_dict in [pop1_from_dict, pop2_from_dict]:
|
||||||
db = JsonDB(repr(data))
|
with self.subTest(pop_from_dict):
|
||||||
# remove
|
data = { 'a': {'b': {'c': 0}}, 'd': 3}
|
||||||
a = db.data.pop('a')
|
db = JsonDB(repr(data))
|
||||||
self.assertEqual(len(db.pending_changes), 1)
|
# remove
|
||||||
b = a['b']
|
a = pop_from_dict(db.data, "a")
|
||||||
# replace item. this must not be written to db
|
self.assertEqual(len(db.pending_changes), 1)
|
||||||
b['c'] = 42
|
b = a['b']
|
||||||
self.assertEqual(len(db.pending_changes), 1)
|
# replace item. this must not be written to db
|
||||||
patches = json.loads('[' + ','.join(db.pending_changes) + ']')
|
b['c'] = 42
|
||||||
jpatch = jsonpatch.JsonPatch(patches)
|
self.assertEqual(len(db.pending_changes), 1)
|
||||||
data = jpatch.apply(data)
|
patches = json.loads('[' + ','.join(db.pending_changes) + ']')
|
||||||
self.assertEqual(data, {'d': 3})
|
jpatch = jsonpatch.JsonPatch(patches)
|
||||||
|
data = jpatch.apply(data)
|
||||||
|
self.assertEqual(data, {'d': 3})
|
||||||
|
|||||||
Reference in New Issue
Block a user