From a9ade08c71c817ebb9e9d627075e71e9820ee762 Mon Sep 17 00:00:00 2001 From: Thor Whalen <1906276+thorwhalen@users.noreply.github.com> Date: Tue, 22 Sep 2026 13:27:48 +0000 Subject: [PATCH] fix: route MongoBaseStore.persist_data through __setitem__, not the leaf persist_data was the one value-side method MongoBaseStore did not override, so it was delegated leaf-bound: it bypassed both _id_of_key and _data_of_obj and issued a whole-document replace_one(upsert=True) built from the outer (untransformed) object. On any store built with set_key_and_data_fields this silently destroyed every field not present in the outer shape and rewrote the document in the wrong shape. Add MongoBaseStore.persist_data alongside its six siblings (contains_value/iter_values/contains_item/iter_items/append/extend), routing through self[key] = data so the wrapper's own key/data transforms apply. key defaults to being inferred from data[ID] for backward compatibility. Closes #11 Co-Authored-By: Claude Sonnet 5 --- mongodol/base.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mongodol/base.py b/mongodol/base.py index 6aace6b..8a8523e 100644 --- a/mongodol/base.py +++ b/mongodol/base.py @@ -614,3 +614,18 @@ def append(self, v): def extend(self, values): """Forward ``extend`` to the wrapped store, transforming each value first.""" return self.store.extend(list(map(self._data_of_obj, values))) + + def persist_data(self, data, key=None): + """Write ``data`` under ``key``, through this wrapper's own ``__setitem__``. + + Unlike the leaf's ``persist_data`` (a thin ``{ID: data[ID]} -> data`` shortcut), + this routes through ``self[key] = data``, so it applies ``_id_of_key``/ + ``_data_of_obj`` instead of bypassing them (see i2mint/mongodol#11). + + ``key`` defaults to being inferred from ``data[ID]``, for backward compatibility + with the previous leaf-bound behaviour -- but that inference itself bypasses the + key codec, so pass ``key`` explicitly wherever the caller already knows it. + """ + if key is None: + key = self._key_of_id({ID: self._data_of_obj(data)[ID]}) + return self.__setitem__(key, data)