This commit is contained in:
Sydney Runkle
2026-04-30 14:49:05 -04:00
parent 9361385084
commit 759eba7fd2
2 changed files with 22 additions and 6 deletions
@@ -40,6 +40,21 @@ PendingWrite = tuple[str, str, Any]
_DELTA_RECONSTRUCTION: threading.local = threading.local()
def _overwrite_types() -> tuple[type, ...]:
"""Return `(Overwrite,)` if `langgraph` is installed, else `()`.
`Overwrite` lives in `langgraph.types`, which this library does not depend
on; importing eagerly would also be circular. An empty tuple makes
`isinstance(x, overwrite_types)` safely return `False` when `langgraph` is
not installed — no `Overwrite` values can exist in that environment.
"""
try:
from langgraph.types import Overwrite # type: ignore[import-untyped]
except ImportError:
return ()
return (Overwrite,)
logger = logging.getLogger(__name__)
@@ -487,7 +502,7 @@ class BaseCheckpointSaver(Generic[V]):
# it only reads pending_writes). This breaks the recursion safely.
if getattr(_DELTA_RECONSTRUCTION, "active", False):
return []
from langgraph.types import Overwrite # type: ignore[import-untyped]
overwrite_types = _overwrite_types()
_DELTA_RECONSTRUCTION.active = True
try:
@@ -504,7 +519,7 @@ class BaseCheckpointSaver(Generic[V]):
if ch != channel:
continue
collected.append(value)
if isinstance(value, Overwrite):
if isinstance(value, overwrite_types):
collected.reverse()
return collected
collected.reverse()
@@ -516,7 +531,7 @@ class BaseCheckpointSaver(Generic[V]):
self, config: RunnableConfig, channel: str
) -> List[Any]: # noqa: UP006
"""Async version of get_channel_writes."""
from langgraph.types import Overwrite
overwrite_types = _overwrite_types()
if getattr(_DELTA_RECONSTRUCTION, "active", False):
return []
@@ -533,7 +548,7 @@ class BaseCheckpointSaver(Generic[V]):
if ch != channel:
continue
collected.append(value)
if isinstance(value, Overwrite):
if isinstance(value, overwrite_types):
collected.reverse()
return collected
collected.reverse()
@@ -23,6 +23,7 @@ from langgraph.checkpoint.base import (
CheckpointTuple,
DeltaChannelWrites,
SerializerProtocol,
_overwrite_types,
get_checkpoint_id,
get_checkpoint_metadata,
)
@@ -168,7 +169,7 @@ class InMemorySaver(
chain.append(current)
_, _, parent = entry
current = parent
from langgraph.types import Overwrite # type: ignore[import-untyped]
overwrite_types = _overwrite_types()
# Scan writes newest→oldest. Stop at the first `Overwrite` — it
# dominates all older history. Either from `snapshot_every` or from
@@ -185,7 +186,7 @@ class InMemorySaver(
continue
val = self.serde.loads_typed(serialized)
collected.append(val)
if isinstance(val, Overwrite):
if isinstance(val, overwrite_types):
collected.reverse()
return collected
collected.reverse()