mirror of https://github.com/pypa/pip
Restore ability to uninstall distutils packages
This is a partial revert of 6afc718307
to restore the ability to overwrite distutils installed packages.
It is not elegant, but some projects (such as OpenStack's devstack)
rely on overwriting packages installed via the system package manager.
These packages can't be removed because they are dependencies for
parts of the base system, but many of the things devstack needs to run
requires later dependencies. For historical reasons it's not easy to
fix this into a virtualenv, etc, all at once.
If distributions move to setuptools based packages, this problem might
fix itself.
This commit is contained in:
parent
495c773662
commit
35a3e8b7f5
|
@ -7,6 +7,7 @@ import shutil
|
|||
import sys
|
||||
import tempfile
|
||||
import traceback
|
||||
import warnings
|
||||
import zipfile
|
||||
|
||||
from distutils.util import change_root
|
||||
|
@ -34,7 +35,9 @@ from pip.utils import (
|
|||
call_subprocess, read_text_file, FakeFile, _make_build_dir, ensure_dir,
|
||||
get_installed_version, canonicalize_name
|
||||
)
|
||||
|
||||
from pip.utils.hashes import Hashes
|
||||
from pip.utils.deprecation import RemovedInPip10Warning
|
||||
from pip.utils.logging import indent_log
|
||||
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
|
||||
from pip.utils.ui import open_spinner
|
||||
|
@ -647,12 +650,14 @@ class InstallRequirement(object):
|
|||
paths_to_remove.add(path + '.pyo')
|
||||
|
||||
elif distutils_egg_info:
|
||||
raise UninstallationError(
|
||||
"Detected a distutils installed project ({0!r}) which we "
|
||||
"cannot uninstall. The metadata provided by distutils does "
|
||||
"not contain a list of files which have been installed, so "
|
||||
"pip does not know which files to uninstall.".format(self.name)
|
||||
warnings.warn(
|
||||
"Uninstalling a distutils installed project ({0}) has been "
|
||||
"deprecated and will be removed in a future version. This is "
|
||||
"due to the fact that uninstalling a distutils project will "
|
||||
"only partially uninstall the project.".format(self.name),
|
||||
RemovedInPip10Warning,
|
||||
)
|
||||
paths_to_remove.add(distutils_egg_info)
|
||||
|
||||
elif dist.location.endswith('.egg'):
|
||||
# package installed by easy_install
|
||||
|
|
|
@ -30,6 +30,28 @@ def test_simple_uninstall(script):
|
|||
assert_all_changes(result, result2, [script.venv / 'build', 'cache'])
|
||||
|
||||
|
||||
def test_simple_uninstall_distutils(script):
|
||||
"""
|
||||
Test simple install and uninstall.
|
||||
|
||||
"""
|
||||
script.scratch_path.join("distutils_install").mkdir()
|
||||
pkg_path = script.scratch_path / 'distutils_install'
|
||||
pkg_path.join("setup.py").write(textwrap.dedent("""
|
||||
from distutils.core import setup
|
||||
setup(
|
||||
name='distutils-install',
|
||||
version='0.1',
|
||||
)
|
||||
"""))
|
||||
result = script.run('python', pkg_path / 'setup.py', 'install')
|
||||
result = script.pip('list')
|
||||
assert "distutils-install (0.1)" in result.stdout
|
||||
script.pip('uninstall', 'distutils_install', '-y', expect_stderr=True)
|
||||
result2 = script.pip('list')
|
||||
assert "distutils-install (0.1)" not in result2.stdout
|
||||
|
||||
|
||||
@pytest.mark.network
|
||||
def test_uninstall_with_scripts(script):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue