darnit-core imports packaging at runtime in two places without any package declaring it as a dependency:
packages/darnit/src/darnit/core/composition.py:363-364 -- SpecifierSet, Version, InvalidVersion
packages/darnit/src/darnit/config/framework_schema.py:1445 -- SpecifierSet
Neither is guarded. packages/darnit/pyproject.toml does not list packaging.
Why it works today
It resolves in the development environment by accident. uv pip show packaging reports:
Name: packaging
Version: 26.0
Required-by: pytest
That is a test dependency. A production install of darnit-core without pytest in the environment has no guarantee that packaging is importable.
The comment that documents the assumption is wrong
framework_schema.py:1443:
# Imported lazily; `packaging` is a transitive dep via setuptools
# and is already part of every Python install with pip available.
pip and setuptools both vendor their own copies of packaging (pip._vendor.packaging, setuptools._vendor). Neither guarantees an importable top-level packaging module. CLAUDE.md repeats the same claim in its Active Technologies entry for feature 013.
Impact
_validate_version_constraint_syntax raises ValueError on any exception, so a missing packaging surfaces there as "Invalid PEP 440 version_constraint" rather than as a missing dependency -- a misleading error for a plugin-composition config that is actually valid.
composition.py would raise ModuleNotFoundError outright.
Both paths only run when version_constraint is set, which is why this has not been reported.
Suggested fix
Declare packaging in packages/darnit/pyproject.toml and correct the comment. Feature 037 declares it in packages/darnit-reproducibility/pyproject.toml for its own use, which does not cover core's two call sites.
Found while implementing #429 (feature 037).
darnit-coreimportspackagingat runtime in two places without any package declaring it as a dependency:packages/darnit/src/darnit/core/composition.py:363-364--SpecifierSet,Version,InvalidVersionpackages/darnit/src/darnit/config/framework_schema.py:1445--SpecifierSetNeither is guarded.
packages/darnit/pyproject.tomldoes not listpackaging.Why it works today
It resolves in the development environment by accident.
uv pip show packagingreports:That is a test dependency. A production install of
darnit-corewithout pytest in the environment has no guarantee thatpackagingis importable.The comment that documents the assumption is wrong
framework_schema.py:1443:pip and setuptools both vendor their own copies of
packaging(pip._vendor.packaging,setuptools._vendor). Neither guarantees an importable top-levelpackagingmodule.CLAUDE.mdrepeats the same claim in its Active Technologies entry for feature 013.Impact
_validate_version_constraint_syntaxraisesValueErroron any exception, so a missingpackagingsurfaces there as "Invalid PEP 440 version_constraint" rather than as a missing dependency -- a misleading error for a plugin-composition config that is actually valid.composition.pywould raiseModuleNotFoundErroroutright.Both paths only run when
version_constraintis set, which is why this has not been reported.Suggested fix
Declare
packaginginpackages/darnit/pyproject.tomland correct the comment. Feature 037 declares it inpackages/darnit-reproducibility/pyproject.tomlfor its own use, which does not cover core's two call sites.Found while implementing #429 (feature 037).