Background
uv run pytest (the documented test command in CLAUDE.md) currently fails collection for any test whose target script imports a third-party dependency. The pytest environment resolves against pyproject.toml, but the scripts declare their dependencies only in their inline # /// script PEP 723 blocks, which apply to uv run <script>.py — not to uv run pytest. As a result, importing the script module at test-collection time raises ModuleNotFoundError. This blocks running the test suite and undermines the "tests import directly from the script module" pattern described in CLAUDE.md.
Existing Behavior
uv run pytest collects 9 items but errors on 3 test modules during import:
test_strava.py -> strava.py:21 import llm -> No module named 'llm'
test_llm_commit_message.py-> llm_commit_message.py:13 import openai -> No module named 'openai'
test_websters1913.py -> websters1913.py:18 from bs4 import ... -> No module named 'bs4'
Only tests whose scripts depend on already-present packages (e.g. requests for test_septa.py) collect successfully. The failure is pre-existing and independent of any single script; it stems from the split between PEP 723 inline deps and the pytest environment.
Files/docs involved:
- pyproject.toml (test config lives here: configfile: pyproject.toml, testpaths: .)
- Script modules: strava.py, llm_commit_message.py, websters1913.py (and any future script with external deps)
- CLAUDE.md (documents uv run pytest as the test command)
Acceptance Criteria
Approach
Add a dev dependency group in pyproject.toml that includes the third-party packages the tests need to import, then run tests against it.
[dependency-groups]
dev = [
"pytest",
"llm==0.31",
"stravalib==2.4",
"python-dotenv==1.0.1",
"openai",
"beautifulsoup4",
]
uv run pytest installs the dev group automatically. Pin versions to match each script's inline block to avoid behavioral drift.
Alternatives considered:
- Per-test uv run --with: invoke tests with explicit deps. Rejected — clumsy, must be repeated per script, easy to forget.
- pytest-forked / subprocess running each script via uv run: heavier, changes the test model away from direct imports.
- Keep as-is and document that only a subset of tests run. Rejected — leaves the documented command broken.
Note the duplication risk: inline blocks and the dev group list the same packages/versions in two places. Acceptable for a small repo; call it out in CLAUDE.md so future scripts get added to both.
References
Risks and Rollback
Low risk — changes are confined to pyproject.toml (test tooling); no script runtime behavior changes. Main risk is version drift between a script's inline deps and the dev group causing tests to exercise a different version than production. Rollback: revert the pyproject.toml change; the repo returns to today's state (3 collection errors), with no impact on uv run <script>.py.
Screenshots / Recordings
Before:
collected 9 items / 3 errors
ERROR test_llm_commit_message.py - No module named 'openai'
ERROR test_strava.py - No module named 'llm'
ERROR test_websters1913.py - No module named 'bs4'
!!! Interrupted: 3 errors during collection !!!
After (target):
collected N items
... (all modules collect; tests pass/fail on assertions only)
Background
uv run pytest (the documented test command in CLAUDE.md) currently fails collection for any test whose target script imports a third-party dependency. The pytest environment resolves against pyproject.toml, but the scripts declare their dependencies only in their inline # /// script PEP 723 blocks, which apply to uv run <script>.py — not to uv run pytest. As a result, importing the script module at test-collection time raises ModuleNotFoundError. This blocks running the test suite and undermines the "tests import directly from the script module" pattern described in CLAUDE.md.
Existing Behavior
uv run pytest collects 9 items but errors on 3 test modules during import:
test_strava.py -> strava.py:21 import llm -> No module named 'llm'
test_llm_commit_message.py-> llm_commit_message.py:13 import openai -> No module named 'openai'
test_websters1913.py -> websters1913.py:18 from bs4 import ... -> No module named 'bs4'
Only tests whose scripts depend on already-present packages (e.g. requests for test_septa.py) collect successfully. The failure is pre-existing and independent of any single script; it stems from the split between PEP 723 inline deps and the pytest environment.
Files/docs involved:
Acceptance Criteria
Approach
Add a dev dependency group in pyproject.toml that includes the third-party packages the tests need to import, then run tests against it.
[dependency-groups]
dev = [
"pytest",
"llm==0.31",
"stravalib==2.4",
"python-dotenv==1.0.1",
"openai",
"beautifulsoup4",
]
uv run pytest installs the dev group automatically. Pin versions to match each script's inline block to avoid behavioral drift.
Alternatives considered:
Note the duplication risk: inline blocks and the dev group list the same packages/versions in two places. Acceptable for a small repo; call it out in CLAUDE.md so future scripts get added to both.
References
Risks and Rollback
Low risk — changes are confined to pyproject.toml (test tooling); no script runtime behavior changes. Main risk is version drift between a script's inline deps and the dev group causing tests to exercise a different version than production. Rollback: revert the pyproject.toml change; the repo returns to today's state (3 collection errors), with no impact on uv run <script>.py.
Screenshots / Recordings
Before:
collected 9 items / 3 errors
ERROR test_llm_commit_message.py - No module named 'openai'
ERROR test_strava.py - No module named 'llm'
ERROR test_websters1913.py - No module named 'bs4'
!!! Interrupted: 3 errors during collection !!!
After (target):
collected N items
... (all modules collect; tests pass/fail on assertions only)