How to get "python -m venv" to directly install latest pip version
The trick is not to install the bundled version of pip (which will almost always be out of date), but to use it to install the most current version from the internet.
Standard library venv
offers a --without-pip
flag that can help here. After creating the virtual environment without pip, you can then you can "execute" ensurepip's wheel directly thanks to Python's zip importer. This is both faster and less hacky than installing pip and then immediately using that same pip installation to uninstall itself and upgrade.
Code speaks louder than words, so here's an example bash function for the process I've described:
# in ~/.bashrc or whereverfunction ve() { local py="python3" if [ ! -d ./.venv ]; then echo "creating venv..." if ! $py -m venv .venv --prompt=$(basename $PWD) --without-pip; then echo "ERROR: Problem creating venv" >&2 return 1 else local whl=$($py -c "import pathlib, ensurepip; whl = list(pathlib.Path(ensurepip.__path__[0]).glob('_bundled/pip*.whl'))[0]; print(whl)") echo "boostrapping pip using $whl" .venv/bin/python $whl/pip install --upgrade pip setuptools wheel source .venv/bin/activate fi else source .venv/bin/activate fi}
If you prefer the older project virtualenv
, it also offers --no-pip
, --no-setuptools
, and --no-wheel
flags to achieve the same on Python 2.7.
Python 3.9's venv
may get an --upgrade-deps
option to automate this, see https://bugs.python.org/issue34556 for more info about that.
I use upgrade-ensurepip
to update those pip
and setuptools
wheel files that are part of the ensurepip
package. It's not as elegant as being able to upgrade ensurepip
via pip
, but it's still preferable to doing it manually.
It is an expected behavior. python -m venv
calls python -m ensurepip
to install pip
and This answer shows that ensurepip
would only install the bundled version even with --upgrade
option. There isn't any official option to update the bundled pip
and setuptools
.
Well I have also no good idea to fix this problem as it just is the designed behavior. I would like to give two suggestions:
Use
pipenv
. It is really good! And it will be the next-generation official package manager in the future(Although there is a big problem related to current Pypi's structure. In short, a package manager can only decide the dependencies with downloading the whole package. This gives a huge difficulty to building dependencies graph.).Implement your custom
EnvBuilder
, actually there is an official example about this. And in the example, it also useget-pip.py
to install the latestpip
.