Files
langgraph/libs/checkpoint-sqlite/pyproject.toml
T
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

90 lines
1.9 KiB
TOML

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "langgraph-checkpoint-sqlite"
version = "3.1.1"
description = "Library with a SQLite implementation of LangGraph checkpoint saver."
authors = []
requires-python = ">=3.10"
readme = "README.md"
license = "MIT"
license-files = ['LICENSE']
dependencies = [
"langgraph-checkpoint>=4.1.0,<5.0.0",
"aiosqlite>=0.20",
"sqlite-vec>=0.1.6",
]
[project.urls]
Source = "https://github.com/langchain-ai/langgraph/tree/main/libs/checkpoint-sqlite"
Twitter = "https://x.com/langchain_oss"
Slack = "https://www.langchain.com/join-community"
Reddit = "https://www.reddit.com/r/LangChain/"
[dependency-groups]
test = [
"pytest",
"pytest-asyncio",
"pytest-mock",
"pytest-watcher",
"langgraph-checkpoint",
"pytest-retry>=1.7.0",
]
lint = [
"ruff",
"codespell",
"ty",
]
dev = [
{include-group = "test"},
{include-group = "lint"},
]
[tool.uv]
default-groups = ['dev']
[tool.uv.sources]
langgraph-checkpoint = { path = "../checkpoint", editable = true }
[tool.hatch.build.targets.wheel]
include = ["langgraph"]
[tool.pytest.ini_options]
addopts = "--strict-markers --strict-config --durations=5 -vv"
asyncio_mode = "auto"
[tool.ruff]
lint.select = [
"E", # pycodestyle
"F", # Pyflakes
"UP", # pyupgrade
"B", # flake8-bugbear
"I", # isort
"PLC0415", # import-outside-top-level
"UP", # pyupgrade
]
lint.ignore = ["E501", "B008"]
target-version = "py310"
[tool.ty.rules]
invalid-argument-type = "ignore"
invalid-assignment = "ignore"
invalid-key = "ignore"
invalid-method-override = "ignore"
invalid-return-type = "ignore"
invalid-yield = "ignore"
not-iterable = "ignore"
not-subscriptable = "ignore"
unused-type-ignore-comment = "ignore"
unresolved-attribute = "ignore"
unresolved-import = "ignore"
unsupported-operator = "ignore"
[tool.pytest-watcher]
now = true
delay = 0.1
runner_args = ["--ff", "-v", "--tb", "short"]
patterns = ["*.py"]