Repository navigation
make install ignores pinned constraints, upgrades transitive deps unexpectedly #70
Description
Summary
make install upgrades transitive dependencies to their latest PyPI versions even when those packages are pinned in constraints.txt / constraints-mxdev.txt. Local venvs diverge from what CI builds (CI typically runs only make packages, which honors pins via -r requirements-mxdev.txt). This breaks reproducibility for projects that rely on pin discipline.
Affected topic templates
Several pip install recipes pass -U (or no constraints at all) instead of routing through -c <constraints-file>:
| File | Line | Command | Issue |
|---|---|---|---|
core/mxenv.mk |
170 | install -U pip setuptools wheel |
-U + no -c |
core/mxenv.mk |
172 | install -U $(MXDEV) $(MXMAKE) |
-U + no -c |
docs/sphinx.mk |
49 | install -U sphinx sphinx-autobuild $(DOCS_REQUIREMENTS) |
-U + no -c |
qa/coverage.mk |
25 | install -U coverage |
-U + no -c |
qa/ruff.mk |
53 | install ruff |
no -c (installs latest on first run) |
docs/sphinx.mk is the most damaging in practice. sphinx-autobuild declares starlette>=0.35, uvicorn>=0.25, websockets>=11, watchfiles>=0.20. These overlap with FastAPI/Starlette application dependencies. When the docs sentinel runs first in the install chain, it pulls these transitive deps to latest. The subsequent pip install -r requirements-mxdev.txt does not downgrade them: pip only honors -c during resolution, not retroactively for already-installed packages.
Reproduction
A FastAPI project with the relevant pins:
$ grep -E '^(starlette|uvicorn|websockets)==' constraints.txt
starlette==0.49.3
uvicorn==0.38.0
websockets==15.0.1
$ make install
...
+ starlette==1.0.0 # upgraded beyond pin
+ uvicorn==0.46.0 # upgraded beyond pin
+ websockets==16.0 # upgraded beyond pin
+ setuptools==82.0.1 # upgraded beyond pin (was 80.9.0)
+ wheel==0.46.3 # upgraded beyond pin (was 0.45.1)
+ ruff==0.15.11 # upgraded beyond pin (was 0.14.3)
Expected behavior
make install produces a venv whose pip freeze exactly matches the pinned constraints (modulo development sources installed editable).
Root cause
Two coupled problems in the topic templates:
-Uflag: forces upgrade to latest, overriding any pin.- No
-c <constraints>: pip doesn't apply project pins to transitive deps of stand-alone tools.
Proposed fix
For each pip install recipe in the topic templates, drop -U and pass -c $(MXDEV_CONSTRAINTS) (or whatever variable resolves to the active constraints file). For docs/sphinx.mk:
- @$(PYTHON_PACKAGE_COMMAND) install -U sphinx sphinx-autobuild $(DOCS_REQUIREMENTS)
+ @$(PYTHON_PACKAGE_COMMAND) install -c $(MXDEV_CONSTRAINTS) sphinx sphinx-autobuild $(DOCS_REQUIREMENTS)Caveat for core/mxenv.mk: this template runs before mxfiles generates constraints-mxdev.txt, so it would need either:
- a fallback to the un-rewritten
constraints.txtfrom the project root, or - a re-ordering so
mxfilesruns beforemxenvfor the bootstrap pip/setuptools install (with the chicken-and-egg of needing pip to run mxdev in the first place — likely solvable by usingpython -m pipdirectly).
Happy to send a PR if the maintainers agree on the approach.
Local workaround
Hand-patch the generated Makefile to add -c constraints.txt and drop -U on the offending lines. Survives until the next mxmake update.
Activity