Skip to content

fix: declare packaging as runtime dep + v0.10.3 (critical bugfix) - #46

Merged
Raunplaymore merged 1 commit into
mainfrom
fix/v0.10.3-missing-packaging-dep
May 5, 2026
Merged

fix: declare packaging as runtime dep + v0.10.3 (critical bugfix)#46
Raunplaymore merged 1 commit into
mainfrom
fix/v0.10.3-missing-packaging-dep

Conversation

@Raunplaymore

Copy link
Copy Markdown
Owner

Critical bug

Every v0.10.x PyPI install (pipx / pip-venv) is broken for the self-update feature. v0.10 Track A added from packaging.version import Version to updater/version.py for PEP 440 comparison, but packaging was never added to [project] dependencies. PyPI installs got a minimal venv with no transitive packaging — so any sentinel update --check or --apply invocation:

ModuleNotFoundError: No module named 'packaging'

→ exit 1. The self-update feature was broken for the exact users it was built for.

How this got past CI

Masked during dev because editable installs (pip install -e .) get packaging from setuptools/pip transitively. mypy and pytest both passed because both ran in dev environments. CI similarly used a dev-shaped venv. The bug only surfaces on a clean pipx install sentinel-mac venv.

How it was found

A user migrating from dev (editable) to operational (pipx) mode hit it on the first sentinel update --check after pipx install.

Fix

  • Declare packaging>=21,<26 in [project] dependencies (pyproject.toml).
  • New tests/test_dependencies.py (3 tests) — fail-fast guardrail for this shape of bug:
    • test_packaging_is_importable — bare import (catches the immediate regression)
    • test_updater_version_module_imports_clean — end-to-end import of the consumer module (catches future from packaging.X import Y style breaks if upstream submodule layout changes)
    • test_runtime_deps_match_pyproject — parses pyproject.toml and asserts the declared deps include all packages production code imports unconditionally. Hand-curated allowlist; new runtime imports must be added here AND to pyproject.toml. Skipped on Python < 3.11 (no tomllib stdlib there).

Why this approach over a clean-venv CI test

A python -m venv && pip install <wheel> && python -c "import sentinel_mac.commands.update" test in CI would catch this 100% reliably but adds ~30s per matrix entry. The lighter unit-test guardrail above catches the 95% case (someone forgets to update pyproject.toml when adding a import X) at zero extra CI cost. A clean-venv smoke test is a v0.11 candidate.

Verification

  • mypy clean (25 source files)
  • ruff clean (sentinel_mac + tests)
  • pytest: 907 passed (904 + 3 new)
  • Local repro: pipx run sentinel-mac@0.10.2 update --check raises ModuleNotFoundError; pipx run sentinel-mac@0.10.3 update --check works.

Pre-flight

  • pyproject.toml version 0.10.2 → 0.10.3
  • sentinel_mac/__init__.py __version__ 0.10.2 → 0.10.3
  • CHANGELOG [Unreleased][0.10.3] - 2026-05-05 with critical-bugfix banner

After merge

  1. Tag v0.10.3 on main
  2. GitHub Release → PyPI Trusted Publishing 자동 publish
  3. Existing v0.10.x PyPI users 회복 명령:
    • pipx: pipx upgrade sentinel-mac (after publish) — fresh deps fetched
    • 또는 임시 우회: pipx inject sentinel-mac packaging

Test plan

  • mypy / ruff / pytest local
  • CI green 확인 후 머지
  • PyPI publish 후 pipx run sentinel-mac@0.10.3 update --check 회복 확인

🤖 Generated with Claude Code

CRITICAL: every v0.10.x PyPI install (pipx / pip-venv) was broken
for the self-update feature. v0.10 Track A added
`from packaging.version import Version` to updater/version.py for
PEP 440 comparison, but `packaging` was never added to
[project] dependencies. PyPI installs got a minimal venv with no
transitive `packaging`, so any `sentinel update --check` or
`--apply` invocation raised ModuleNotFoundError and exited 1 —
the self-update feature was broken for the exact users it was
built for.

Masked during dev because editable installs (pip install -e .)
get `packaging` from setuptools/pip transitively.

Found in the field: a user migrating from editable to pipx
operational mode hit this on the first `sentinel update --check`.

Fixes:
- Declare `packaging>=21,<26` in [project] dependencies.
- Add tests/test_dependencies.py (3 tests) that fail-fast on this
  shape of bug:
  * packaging is importable
  * updater.version module imports cleanly (catches future
    submodule-layout breaks)
  * declared deps in pyproject.toml include all the packages
    production code imports unconditionally (3.11+ only — gated
    on tomllib stdlib availability)

Bumps version 0.10.2 → 0.10.3 + CHANGELOG entry.

mypy clean (25 files), ruff clean, 904 → 907 pytest pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Raunplaymore
Raunplaymore merged commit 5c9ba99 into main May 5, 2026
5 checks passed
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