π§ This reference is still under construction. Please do not yet widely share.
This website is reference on how various popular Python tools cover different functionalities involved in Python development. The goal is to help you understand the different layers of functionality that you may need, and how the various tools cover them. Opinions about the tools are generally not provided.
What's up with Python vs. Conda packages and environments?
Python packages are distributable archives of Python code. Even if a Python package includes code in another language, like C++ or Rust, the package would have Python "bindings" that allow that code to be called from Python. Virtual environments are isolated and independent sets of installed software, and it's a best practice to have a virtual environment per project. Python environments then refers to virtual environments for Python packages.
On the other hand, Conda packages are distributable archives of software in any language. They could include Python libraries, but system libraries, R libraries, Julia libraries, and other executable programs are also often distributed as Conda packages. Conda environments are accordingly virtual environments for Conda packages. However, Python has a special level of support in the Conda ecosystem, and you can actually use pip to install Python packages into a Conda environment as if it were a Python virtual environment. Those Python packages will be available in the Conda environment alongside any Conda packages.
Which kind of package ecosystem should I use?
If you are working with exclusively Python packages, you will likely have a better experience using Python virtual environments and Python package tools. The experience will be simpler, and you'll be able to install packages more quickly and easily.
However, if you are likely to need software in other languages, or if your Python dependencies have dependencies on system-level libraries, then Conda can be useful for handling everything together. This is can be common in scientific computing, data science, machine learning, and geospatial data analysis.
When do I need these different functionalities?
Managing Python installations β
Creating a virtual environment β
Managing dependencies β
Automation of multiple virtual environments β
Writing lock files β
Building packages β
Publishing packages β
Library development β
β
β
β
β
β
β
Application development β
β
β
β
β
Data science project β
β
β
β
β
Functionality definitions
Managing Python installations
Installs multiple versions of Python, and provides ways to switch between them on a global or per-project basis.
Creating a virtual environment
Can create a virtual environment, i.e., a specific Python interpreter and an isolated set of installed Python packages. Typically, a Python project uses at least one virtual environment. This may be a standalone virtual environment stored in a central location, or it may be inside a project directory and tied to that project. There are two kinds of virtual environments relevant to Python development: regular Python virtual environments; and Conda environments which can include other non-Python software packages.
Managing dependencies
Provides a way to declare project dependencies and install them into a virtual environment.
Automation of multiple virtual environments
Automation for creation, dependency management, and task invocation for multiple virtual environments for a single project. This is often used to manage separate environments for tests, documentation generation, linting, and other tasks. Such tools often let you create virtual environments from a matrix of parameters.
Writing lock files
Lock files specify the exact set of packages installed in an environment with exact versions. They allow for reproducing that environment. This is most commonly useful if you are developing software that will be deployed, like an application or data pipeline. It's less relevant if you are developing a library.
Building packages
Creating file archives of Python code that can be distributed and installed by other users. There are two kinds of packages common for Python: regular Python packages distributed on PyPI, and Conda packages which can be code in any language but often is used with Python.
Publishing packages
Publishing Python packages to PyPI or Conda packages to conda-forge.
Tools
pyenv
pyenv is a tool that installs multiple versions of Python and lets you switch between them.
pyenv has an pyenv install command for installing Python versions, a pyenv global command for setting a global Python version, and a pyenv local command for setting a per-project Python version.
asdf with the asdf-python plugin has an asdf install python command for installing Python versions, a asdf global python command for setting a global Python version, and a asdf local python command for setting a per-project Python version.
mise (formerly rtx) is a tool for managing multiple versions of many language runtimes, including Python. It started out as a clone of asdf implemented in Rust.
mise has an mise install python@<version> command for installing Python versions and a mise use python@<version> command for setting an active Python version.
virtualenv is a tool for creating Python virtual environments. It has more functionality than the standard library venv module, such as creating virtual environments for any installed Python interpreter/version.
Pip has an pip install command for installing packages, either from a local distribution or from PyPI. It also has a requirements.txt requirements file specification that it can read and install from.
Conda treats Python like any other conda package, and it allows you to install any version of Python as an isolated Python runtime in conda environment. To use that instance of Python, you will need to either activate the environment or use conda run -n <envname>.
Conda has a environment.yml file specification for specifying dependencies to install into an environment. In it, you can have a subsection under pip for Python package dependencies.
tox is a tool for automated testing in multiple virtual environments. You can configure environments using an INI-format configuration file, and it provides CLI commands to easily run tasks in those environments.
Nox is a tool for automated testing in multiple virtual environments similar to tox. Unlike tox, Nox uses a Python script for configuration rather than an INI file.
Nox can use venv or virtualenv as a virtual environment backend. This will create Python environments, and it allows you to script Python package installations with pip.
Pipenv is a tool for managing Python environments and dependencies for a project. It uses its own Pipfile and Pipefile.lock file formats for specifying and locking dependencies.
If you use Hatch's virtual environment management functionality, it will create a virtual environment named "default" that is the primary environment for a project.
Hatch lets you define dependencies in your project's pyproject.toml file. It will automatically install them in any virtual environments that it manages.
Hatch lets you configure multiple virtual environments in your project's pyproject.toml file. It has advanced configurability like inheritance between environments and matrices of parameters. Hatch will keep dependencies in environments synchronized, and provides a hatch run command for executing scripts in one or multiple environments.
Hatch is a build frontend, and it also comes with a build backend named Hatchling. Both are compliant with modern Python packaging specifications (PEP 517 and PEP 621). You can use Hatch to build a package with the hatch build command.
pip-tools is a set of command-line programs for creating a lock file for Python packages and for syncing a virtual environment with a lock file. It uses the requirements.txt format used by pip.
The pip-compile command generates a fully pinned lock file (fully pinned requirements.txt) from a set of abstract requirements. The pip-sync command synchronizes an environment with a lock file.
Use the conda-lock CLI with a conda environment.yml file containing abstract requirements to generate a lock file. You can use the conda-lock install command to install from a lock file.
Flit is a build frontend, and it includes a build backend flit_core. Both are compliant with modern Python packaging specifications (PEP 517 and PEP 621). You can use Flit to build a package with the flit build command.