I recommend using pip-compile
. This is a tool that will take a requirements.in
file with a ranged specifiers, and “compile” them into a requirements.txt
that uses exact pinned version numbers (==
).
For example, you can write in your requirements.in
just:
django>=3.2,<4.0
Then compile it with:
$ pip-compile
...
And your resulting requirements.txt
will contain (with current version numbers):
#
# This file is autogenerated by pip-compile with python 3.9
# To update, run:
#
# pip-compile
#
asgiref==3.4.1
# via django
django==3.2.9
# via -r requirements.in
pytz==2021.3
# via django
sqlparse==0.4.2
# via django
You can later upgrade everything with pip-compile -U
.
This will make it a lot easier to keep your versions pinned, but updated. It also solves problems with unpinned/added/removed transitive dependencies (the dependencies of your dependencies).
Hope that helps!
(I’m writing a whole section on pip-compile in my upcoming Django development experience book.)