Python environment management is easier when version selection and dependency isolation are treated as separate decisions. A version manager such as `pyenv` can select an interpreter. Python's built-in `venv` then creates an isolated environment for one project.
This article was verified on 2026-08-01 against the [Python `venv` documentation](https://docs.python.org/3/library/venv.html) and the [Python Packaging User Guide](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/).
## Recommended baseline
Use a Python release that is still supported by the Python project. From the project root:
```bash
python3 --version
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
```
Activation is convenient but not required. Automation can call `.venv/bin/python` directly. Keep `.venv/` out of Git and record dependencies in project metadata or a reviewed requirements input rather than committing the environment itself.
## Choosing a tool
- Use `venv` when you want the standard, minimal building block.
- Use `pyenv` when projects require different Python interpreters; pin the choice in `.python-version` only if the team agrees to that convention.
- Use a workflow tool such as Hatch, PDM, Pipenv, Poetry, or uv when its locking, publishing, or task features solve a concrete project need. The PyPA does not prescribe one universal workflow tool.
- Use `pipx` for standalone Python command-line applications so each tool receives its own environment.
## Migrating an older project
1. Confirm the required Python version and that it is still supported.
2. Preserve the dependency declaration before deleting any old environment.
3. Create `.venv` with the selected interpreter.
4. Install from the project's declared dependencies.
5. Run tests and the application's normal start command.
Do not assume that an environment created by one interpreter can be upgraded in place. Recreate it and verify it instead.
## Why the older recipe changed
Python 2 reached end of life in 2020, and its standard library did not provide the Python 3 `venv` module described by modern tutorials. A command such as `python2 -m venv` therefore was not a portable baseline. Older examples also tend to mix the operating-system Python, Homebrew Python, a version manager, and project packages without explaining which layer owns what.
Keep the ownership boundaries explicit. The operating system or package manager owns its Python installation. A version manager may install additional interpreters for development. The project owns its dependency declaration. A disposable virtual environment contains installed artifacts. Never use `sudo pip install` to make a project work, and do not modify an externally managed system interpreter to avoid creating an environment.
## A reproducible project example
For a small application, create `pyproject.toml` with its direct requirements and build metadata rather than treating a `pip freeze` snapshot as design intent. The exact content depends on the selected build backend. Once the repository has chosen a workflow, document one bootstrap command and keep CI aligned with it.
```bash
git clone https://example.com/team/project.git
cd project
pyenv install --skip-existing 3.13.5
pyenv local 3.13.5
python -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m pytest
```
The concrete version above is an example, not a timeless recommendation. Check the [Python versions page](https://devguide.python.org/versions/) and the project's declared support range before selecting it. In CI, create a fresh environment for every supported Python version instead of copying a developer's `.venv`.
## Common failure modes
- If `python` still resolves outside `.venv`, inspect `command -v python` and use the environment's absolute interpreter path.
- If native extensions fail, confirm compiler and operating-system prerequisites; recreating the environment cannot supply missing system libraries.
- If two developers resolve different versions, adopt the project's chosen lock or constraints workflow rather than exchanging environment directories.
- If a command-line tool conflicts with project dependencies, install it through `pipx` instead of the project environment.
- If `.venv` was copied or the interpreter moved, recreate it. Virtual environments are generally disposable and not designed to be portable archives.
Activation scripts execute shell code. Use the activation script created by the environment you control, and do not source an environment directory obtained from an untrusted archive.
## Verification
```bash
python -c 'import sys; print(sys.executable); print(sys.version)'
python -m pip check
```
The executable should resolve inside `.venv`, and `pip check` should report no broken installed requirements.
Finally, run the repository's full test, lint, type-check, build, and smoke-test commands. Environment creation is successful only when a clean machine can reproduce the same supported workflow.
Python environment management is easier when version selection and dependency isolation are treated as separate decisions. A version manager such as pyenv can select an interpreter. Python’s built-in venv then creates an isolated environment for one project.
Activation is convenient but not required. Automation can call .venv/bin/python directly. Keep .venv/ out of Git and record dependencies in project metadata or a reviewed requirements input rather than committing the environment itself.
Choosing a tool
Use venv when you want the standard, minimal building block.
Use pyenv when projects require different Python interpreters; pin the choice in .python-version only if the team agrees to that convention.
Use a workflow tool such as Hatch, PDM, Pipenv, Poetry, or uv when its locking, publishing, or task features solve a concrete project need. The PyPA does not prescribe one universal workflow tool.
Use pipx for standalone Python command-line applications so each tool receives its own environment.
Migrating an older project
Confirm the required Python version and that it is still supported.
Preserve the dependency declaration before deleting any old environment.
Create .venv with the selected interpreter.
Install from the project’s declared dependencies.
Run tests and the application’s normal start command.
Do not assume that an environment created by one interpreter can be upgraded in place. Recreate it and verify it instead.
Why the older recipe changed
Python 2 reached end of life in 2020, and its standard library did not provide the Python 3 venv module described by modern tutorials. A command such as python2 -m venv therefore was not a portable baseline. Older examples also tend to mix the operating-system Python, Homebrew Python, a version manager, and project packages without explaining which layer owns what.
Keep the ownership boundaries explicit. The operating system or package manager owns its Python installation. A version manager may install additional interpreters for development. The project owns its dependency declaration. A disposable virtual environment contains installed artifacts. Never use sudo pip install to make a project work, and do not modify an externally managed system interpreter to avoid creating an environment.
A reproducible project example
For a small application, create pyproject.toml with its direct requirements and build metadata rather than treating a pip freeze snapshot as design intent. The exact content depends on the selected build backend. Once the repository has chosen a workflow, document one bootstrap command and keep CI aligned with it.
The concrete version above is an example, not a timeless recommendation. Check the Python versions page and the project’s declared support range before selecting it. In CI, create a fresh environment for every supported Python version instead of copying a developer’s .venv.
Common failure modes
If python still resolves outside .venv, inspect command -v python and use the environment’s absolute interpreter path.
If native extensions fail, confirm compiler and operating-system prerequisites; recreating the environment cannot supply missing system libraries.
If two developers resolve different versions, adopt the project’s chosen lock or constraints workflow rather than exchanging environment directories.
If a command-line tool conflicts with project dependencies, install it through pipx instead of the project environment.
If .venv was copied or the interpreter moved, recreate it. Virtual environments are generally disposable and not designed to be portable archives.
Activation scripts execute shell code. Use the activation script created by the environment you control, and do not source an environment directory obtained from an untrusted archive.
The executable should resolve inside .venv, and pip check should report no broken installed requirements.
Finally, run the repository’s full test, lint, type-check, build, and smoke-test commands. Environment creation is successful only when a clean machine can reproduce the same supported workflow.