In a requirements-*.in
file, at the top of the file, are lines with -c
and -r
flags followed by a requirements-*.in
file. Uses relative paths (ignoring URLs).
Say have docs/requirements-pip-tools.in
-r ../requirements/requirements-prod.in
-c ../requirements/requirements-pins-base.in
-c ../requirements/requirements-pins-cffi.in
...
The intent is compiling this would produce docs/requirements-pip-tool.txt
But there is confusion as to which flag to use. It’s non-obvious.
constraint
Subset of requirements features. Intended to restrict package versions. Does not necessarily (might not) install the package!
Does not support:
-
editable mode (-e)
-
extras (e.g. coverage[toml])
Personal preference
-
always organize requirements files in folder(s)
-
don’t prefix requirements files with
requirements-
, just doing it here -
DRY principle applies; split out constraints which are shared.
Requirements are literally the packages your project requires to run,down to a specific version if you wish.
Constraints specifies what version of a package to install IF the package is required by your requirements, or by transitive requirement (required by packages you require). If package is not required, the constraint is not used.
I tend to use requirements file to list direct dependencies of my project and their versions. Constraints is useful to pin down and transitive dependencies to make sure they’re not accidentally upgraded (repeatable builds) . Also if the 3rd party package drops a requirement you don’t have to worry that it’ll still be installed if it’s still on your constraints. It’ll simply not be installed.
Great explanation of the most important difference