How to Resolve Python Pip Error "Cannot uninstall <package>. It is a distutils installed project..."
When trying to uninstall or upgrade Python packages using pip
, you might encounter the error message: Cannot uninstall '<package-name>'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
This error indicates that pip
recognizes the package exists but wasn't installed by pip
itself, often being installed by the system's package manager (like apt
or yum
) or by Conda. Pip refuses to modify these external installations to avoid potentially breaking your system or Conda environment.
This guide explains why this conflict occurs and provides the correct ways to manage these packages.
Understanding the Error: pip
vs. Other Package Managers
Your Python packages can be installed through various mechanisms:
pip
: Python's standard package installer, typically managing packages within a specific Python environment'ssite-packages
directory (either global, user-specific, or inside a virtual environment).- System Package Managers (
apt
,yum
,dnf
,pacman
, etc.): Linux distributions often provide Python packages through their native managers (e.g.,python3-yaml
,python3-numpy
). These are installed in system-wide locations and managed by the OS. - Conda: A cross-platform package and environment manager, particularly popular for scientific computing. It manages its own environments and packages, sometimes installing versions different from PyPI.
The "distutils installed project" message is pip
's way of saying, "I see this package exists, but I didn't put it here (it was likely installed by the OS or Conda), so I won't touch it to avoid causing problems." distutils
refers to an older Python packaging system, but the message is often used more broadly by pip to indicate an externally managed package.
The Cause: Attempting pip
Modification on Externally Managed Packages
The error occurs when you run a pip
command (like pip uninstall <package-name>
or pip install --upgrade <package-name>
, or even pip install <other-package>
where <other-package>
has a dependency conflict with an externally managed package) that tries to modify or remove a package originally installed by apt
, yum
, conda
, or potentially other system tools. Pip
correctly recognizes its lack of "ownership" and refuses the operation by default.
Solution 1: Use the Original Package Manager (Recommended)
If a package was installed by your system's package manager or Conda, use that same manager to uninstall or update it. Do not mix managers for the same package installation.
##à For System Packages (Debian/Ubuntu apt
, RHEL/CentOS yum
)
Use apt
or yum
/dnf
with sudo
to manage system-installed Python packages. The exact package name might differ slightly (e.g., prefixed with python3-
).
Example: Uninstall system-installed PyYAML on Debian/Ubuntu
sudo apt remove python3-yaml
Example: Uninstall system-installed NumPy on RHEL/CentOS
sudo yum remove python3-numpy # Or python-numpy, check exact name
Consult your distribution's documentation for finding the correct package name.
For Conda Packages (conda remove
/update
)
If the package is in a Conda environment (check with conda list
), use conda
commands.
# Activate the relevant conda environment first
conda activate your_env_name
# Uninstall a conda-installed package
conda remove <package-name> # e.g., conda remove pyyaml
# Update a conda-installed package
conda update <package-name> # e.g., conda update numpy
# Update all conda packages
# conda update --all
Managing Conda packages with conda
ensures the environment remains consistent.
Solution 2: Use --ignore-installed
with pip
(Use with Caution)*
If you specifically want to replace the system- or Conda-installed version with a version from PyPI installed by pip
(perhaps you need a newer version not available elsewhere), you can force pip
to overwrite it using the --ignore-installed
flag.
# WARNING: Use carefully. This can lead to mixed environments.
pip install --ignore-installed <package-name>
# Or:
python -m pip install --ignore-installed <package-name>
Example: Force pip to install its version of PyYAML over any existing one
pip install --ignore-installed PyYAML
- What it does: This tells
pip
to proceed with the installation as if the existing package wasn't there. It will download from PyPI and install intopip
's target directory (global site-packages if run withsudo
/admin, user site-packages if run with--user
, or venv site-packages if active). - Risks: This creates a situation where you might have two versions of the package potentially visible to Python (one managed by the system/Conda, one by pip), or where the pip version overwrites files needed by the system/Conda manager. This can lead to unexpected behavior or break dependencies managed by the original installer. It's generally better to use virtual environments (Solution 3) or manage the package with its original installer (Solution 1). Use this flag only if you understand the consequences and explicitly intend to override the system/Conda version with the pip version.
Solution 3: Use Virtual Environments (Best Practice)
The safest and most recommended way to avoid this entire class of problems is to use Python virtual environments (venv
or Conda environments).
- Create an isolated environment:
# Using venv
python3 -m venv my_project_env
# Using conda
# conda create --name my_project_env python=3.9 # Specify python version - Activate the environment:
# venv on Linux/macOS:
source my_project_env/bin/activate
# venv on Windows CMD:
my_project_env\Scripts\activate.bat
# venv on Windows PowerShell:
my_project_env\Scripts\Activate.ps1
# conda:
# conda activate my_project_env - Install packages using
pip
inside the activated environment:# Your prompt should show (my_project_env) or similar
pip install <package-name> # e.g., pip install PyYAML numpy requests
Inside the virtual environment, pip
installs packages into the environment's local site-packages
directory. It operates independently of system-wide or Conda base packages, preventing conflicts and the "Cannot uninstall" error because pip
"owns" all packages within the active venv.
Commonly Affected Packages
This error is frequently seen with foundational packages often installed by system tools or Conda defaults, including:
PyYAML
llvmlite
(often a dependency for packages likenumba
)certifi
(dependency for secure connections, e.g., byrequests
)numpy
wrapt
(dependency for decorators, e.g., by oldertensorflow
)
The solution approach remains the same regardless of the specific package: identify how it was originally installed and use the appropriate tool (system package manager, conda
, or pip
within a venv) or use --ignore-installed
cautiously. If llvmlite
or wrapt
cause issues when installing another package (like nemo_toolkit
or tensorflow
), applying --ignore-installed
to the dependency (pip install --ignore-installed llvmlite
) before installing the main package might work, but using a clean virtual environment is generally safer.
Conclusion
The pip
error Cannot uninstall '<package-name>'. It is a distutils installed project...
means pip
is refusing to modify a package installed by a different manager (like apt
, yum
, or conda
).
To resolve this properly:
- Use the original package manager: If installed via
apt
/yum
, useapt remove
oryum remove
. If installed viaconda
, useconda remove
orconda update
. - Use Virtual Environments: (Strongly Recommended) Create and activate a
venv
orconda env
and usepip install
inside it. This isolates dependencies and avoids conflicts. - Use
pip install --ignore-installed <package-name>
: (Use with Caution) Only if you intentionally wantpip
to overwrite the externally managed package, accepting the potential risks of a mixed environment.
Avoiding the mixing of package managers for the same package installation, primarily through the consistent use of virtual environments, is the best way to prevent this error.