Commit Graph
5 Commits
Author SHA1 Message Date
Elior Nataf LackritzandGitHub 36a505ac65 test(checkpoint-postgres,checkpoint-sqlite): run the conformance suite (#8537)
Depends on #8535

`libs/checkpoint-conformance/tests/` only validates `InMemorySaver`.
`checkpoint-sqlite` has had a `test_conformance_delta.py` for a while,
but it guards on `importorskip("langgraph.checkpoint.conformance")` and
the package was never in its test environment — so it has been skipping
silently every run. `checkpoint-postgres` had no runner at all.

Net effect: the shared checkpointer contract was effectively unenforced
everywhere except in-memory.

### Change

Adds `langgraph-checkpoint-conformance` to the `test` dependency group
of both packages, with a path source like the existing
`langgraph-checkpoint` entry. That alone is what makes sqlite's runner
start executing. Postgres gets the equivalent runner.

Both pass the `delta_channel_history` capability.

### Why it's stacked

Against `main`'s Postgres, the new runner fails:

```
Capability delta_channel_history failed:
  test_history_migration_plain_value_as_seed
```

That is exactly the bug #8535 fixes, and it had been failing unnoticed
precisely because nothing ran the suite there. So this is based on that
branch rather than `main` — the diff here is the one conformance commit,
and it will retarget once #8535 lands.

Reasonable to read that as the change justifying itself: the first thing
turning the suite on did was catch a real bug that had been sitting in
`main`.

### Verified

`checkpoint-postgres` 270 passed on PG 15 and 16, `checkpoint-sqlite`
118 passed, lint and `ty` clean in both. The `uv.lock` updates are the
conformance package entry only.

### Note

The sync `PostgresSaver` and `SqliteSaver` aren't covered — the
conformance harness reports every capability as `detected=False` for
them, so only the async savers are exercised. Pre-existing and not
addressed here, but worth knowing the coverage isn't total.
2026-08-07 09:39:20 -04:00
Elior Nataf LackritzandGitHub f22af6248c chore: enable RUF100 and clear unused noqa directives (#8546)
Follow-up to review on #8540, where a stale `# noqa: E402` slipped past
me and Sydney spotted it by eye. This turns on the rule that catches
that automatically.

`RUF100` flags a `noqa` that suppresses nothing. `sdk-py` already had it
through its blanket `RUF` selection; this adds it to the other seven
packages and clears what it finds.

### The 33 it flags, all autofixed

**Blanket `# noqa` on docstring-closing lines** (4, in
`checkpoint-postgres` and `checkpoint-sqlite`). `E501` is in
`lint.ignore` for those packages, so nothing was being suppressed:

```diff
-        """  # noqa
+        """
```

**`# noqa: F821` on `anext(aiter_)`** (2). Left over from Python 3.9
support. `anext` became a builtin in 3.10, which is the floor now, so
`F821` no longer fires:

```diff
-                    anext(aiter_),  # type: ignore[arg-type]  # noqa: F821
+                    anext(aiter_),  # type: ignore[arg-type]
```

**Suppressions naming rules the package does not enable** (27), across
`langgraph`, `prebuilt` and `checkpoint-sqlite`: `FBT001`, `FBT002`,
`TC002`, `BLE001`, `ANN001`, `ANN002`, `ANN003`, `E501`, `F401`. Mostly
copied between packages whose rule sets differ.

### One measurement note

If you check these numbers yourself, use `--extend-select`:

```
ruff check --select RUF100 .          # 81, misleading
ruff check --extend-select RUF100 .   # 33, real
```

With a bare `--select`, ruff treats every other rule as disabled, so
every suppression for another rule looks unused. I quoted 81 before
catching that.

### Verified

`checkpoint-sqlite` 118 passed, `prebuilt` 284 passed, `langgraph` 1968
passed, `checkpoint-postgres` 264 passed on PG 15 and 16. `make lint`
clean in every package.

Independent of #8540 and #8537, so it can land in any order.
2026-08-06 17:38:31 -04:00
Elior Nataf LackritzandGitHub 658541c496 chore(checkpoint-postgres,checkpoint-sqlite): enable PLC0415 lint rule (#8540)
Follow-up to review on #8537: turn on ruff's `PLC0415`
(`import-outside-top-level`) so deferred imports in tests stop
accumulating.

Scoped to `checkpoint-postgres` and `checkpoint-sqlite` rather than
repo-wide, because the sweep turns up three different things and only
one of them is a style problem.

### What the rule finds today

```
package                 tests   src    files
checkpoint                13     10      11
checkpoint-conformance     0     10       4
checkpoint-postgres        6      0       2
checkpoint-sqlite          9      0       3
langgraph                130     23      32
prebuilt                  14      3       7
cli                        9     14      10
sdk-py                   189     23      38
                        ────────────────────
                         370     83     107
```

453 violations across 107 files, and ruff has no autofix for this rule.

### Three categories, not one

**Style — hoist.** `checkpoint-sqlite/tests/test_store.py` deferred
`math`, `random`, `time`, `Counter` and `defaultdict` inside methods for
no reason.

**Deliberate — keep, annotate.**
`checkpoint-postgres/tests/test_async.py` defers behind
`pytest.importorskip("langgraph.channels.delta")` because langgraph core
is *not* a test dependency of that package. Hoisting would break the
skip. Those get `# noqa: PLC0415` and a comment.

**Redundant guard — hoist.**
`checkpoint-sqlite/tests/test_conformance_delta.py` deferred imports
only to get past its own `importorskip`. Imports move up; the
`aiosqlite` guard stays, since that dependency genuinely can be absent.

The second category is why I did not enable this everywhere in one go.
Most of the 83 source-level violations look like the same pattern —
optional-dependency handling and circular-import avoidance in
`jsonplus.py`, `embed.py`, `encrypted.py` and friends. Blanket-enabling
would mean `# noqa` on a lot of correct code, and each one wants an
owner's eye rather than a mechanical pass.

These two packages are clean to enforce today because both have **zero**
source-level violations.

### Suggested rollout for the rest

Either extend package by package as owners confirm which deferrals are
intentional, or enable everywhere at once with `per-file-ignores`
grandfathering the current 107 files so new code is blocked immediately
and the debt burns down. Happy to do either — the second is a smaller
diff but leaves a long ignore list.

### Verified

`checkpoint-sqlite` 118 passed, `checkpoint-postgres` 264 passed on PG
15 and 16, `make lint` clean in both.

One overlap worth flagging:
`checkpoint-sqlite/tests/test_conformance_delta.py` is also touched by
#8537. The change is identical in both, so it should merge cleanly
either way.
2026-08-05 21:23:28 -04:00
Quanzheng LongandGitHub fb6e5c2bce chore: remove keepset helper (#7745)
Comment follow up
2026-05-08 18:00:31 +00:00
398d6cc59d chore(langgraph): add guide/conformance for delta channel checkpointer (#7736)
## Summary

Add a user-facing design doc and `get_delta_channel_keepset` helper for
third-party `BaseCheckpointSaver` authors who need to support graphs
using `DeltaChannel`.

**Deliverables:**

1. ~~**`docs/delta-channel-checkpointer-guide.md`** — comprehensive
guide covering~~:
moved to docs repo

2. **`BaseCheckpointSaver.get_delta_channel_keepset` /
`aget_delta_channel_keepset`** — returns the minimum set of ancestor
`checkpoint_id`s that must survive deletion for a given head's
`DeltaChannel` reconstruction to remain intact. Enables safe `prune`
implementations without silently corrupting delta history.

3. **Docstring warnings** on `prune`, `aprune`, `delete_for_runs`,
`adelete_for_runs`, `copy_thread`, `acopy_thread` explaining the
DeltaChannel pitfall (silent data loss if ancestor writes/snapshots are
deleted).

4. **Three new conformance capabilities** in
`libs/checkpoint-conformance`:
- `delta_channel_history` — validates the `aget_delta_channel_history`
walk contract
   - `delta_channel_keepset` — validates the keep-set contract
- `delta_channel_reconstruction` — end-to-end round-trip (aput +
aput_writes + history + reconstruct)

## Test plan

- [x] `make format lint` passes in `libs/checkpoint`,
`libs/checkpoint-conformance`
- [x] All three new conformance capabilities pass against
`InMemorySaver`
- [x] Run conformance against SQLite saver 
- [x] Run conformance against Postgres saver

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 17:34:46 -07:00