I'm using uv now. I'm also still using pyenv, but uv may replace the need for this in the future.
Setting up a development environment for Python can be a bit confusing, mainly stemming from the fact that there are multiple competing standards for package management.
Compared with JavaScript and Node.js, which indeed have several different popular package managers such as npm, yarn, and pnpm, they at least all agree on a common manifest format (package.json) and they are largely all interoperable with each other. In addition, it's very clear to new JS developers that npm is where you ought to start.
This is not the case with Python, where there are multiple competing manifest formats (requirements.txt, Pipfile, pyproject.toml), interoperability is hit and miss, and it's not clear where to start because the official PEPs are somewhat conflicting and the Python Packaging Authority (PyPA) doesn't take a strong stance on the issue either.
pip, which usesrequirements.txt, is the most official and is in the standard lib. But, it's lacking in features you might expect to be built in.pyproject.tomlis also official and you see it mentioned in more recently approved PEPs. This format has been adopted by some newer, but decidedly unofficial, tools.- Then there is
pipenvand thePipfile, which isn’t enshrined in the PEPs, but it’s quasi-official because it’s maintained by PyPA.pipenvseems to have all the community support for the future direction of Python package management.
Those are the main contenders in my opinion, but there’s half a dozen others such as Poetry, Rye, and pdm.
This guide will walk you through setting up a Python development environment using pyenv, pipx, and pipenv. This is the toolchain that I have settled on after trying out several different options. pipenv was chosen as the package manager for it's strong community support, endorsement by PyPA, and it's robust feature set, such as built in support for creating isolated virtual environments for each project, ability to generate lockfiles and install dev dependencies, and the fact that transitive dependencies are not intermingled with your project dependencies in the manifest file.
- If you commonly work on other people's projects, you will likely need to be familiar with other workflows and may need to install additional tools.
- This guide is intended to be a solid starting point for application developers. No consideration has been given to library authors and/or the tools and workflows necessary for publishing packages.
pyenv- Install and switch between multiple different versions of Pythonpipx- Work with Python global cli tools. Similar tonpx.pipcould also be used for this, butpipxis better because it creates an isolated environment for each cli tool.pipenv- Create virtual environments and manage project dependencies usingPipfileandPipfile.lock
Note 1: This guide assumes that you already have Homebrew and Xcode command line tools installed. If not, install them first.
Note 2: This guide assumes you are using the fish shell. If you are using a different shell, consult the pyenv docs for instructions on how to configure your shell.
-
Install pyenv
Install with brew...
brew install pyenvConfigure fish shell...
set -Ux PYENV_ROOT $HOME/.pyenv fish_add_path $PYENV_ROOT/binReload fish shell for PATH changes to take effect. Then, add this to ~/.config/fish/config.fish...
pyenv init - | sourceInstall dependencies required by pyenv...
brew install openssl readline sqlite3 xz zlib tcl-tk -
Install python using pyenv
List available versions...
pyenv install --listInstall a specific version...
pyenv install 3.11.6Set the global version...
pyenv global 3.11.6 -
Install pipx using brew (installing with pip is also an option)
brew install pipx pipx ensurepath -
Install pipenv using pipx
pipx install pipenv
-
Create a new project directory and initialize git
mkdir my-project cd my-project git init touch .gitignore -
Set the python version for the project
pyenv install 3.11.6 (if not already installed) pyenv local 3.11.6 -
Create a virtual environment for the project
Note: If you would prefer that the virtual environment is created locally to the project, you can set the environment variable
PIPENV_VENV_IN_PROJECT=1. Be sure to add.venvto your.gitignorefile. This is somewhat of an underdocumented feature.pipenv install -
Activate the virtual environment. This must be done for each new shell session.
pipenv shellAlternatively, you can run commands in the virtual environment without activating it...
pipenv run python app.py -
Install project dependencies
pipenv install flask or pipenv install flask==3.0.0I think you need to manually edit the Pipfile and rerun
pipenv installif you want a flexible version range. The cli doesn't seem to support it.flask = ">=3.0,<4.0"If you just cloned a project, you can install all dependencies from the Pipfile...
pipenv installOr, if you also want dev dependencies...
pipenv install --dev
If you like small focused tools and you like using official things from the standard lib, this might be more to your taste.
pyenv- samepipx- samepip- Install project dependencies usingrequirements.txtand, optionally,dev-requirements.txt. Comes packaged with modern python installations.venv- Create isolated virtual environments for your projects. Comes packaged with modern python installations.pip-tools- A community project that provides a standard convention for adding lockfiles to your Python workflow.