What’s the best way to duplicate a Note class instance as a note is being added in the note_will_be_added hook? The following don’t work:
duplicate_note = Note(id=note.id, col=note.col), new notes don’t exist in the collection so note.load() fails.
duplicate_note = copy.deepcopy(note), fails as it tries to copy some rust backend link
The use case is that I’m modifying the note using values from the note in a sequence of operations, where each operation modifies the note. If I were to just use the same Note instance as the source there will occur undesired effects as the source data is modified during the process.
def duplicate_note(note: Note) -> Note:
"""
Duplicate a note by creating a new instance and copying the fields.
Using copy.deepcopy on a Note object does not work, and Note(id=note.id) does not
work on a new note (where id is 0), thus this utility function.
"""
new_note = Note(col=note.col, model=note.note_type())
# Copied code from notes.py _to_backend_note method
# the method calls hooks.note_will_flush(self) which is not desired here
# This code may break if the Note class changes in the future.
backend_note = notes_pb2.Note(
id=note.id,
guid=note.guid,
notetype_id=note.mid,
mtime_secs=note.mod,
usn=note.usn,
tags=note.tags,
fields=note.fields,
)
# Calling internal method that is not part of the public API, so this may break if the
# Note class changes in the future.
new_note._load_from_backend_note(backend_note)
return new_note
I’d like to know if there’s some method that’d be less likely to break in the future.
I’m wondering if adding a duplicate_note method to notes.py would actually be as simple as adding one new internal method that does the copying to notes_pb2.Note only and use that in the duplicate method (exactly as my function above does):
I’d be happy to accept a PR that handles this in __deepcopy__, by e.g. nulling out the backend handle prior to copying, then restoring it afterwards so both objects share it.