Is there a generally accepted strategy for keeping all modules in the environment updated?

With something like Anaconda matters are fairly simple, but if you’re “rolling your own” environment from vanilla python it’s a more complicated question. There are a number of commands I saw, like pipreview, pip-upgrade, and pip list --outdated. Is this still up for debate, or have people settled on a solution?

By Theycallmevirgo via Discussions on Python.org at 24Sep2022 21:59:

With something like Anaconda matters are fairly simple, but if you’re
“rolling your own” environment from vanilla python it’s a more
complicated question. There are a number of commands I saw, like
pipreview, pip-upgrade, and pip list --outdated. Is this still up for
debate, or have people settled on a solution?

My approach for my personal repo, which I think is common for basic
environments, is a requirements.txt file, mostly just naming packages
I want in the environment, some with version constraints (eg because I
use some feature I know only came in at some point).

Then:

 pip install -r requirements.txt

does the initial install, and:

 pip install -U -r requirements.txt

updates everything named in the requirements.txt file. Obviously pip
is the pip associated with the environment, often python -m pip where
python is the Python from the environment.

I’m also working in a dev environment where we use pip-compile (from
the pip-tools package) to maintain our environment packages. In this
scenario we’re not going for “update everything” because we want
consistent/stable behaviour both in dev/testing/ci and in deployment. So
there’s a requirements.in which we treat as a specification like
requirements.txt in the example above, and a requirements.txt which
is computed from that and the current state of the
requirements.txt.

So here the process is:

 pip-compile --output-file=requirements.txt requirements.in
 pip install -r requirements.txt

(and a commit for the relevant change if it’s good). The
requirements.txt file is like the output of pip freeze: it contains
a specific package revision for every package. Running pip-compile
preserves the versions in requirements.txt except as required to
meeting the specifications in requirements.in. For example we might
add an (unversioned) package to requirements.in or bump a minimum
version there (for a feature or bugfix). Then pip-compile updates the
specific revisions in requirements.txt to meet those constraints,
keeping things unchanged where possible. Then we install those
specific versions.

So that’s not your “update everything” operation, but it is another
approach to package versioning to consider.

Cheers,
Cameron Simpson cs@cskk.id.au