Context
There is a long history of discussions around, and issues with, the use of Pip in Conda environments. There are both legitimate needs for using Pip in a Conda environment and easy to make mistakes by users which break environments or applications when they are using pip when then should have used conda or mamba.
Over the past few months there have been a number of threads on the Python packaging Discourse where Conda came up. For example:
- PEP 704 - Require virtual environments by default for package installers, which proposes a change which would be a significant backwards compat break in pip for conda users. Discourse thread
- The Wanting a singular packaging tool/vision thread
- The Python Packaging Strategy Discussion - Part 1 thread
- PEP 668 - Marking Python base environments as “externally managed” (a bit older). Discourse thread
- This post specifically outlines the existing “knobs” available for tweaking how
pipinteracts with other package managers.
Rather than always pushing back with “this doesn’t work for conda”, Steve Dower suggested that the conda community should specify how it wants pip to behave inside conda envs (see https://discuss.python.org/t/wanting-a-singular-packaging-tool-vision/21141/149). That is not an easy question, but it would be great to see a coherent view indeed. This may, but doesn’t have to, include a request for new features from pip or from Python packaging.
I’ll note that the question is broader than pip - there are other Python package installers, and there are also topics like virtual environments and dependency specifiers that interact with conda/mamba or conda environments.
Usage scenarios
There are multiple reasons for users or tools wanting to use pip or wheels from PyPI inside a conda environments:
- Installing Python packages from PyPI for which no conda package is available in
defaults,conda-forgeor another channel, - Installing a package from source locally. This can be a development version of any package, even if it’s available as a release in a conda channel,
- Using an all-wheel workflow like
conda create -n my-devenv python=3.11(which does installpipin addition to python 3.11) followed bypip install a-bunch-of-pypi-pkgs, - As part of the workflow for building conda packages:
recipe/build.shin a conda-forge feedstock is likely to contain something like${PYTHON} -m pip install . -vv, as documented in https://conda-forge.org/docs/maintainer/adding_pkgs.html#use-pip,- Another example: https://conda-forge.org/docs/maintainer/adding_pkgs.html#use-pip
pip listandpip checkare used too: https://conda-forge.org/docs/orga/guidelines.html#python-specific-details- Note that the conda-forge automation ensures
--no-build-isolationis used by default when usingpipwithin a conda-forge build, in order to avoid problems when building packages with compiled extensions,
There is some basic guidance in the Conda docs for this:
- Managing packages — conda 25.11.0 documentation
- Managing environments — conda 25.11.0 documentation
- The docs also contain an example of using
pipto install a package from PyPI as part of anenvironment.ymlfile:
name: stats2
channels:
- javascript
dependencies:
- python=3.9
- bokeh=2.4.2
- conda-forge::numpy=1.21.*
- nodejs=16.13.*
- flask
- pip
- pip:
- Flask-Testing
- There is a
pip_interop_enabledImproving interoperability with pip — conda 25.11.1.dev10 documentation experimental mode forconda. Unlike mostcondafeatures, this doesn’t seem to have an analog inmamba(it’s possible thatmambaalready has the improved behavior hidden behind this flag, not sure).
On the other hand, pip is often misused (especially by beginning users) when conda or mamba should be used instead. This is a very frequent source of broken environments and of bug reports to popular Python packages. The Spyder team even made a polished 3-minute video about this with the usual “avoid mixing pip and conda” advice. Even advanced Python users who are comfortable building from source tend to shoot themselves in the foot because they use pip install . instead of pip install . --no-build-isolation.
Another thing that leads to unpredictable results is iterative use of conda install and pip install in an environment - this tends to degrade and then break. If pip usage is indeed warranted, it should be done once - any further updates require recreating the environment for reliable results (as documented under “Recreate the environment if changes are needed” in this section of the conda docs).
Conceptual issues with usage scenarios
One fairly fundamental problem here is that pip is used for multiple purposes:
- Building a package from source, then installing it,
- Installing wheels from PyPI
- Package/dependency management
- Virtual environment creation/management: now for isolated builds, possibly more in the future.
conda on the other hand has a single coherent purpose (installing a compatible set of built packages into an environment) but does not have a good “build from source” (or “developer”) story. The metadata in a Python package’s source tree (in pyproject.toml) is not generic dependency metadata, it’s PyPI-specific. The mapping from PyPI dependencies to conda package dependencies happens in conda recipes, rather than in the project’s own VCS repo. Hence the need to use pip, rather than a similar conda install ..
So what conda users need from pip is a subset of everything that pip does, and it comes with a UX that isn’t ideal.
Some concrete questions to answer
- Should it be possible to use
pip(and other installers likepypa/installer) to install a Python package into a conda environment from a vcs checkout, an sdist, or a wheel?- answer RG: yes
- Also for the
baseenvironment?- answer RG: no, too fragile
- Should
pipbe able to uninstall/overwritecondapackages, and vice versa?- answer RG: probably yes, users rely on this and there are valid usage scenarios, so making this work as smoothly as possible seems preferred over preventing this.
- Should a conda env be considered or marked as a virtual environment?
- answer RG: no, they’re clearly different beasts, this will lead to problems
Design changes?
Options given the current state of Python packaging and Pip include:
- Do/change nothing
- Protect the
baseenvironment better by addingEXTERNALLY-MANAGEDto it (see conda#12245) - Add
EXTERNALLY-MANAGEDto all environments, which makes users opt in to potential breakage by using a flag:pip install ... --break-system-packages.- Optionally, provide an alternative installer (maybe even a renamed
pip?) for the valid use cases that conda users have, like installing from source or installing packages that are not present in a conda channel.
- Optionally, provide an alternative installer (maybe even a renamed
Options for future design changes that would require Pip or Python packaging changes include:
pipnot installing dependencies that are available as conda packages. E.g., ifpip install my-niche-packagecontains a dependency onnumpy, thenpipshould not installnumpy(it could either error out with an informative message, or - very futuristic, and probably hard - installnumpywithconda/mamba)- Shared metadata, or metadata mapping, such that the
pyproject.tomldependencies would be fully translatable to conda packages.- This would make it easier to do things like
conda install .spinning up an isolated conda env with conda build dependencies, rather than a virtual environment with packages installed from wheels, - It would also make it easier for projects to not have multiple
environment.yml,requirements.txt, etc. files (there’s already a PyPI-only issue here, because there is no such thing aspip install . --only-depsand there should be), - Equivalently, the
environment.yamlandrequirements.txtformats could converge.
- This would make it easier to do things like
- Generalize the concept of virtual environments, so tools that use them can more easily support conda environments as well (think of pip/tox/nox/asv/etc. here; anything that automatically creates a temporary or permanent venv)
- ?
Other specific requests for pip or Python packaging as a whole?
- No breakage for scenarios that work today (so “no” to PEP 704’s idea of requiring a virtual environment to install into).
- ?
Relevant open issues
This is an incomplete list, but touches on some of the more important open issues:
- Editable installs (
pip install -e .) doesn’t interact well with conda: conda#5861 - Add an EXTERNALLY-MANAGED file to base environment: conda#12245
conda env exporttends to not be robust when PyPI packages are present: conda#9624pip_interop_enabledissues: conda#11177, conda#12242,
Next steps
The above is a start at a summary; it’d be great to discuss here as well as in an upcoming conda community meeting (as proposed by @beckermr in the conda Element channel), expand this doc, and then turn it into (a) doc improvements in conda/mamba/conda-forge docs, and (b) in something that can be presented as a “think is what the conda community thinks or would like” to the PyPA & https://discuss.python.org/ crowd.