My approach (right now) for python virtual environments is a combination of
python -m venv venv
and compiled requirements created with pip-compile (from pip-tools).
After creating and activating the python virtual environment, I usualy install build requirements using plain pip:
python -m pip install --upgrade -r build_requirements.txt
With build_reqiurements.txt containing only one requirement:
pip-tools==5.3.1
It’s important to install pip-tools inside the python virtual environment. Otherwise pip-sync (installs dependencies from compiled requirements) would install the dependencies into your system’s python environment – pip-sync would possibly even overwrite some of them.
Now the requirements I keep in requirements.in can be compiled into requirements.txt:
pip-compile --rebuild --upgrade --output-file requirements.txt requirements.in
The advantages of such compiled requirements can be read about here – Dependencies and even dependencies of dependencies are pinned to specific versions (==).
Full example:
# Create python virtual environment.
python -m venv venv
# Activate python virtual environment.
. /venv/bin/activate
# Install pip-tools.
python -m pip install --upgrade -r build_requirements.txt
# Compile defined requirements.
pip-compile --rebuild --upgrade --output-file requirements.txt requirements.in
# Install compiled requirements.
pip-sync requirements.txt
# Deactivate python virtual environment.
deactivate