from typing import Protocol, runtime_checkable, Optional, Dict, List, Self, NamedTuple, Iterable, TypedDict, Iterator from uuid import UUID import datetime as dt import errno type ObjectId = int | str | UUID class TroveError(Exception): """Base class for all Trove errors.""" class ErrorWithErrno(TroveError): """Raised when an error occurs with an errno.""" def __init__(self, error: int, *args): super().__init__(*args) self.errno = error class ErrorExists(ErrorWithErrno): """Raised when a note already exists.""" def __init__(self, *args): super().__init__(errno.EEXIST, *args) class ErrorNotFound(ErrorWithErrno): """Raised when a note is not found.""" def __init__(self, *args): super().__init__(errno.ENOENT, *args) class ErrorNotEmpty(ErrorWithErrno): """Raised when a directory is not empty.""" def __init__(self, *args): super().__init__(errno.ENOTEMPTY, *args) class ErrorBadType(TypeError): """Raised when an invalid type is encountered.""" ... class BadNoteType(TypeError): """Raised when an invalid note type is encountered.""" class TreeExists(RuntimeError): """Raised when a label already exists.""" class NoteNotFound(KeyError): """Raised when a note is not found.""" class OpenArguments(TypedDict): create: bool class TreeEntry(NamedTuple): name: str object_id: ObjectId DEFAULT_MIME = "application/octet-stream" @runtime_checkable class Note(Protocol): """ Protocol for a Note item. Represents access to an individual note's content and metadata. """ @property def object_id(self) -> ObjectId: """The unique identifier for this note.""" ... @property def mime(self) -> str: """The MIME type of the note's content.""" ... @property def readonly(self) -> bool: """Whether the note is read-only.""" ... @property def mtime(self) -> dt.datetime: """The last modification time of the note.""" ... def get_raw_metadata(self, key: str) -> Optional[bytes]: """Retrieve metadata value for the given key.""" ... def set_raw_metadata(self, key: str, value: bytes) -> None: """Set metadata value for the given key.""" ... def read_content(self) -> bytes: """Read the raw content of the note.""" ... def write_content(self, data:bytes) -> None: """Write the raw content of the note.""" ... def children(self) -> Iterator[TreeEntry]: """Get all children of this note.""" ... def child(self, name: str) -> 'Note': """Retrieve a child note by name.""" ... def new_child(self, name: str, mime: str, content: bytes | None, executable: bool, hidden: bool) -> 'Note': """Create a new child note.""" ... def rm_child(self, name: str, recurse: bool): """Remove a child note.""" ... def has_children(self) -> bool: """Check if note has children.""" return next(self.children(), None) is not None def new_child(note: Note, name: str, mime: str = DEFAULT_MIME, content: bytes | None = None, executable: bool = False, hidden: bool = False) -> Note: return note.new_child(name=name, mime=mime, content=content, executable=executable, hidden=hidden) @runtime_checkable class Tree(Protocol): def link(self, name: str, note: Note): """Link name to a given note.""" ... def unlink(self, name: str): """Remove name from the tree.""" ... def mkdir(self, name: str) -> Self: """Create a new Tree with the given name.""" ... def rmdir(self, name: str) -> None: """Remove a directory from the tree.""" ... def entries(self) -> Iterable[TreeEntry]: """Return all entries in the directory""" ... @runtime_checkable class TreeNote(Note, Tree, Protocol): """Tree Note""" @runtime_checkable class Trove(Protocol): """ Protocol for the Trove database API. Provides high-level access to notes and trees. """ def get_raw_note(self, note: ObjectId) -> Note: """Retrieve a note by a object id""" ... def move(self, src_parent: Note, src_name: str, dst_parent: Note, dst_name: str, overwrite: bool): """Move a child note to a new location.""" ... def create_blob(self, data: bytes | None = None) -> Note: """Create a new blob node at the given path with content""" ... def get_root(self) -> TreeNote: """Get Tree Node at the given path""" ...