Skip to content

Commit 0d60e37

Browse files
committed
Added workaround for broken setuptools on Debian/Ubuntu; fixes 'pip uninstall' outside of venv for users of packaged setuptools on those platforms.
1 parent 1fcf4fa commit 0d60e37

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

pip/req.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,24 @@ def uninstall(self, auto_confirm=False):
407407

408408
pip_egg_info_path = os.path.join(dist.location,
409409
dist.egg_name()) + '.egg-info'
410+
# workaround for http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618367
411+
debian_egg_info_path = pip_egg_info_path.replace(
412+
'-py%s' % pkg_resources.PY_MAJOR, '')
410413
easy_install_egg = dist.egg_name() + '.egg'
411414
develop_egg_link = egg_link_path(dist)
412-
if os.path.exists(pip_egg_info_path):
415+
416+
pip_egg_info_exists = os.path.exists(pip_egg_info_path)
417+
debian_egg_info_exists = os.path.exists(debian_egg_info_path)
418+
if pip_egg_info_exists or debian_egg_info_exists:
413419
# package installed by pip
414-
paths_to_remove.add(pip_egg_info_path)
420+
if pip_egg_info_exists:
421+
egg_info_path = pip_egg_info_path
422+
else:
423+
egg_info_path = debian_egg_info_path
424+
paths_to_remove.add(egg_info_path)
415425
if dist.has_metadata('installed-files.txt'):
416426
for installed_file in dist.get_metadata('installed-files.txt').splitlines():
417-
path = os.path.normpath(os.path.join(pip_egg_info_path, installed_file))
427+
path = os.path.normpath(os.path.join(egg_info_path, installed_file))
418428
paths_to_remove.add(path)
419429
if dist.has_metadata('top_level.txt'):
420430
if dist.has_metadata('namespace_packages.txt'):

tests/test_compat.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""
2+
Tests for compatibility workarounds.
3+
4+
"""
5+
import os
6+
from test_pip import reset_env, run_pip, pyversion, assert_all_changes
7+
8+
9+
def test_debian_egg_name_workaround():
10+
"""
11+
We can uninstall packages installed with the pyversion removed from the
12+
egg-info metadata directory name.
13+
14+
Refs:
15+
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618367
16+
https://bugs.launchpad.net/ubuntu/+source/distribute/+bug/725178
17+
https://bitbucket.org/ianb/pip/issue/104/pip-uninstall-on-ubuntu-linux
18+
19+
"""
20+
env = reset_env()
21+
result = run_pip('install', 'INITools==0.2', expect_error=True)
22+
23+
egg_info = os.path.join(
24+
env.site_packages, "INITools-0.2-py%s.egg-info" % pyversion)
25+
26+
# Debian only removes pyversion for global installs, not inside a venv
27+
# so even if this test runs on a Debian/Ubuntu system with broken setuptools,
28+
# since our test runs inside a venv we'll still have the normal .egg-info
29+
assert egg_info in result.files_created, "Couldn't find %s" % egg_info
30+
31+
# The Debian no-pyversion version of the .egg-info
32+
mangled = os.path.join(env.site_packages, "INITools-0.2.egg-info")
33+
assert mangled not in result.files_created, "Found unexpected %s" % mangled
34+
35+
# Simulate a Debian install by copying the .egg-info to their name for it
36+
full_egg_info = os.path.join(env.root_path, egg_info)
37+
assert os.path.isdir(full_egg_info)
38+
full_mangled = os.path.join(env.root_path, mangled)
39+
os.renames(full_egg_info, full_mangled)
40+
assert os.path.isdir(full_mangled)
41+
42+
# Try the uninstall and verify that everything is removed.
43+
result2 = run_pip("uninstall", "INITools", "-y")
44+
assert_all_changes(result, result2, [env.venv/'build', 'cache'])

0 commit comments

Comments
 (0)