Skip to content

Keep .restore() method mutates state from caller #192

@smemsh

Description

@smemsh

I have found that previous state parameter passed as Keep .restore(state=oldstate) results in mutation of the passed object. I do not think the passed object should be mutated, because the new state is retrieved by .dump(), whereas the original object should be in caller's hands unchanged. I.e., the deepcopy() should be internal.

My application is to compare the before and after, writing a new backup file only if the nodes have changed (ignoring sortVersion, which changes by just reading notes). Then I'm outputting a diff and writing a new backup file.

I noticed that before and after .restore(), certain fields from the original state= object have changed, so there are always differences. In particular shareRequests field changes from [] to [False] and the same for labelIds. This happens for every node. However if I pass the state as .restore(state=deepcopy(oldstate)) then a later comparison between oldstate and .dump() result works properly.

Possibly also this diff should be applied, but I'm not certain about it because everything works as long as I make a deep copy:

--- node.py.bak 2026-03-31 08:23:30.416377547 -0700
+++ node.py     2026-04-01 12:41:25.498140216 -0700
@@ -1453,11 +1453,11 @@
         self._archived = raw.get("isArchived", False)
         self._pinned = raw.get("isPinned", False)
         self._title = raw.get("title", "")
-        self.labels.load(raw.get("labelIds", []))
+        self.labels.load(raw.get("labelIds", [False]))
 
         self.collaborators.load(
             raw.get("roleInfo", []),
-            raw.get("shareRequests", []),
+            raw.get("shareRequests", [False]),
         )
         self._moved = "moved" in raw

Those are the fields that are always reported as different, for every node, unless I do a deepcopy beforehand.

I'm curious to see if anyone has encountered this or has thoughts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions