pipenv
pipenv copied to clipboard
The Python version from Pipfile and Pipfile.lock is ignored when a venv is already present
I think this is rather straightforward, but I couldn't find an existing bug like this.
Description
Pipenv ignores the Python version once the virtualenv is installed.
I think it would be nice to show a warning or similar when the Python versions diverge.
Context
When collaborating with multiple people, this can lead to unexpected bugs, since one person might have upgraded the Python version in the pipfile without the others noticing. Their local development environments will happily continue to use the old Python version.
We did, in fact, just have this problem that we could not reproduce a production bug since our local installations ran on a different version of Python and we were accidentally relying on unintended edge-case behavior in the standard library that had subsequently been fixed. We did not believe the bug report at first, since we could not replicate it.
Steps to reproduce
Make sure that you have two versions of Python installed, in this example 3.11 and 3.12.
-
Create a simple Pipfile with the following content (in a fresh folder):
[requires] python_version = "3.11"
-
Run
pipenv install
. -
Change the Pipenv file to require a new Python version:
[requires] python_version = "3.12"
-
Run
pipenv install
again.
Expected behavior: Pipenv would complain in some way or another that the Python version has changed. The version in the venv has have diverged from the one in the Pipfile.
Actual behavior:
$ pipenv install
Pipfile.lock (51d3e4) out of date, updating to (2110f5)...
Locking [packages] dependencies...
Locking [dev-packages] dependencies...
Updated Pipfile.lock (702ad05de9bc9de99a4807c8dde1686f31e0041d7b5f6f6b74861195a52110f5)!
Installing dependencies from Pipfile.lock (2110f5)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
There is no indication that we're on a different Python version right now, but it is:
$ pipenv run python --version
Python 3.11.7
Full Bash script to reproduce
mkdir pipenv-bug-demo
cd pipenv-bug-demo
cat > Pipfile <<EOF
[requires]
python_version = "3.11"
EOF
pipenv install
cat > Pipfile <<EOF
[requires]
python_version = "3.12"
EOF
pipenv install
pipenv run python --version
The other pipenv
commands, e.g. clean
, verify
or sync
also provide no indication that anything is wrong. pipenv sync
even says All dependencies are now up-to-date!
, which is just not true -- Python itself, as a dependency, is not up to date.
Edit: Oh, and you can delete the Pipfile.lock as well or change the version inside it, none of it will change anything about this.
Alternatives
Pipenv could also force-recreate the venvs with the correct version, but I think this would be too agressive, at least as a default.
$ pipenv --support
Pipenv version: '2023.10.3'
Pipenv location: '~/.local/lib/python3.11/site-packages/pipenv'
Python location: '/usr/bin/python3.11'
OS Name: 'posix'
User pip version: '23.2.1'
user Python installations found:
PEP 508 Information:
{'implementation_name': 'cpython',
'implementation_version': '3.11.7',
'os_name': 'posix',
'platform_machine': 'x86_64',
'platform_python_implementation': 'CPython',
'platform_release': '6.5.0-17-generic',
'platform_system': 'Linux',
'platform_version': '#17~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 16 '
'14:32:32 UTC 2',
'python_full_version': '3.11.7',
'python_version': '3.11',
'sys_platform': 'linux'}
The pyvenv.cfg
file inside the venv folder contains the Python version already, so Pipenv would just need to check against it.
I am not sure on this one as I would also expect you could use a vitualenv of your choosing outside of what is defined in the Pipfile -- say you want to test upgrading Python versions, its more flexible to be able to create and work with a virtualelnv of your choosing without having to rigidly define or change the Python version yet in the Pipile, but on the other hand I think you bring up a fair point.