Source code for sqlatypemodel.mixin.state

from __future__ import annotations

import threading
import weakref
from typing import TYPE_CHECKING, Any, Generic, TypeVar

if TYPE_CHECKING:
    from sqlatypemodel.mixin.protocols import Trackable

T = TypeVar("T")


[docs] class MutableState(Generic[T]): """Immutable wrapper for parent references in the change tracking graph. This class acts as a hashable token representing the identity of a trackable object. It solves the 'unhashable parent' problem by holding a weak reference to the parent object, allowing any object (even unhashable ones like lists or unfreezed dataclasses) to participate in the parent tracking mechanism. Attributes: ref: A weak reference to the parent object. """ __slots__ = ("ref", "_lock", "__weakref__")
[docs] def __init__(self, obj: T) -> None: """Initialize the mutable state token. Args: obj: The parent object to create a weak reference for. """ self.ref: weakref.ReferenceType[T] = weakref.ref(obj) self._lock = threading.RLock()
[docs] def obj(self) -> T | None: """Return the parent object from the weak reference. This method fulfills the SQLAlchemy Mutable parent protocol, allowing this state token to be used directly in SQLAlchemy's `_parents` dictionary. Returns: The dereferenced parent object, or None if it has been collected. """ return self.ref()