Synopsis
Use pyenv to quickly install and switch between different Python releases while using pipenv to virtually isolate project files and libraries.
For example, create a virtual python environment using Python release 3.11.1 with pipenv command pipenv --python 3.11.1
. If Python 3.11.1 is not installed on the local system pipenv will leverage pyenv to install and make it ready for use.
The be clear, pyenv and pipenv are completely separate tools from one another and operate with benefit independently. However, when they both exist together, the workflow of setting up a virtual python environment, based on various version requirements, is optimized.
For further details about the two tools,
Install steps
The following are the steps I took for installation on macOS. At the time of drafting this document, the release of macOS is 13.1 (Ventura). The hardware is Apple M1 Max.
pipenv
Using the host’s default python installation, install pipenv using pip
.
pip install --user pipenv
Add pipenv to $PATH
in the .zshrc
file.
cd ~
vi .zshrc
export PATH=$PATH:/Users/user/Library/Python/3.9/bin
(save and exit)
Check the installation using pipenv --help
user@host ~ % pipenv --help
Usage: pipenv [OPTIONS] COMMAND [ARGS]...
Options:
--where Output project home information.
--venv Output virtualenv information.
--py Output Python interpreter information.
--envs Output Environment Variable options.
--rm Remove the virtualenv.
--bare Minimal output.
--man Display manpage.
--support Output diagnostic information for use in
GitHub issues.
--site-packages / --no-site-packages
Enable site-packages for the virtualenv.
[env var: PIPENV_SITE_PACKAGES]
--python TEXT Specify which version of Python virtualenv
should use.
--three Use Python 3 when creating virtualenv.
Deprecated
--clear Clears caches (pipenv, pip). [env var:
PIPENV_CLEAR]
-q, --quiet Quiet mode.
-v, --verbose Verbose mode.
--pypi-mirror TEXT Specify a PyPI mirror.
--version Show the version and exit.
-h, --help Show this message and exit.
Usage Examples:
Create a new project using Python 3.7, specifically:
$ pipenv --python 3.7
Remove project virtualenv (inferred from current directory):
$ pipenv --rm
Install all dependencies for a project (including dev):
$ pipenv install --dev
Create a lockfile containing pre-releases:
$ pipenv lock --pre
Show a graph of your installed dependencies:
$ pipenv graph
Check your installed dependencies for security vulnerabilities:
$ pipenv check
Install a local setup.py into your virtual environment/Pipfile:
$ pipenv install -e .
Use a lower-level pip command:
$ pipenv run pip freeze
Commands:
check Checks for PyUp Safety security vulnerabilities and against
PEP 508 markers provided in Pipfile.
clean Uninstalls all packages not specified in Pipfile.lock.
graph Displays currently-installed dependency graph information.
install Installs provided packages and adds them to Pipfile, or (if no
packages are given), installs all packages from Pipfile.
lock Generates Pipfile.lock.
open View a given module in your editor.
requirements Generate a requirements.txt from Pipfile.lock.
run Spawns a command installed into the virtualenv.
scripts Lists scripts in current environment config.
shell Spawns a shell within the virtualenv.
sync Installs all packages specified in Pipfile.lock.
uninstall Uninstalls a provided package and removes it from Pipfile.
update Runs lock, then sync.
verify Verify the hash in Pipfile.lock is up-to-date.
user@host ~ %
pyenv
I used the “Basic GitHub Checkout” installation method. I thought this was an efficient “installation” method.
Open a terminal
cd ~
git clone https://github.com/pyenv/pyenv.git .pyenv
The following was used for the zsh default shell on macOS 13.1
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
Close and reopen a new terminal shell.
Check the installation using pyenv --help
user@host ~ % pyenv --help
Usage: pyenv <command> [<args>]
Some useful pyenv commands are:
--version Display the version of pyenv
commands List all available pyenv commands
exec Run an executable with the selected Python version
global Set or show the global Python version(s)
help Display help for a command
hooks List hook scripts for a given pyenv command
init Configure the shell environment for pyenv
install Install a Python version using python-build
latest Print the latest installed or known version with the given prefix
local Set or show the local application-specific Python version(s)
prefix Display prefixes for Python versions
rehash Rehash pyenv shims (run this after installing executables)
root Display the root directory where versions and shims are kept
shell Set or show the shell-specific Python version
shims List existing pyenv shims
uninstall Uninstall Python versions
version Show the current Python version(s) and its origin
version-file Detect the file that sets the current pyenv version
version-name Show the current Python version
version-origin Explain how the current Python version is set
versions List all Python versions available to pyenv
whence List all Python versions that contain the given executable
which Display the full path to an executable
See `pyenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/pyenv/pyenv#readme
user@host ~ %
Example
The following command creates a virtual python environment and installs the requested Python release.
mkdir project1 && cd project1
jneuffer@Humble project1 % pipenv --python 3.7.16
Warning: Python 3.7.16 was not found on your system...
Would you like us to install CPython 3.7.16 with Pyenv? [Y/n]: y
Installing CPython 3.7.16 with /Users/jneuffer/.pyenv/bin/pyenv (this may take a few minutes)...
✔ Success!
⠹ Installing python...patching file 'test/v3ext.c'
patching file 'Doc/library/ctypes.rst'
patching file 'Lib/test/test_unicode.py'
patching file 'Modules/_ctypes/_ctypes.c'
patching file 'Modules/_ctypes/callproc.c'
patching file 'Modules/_ctypes/ctypes.h'
patching file setup.py
patching file 'Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst'
patching file 'Modules/_decimal/libmpdec/mpdecimal.h'
patching file setup.py
python-build: use zlib from xcode sdk
Creating a virtualenv for this project...
Pipfile: /Users/jneuffer/project1/Pipfile
Using /Users/jneuffer/.pyenv/versions/3.7.16/bin/python3.7m (3.7.16) to create virtualenv...
⠸ Creating virtual environment...created virtual environment CPython3.7.16.final.0-64 in 307ms
creator CPython3Posix(dest=/Users/jneuffer/.local/share/virtualenvs/project1-TKHsXDeN, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/jneuffer/Library/Application Support/virtualenv)
added seed packages: pip==22.3.1, setuptools==65.6.3, wheel==0.38.4
activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
✔ Successfully created virtual environment!
Virtualenv location: /Users/jneuffer/.local/share/virtualenvs/project1-TKHsXDeN
Creating a Pipfile for this project...

Using pipenv shell
we can drop into the new virtual project.
jneuffer@Humble project1 % pwd
/Users/jneuffer/project1
jneuffer@Humble project1 % pipenv shell
Launching subshell in virtual environment...
Restored session: Sat Dec 24 12:36:09 EST 2022
. /Users/jneuffer/.local/share/virtualenvs/project1-TKHsXDeN/bin/activate
jneuffer@LivingRoom1 project1 % . /Users/jneuffer/.local/share/virtualenvs/project1-TKHsXDeN/bin/activate
(project1) jneuffer@Humble project1 % python --version
Python 3.7.16
(project1) jneuffer@Humble project1 % pip list
Package Version
---------- -------
pip 22.3.1
setuptools 65.6.3
wheel 0.38.4
(project1) jneuffer@Humble project1 %
Let’s install pandas inside the virtual python environment.
The following screenshot shows the output from issuing the command, (project1) jneuffer@Humble project1 % pip install pandas

We’ve installed pandas inside the virtual python environment. Now we’ll do a pip list
to see what that looks like.
(project1) jneuffer@Humble project1 % pip list
Package Version
--------------- -------
numpy 1.21.6
pandas 1.3.5
pip 22.3.1
python-dateutil 2.8.2
pytz 2022.7
setuptools 65.6.3
six 1.16.0
wheel 0.38.4
(project1) jneuffer@Humble project1 %
Now let’s leave the virtual python environment.
(project1) jneuffer@Humble project1 % exit
Saving session...
...saving history...truncating history files...
...completed.
jneuffer@Humble project1 %
Conclusion
These two tools can streamline the need to use specific release versions of not only Python, but also specific releases of modules.
There are other approaches to isolating Python and modules, such as VMs (Vagrant) and containers. These approaches are just as interesting as the method described above. Everything has a set of pro/con and requirements; therefore, having more than one solution to solve a problem is a good thing.
Comments