Skip to content

build(deps): hash-lock python dependencies - #105

Open
kcrmin wants to merge 5 commits into
developfrom
build/lock-python-dependencies
Open

kcrmin wants to merge 5 commits into
developfrom
build/lock-python-dependencies

Conversation

@kcrmin

@kcrmin kcrmin commented Oct 27, 2026

Copy link
Copy Markdown
Member

What and why

pyproject.toml pins the direct dependencies, but nothing pinned the transitive
set, so two image builds could ship different bytes. This adds hash-locked sets
from uv pip compile --universal --generate-hashes:

  • requirements/runtime.txt (31 packages): what the image ships
  • requirements/dev.txt (71 packages): runtime plus the test and dev extras

The Dockerfile installs runtime.txt wheels-only with --require-hashes, then
the project with --no-deps and pip check. Every CI gate installs from the
lock the same way. gate2 now fails when pyproject.toml and requirements/
drift (extras included, runtime pins equal in both files), and gate5 imports
the app from the runtime lock alone. DEVELOPMENT.md documents regeneration.

Depends on #103. This branch starts from it, so until #103 (and #102) merge the
diff also shows their two commits. Paired with the data-pipeline branch of the
same name, build/lock-python-dependencies. Related: #104.

Verified

  • Regenerating both files with uv 0.13.5 reproduces them exactly, header aside
  • python:3.12.13-slim-bookworm on linux/arm64 and linux/amd64 (QEMU): both
    locks install wheels-only with --require-hashes, pip check is clean, the
    gate2 lock check passes, and backtest_engine.api, .worker and
    .orchestrator import from the runtime lock alone
  • Native arm64 docker build --no-cache: builds, pip check clean; inside it,
    as user app, import backtest_engine.api, backtest_engine.worker works and
    perl stays purged
  • Gates 1-4 from requirements/dev.txt on linux/arm64: ruff clean; mypy no
    issues in 74 files; pytest 1415 passed, 6 skipped (CI on build(deps): cap sqlalchemy below 2.2 #103: 1414, plus the
    new Dockerfile test), coverage 77.62%; contract tests pass
  • macOS: the dev lock installs; pip check, the lock check, ruff and mypy pass
  • Drift fails: bumping pytest in pyproject.toml fails the gate2 lock check,
    bumping fastapi fails pip check
  • Merges cleanly with chore(ci): tidy backtest gates and macos skip #104, and coverage stays above its 77% floor

Checklist

SQLAlchemy 2.1 types Result with variadic generics, so mypy 2.3.0
reports var-annotated on bare scalar_one() assignments.
SQLAlchemy 2.1 retyped Result and broke the type gate, so the next
minor should be a deliberate bump. mypy stays pinned with data-pipeline.
runtime.txt pins what the image ships; dev.txt adds the test and dev
extras. DEVELOPMENT.md documents how to regenerate both.
Wheels only and hashes required, then the project with --no-deps and
pip check, so a drifted lock fails the build instead of shipping.
gate2 now fails when pyproject.toml and requirements/ drift, extras
included, and gate5 imports the app with the runtime lock alone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant