2012-09-07 18:32:45 +02:00
|
|
|
from __future__ import with_statement
|
|
|
|
|
2017-03-20 03:08:31 +01:00
|
|
|
import json
|
2018-06-14 09:02:37 +02:00
|
|
|
import logging
|
2013-01-23 05:52:35 +01:00
|
|
|
import os
|
2010-06-03 04:25:26 +02:00
|
|
|
import sys
|
2017-05-16 12:16:30 +02:00
|
|
|
import textwrap
|
2014-01-28 15:17:51 +01:00
|
|
|
from os.path import join, normpath
|
2010-02-24 11:24:55 +01:00
|
|
|
from tempfile import mkdtemp
|
|
|
|
|
2017-05-16 12:16:30 +02:00
|
|
|
import pretend
|
|
|
|
import pytest
|
2017-06-13 14:17:00 +02:00
|
|
|
|
2018-08-21 17:07:40 +02:00
|
|
|
from pip._internal.req.constructors import install_req_from_line
|
2017-08-31 17:48:18 +02:00
|
|
|
from pip._internal.utils.misc import rmtree
|
2017-05-16 12:16:30 +02:00
|
|
|
from tests.lib import assert_all_changes, create_test_package_with_setup
|
|
|
|
from tests.lib.local_repos import local_checkout, local_repo
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2011-05-04 09:44:02 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2017-12-16 19:13:46 +01:00
|
|
|
def test_basic_uninstall(script):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2017-12-16 19:13:46 +01:00
|
|
|
Test basic install and uninstall.
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2013-08-21 11:16:07 +02:00
|
|
|
result = script.pip('install', 'INITools==0.2')
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(script.site_packages, 'initools') in result.files_created, (
|
|
|
|
sorted(result.files_created.keys())
|
|
|
|
)
|
|
|
|
# the import forces the generation of __pycache__ if the version of python
|
|
|
|
# supports it
|
2013-08-21 11:16:07 +02:00
|
|
|
script.run('python', '-c', "import initools")
|
|
|
|
result2 = script.pip('uninstall', 'INITools', '-y')
|
2014-02-24 22:52:23 +01:00
|
|
|
assert_all_changes(result, result2, [script.venv / 'build', 'cache'])
|
2010-02-24 11:24:55 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2017-12-16 19:13:46 +01:00
|
|
|
def test_basic_uninstall_distutils(script):
|
2016-01-20 06:50:18 +01:00
|
|
|
"""
|
2017-12-16 19:13:46 +01:00
|
|
|
Test basic install and uninstall.
|
2016-01-20 06:50:18 +01:00
|
|
|
|
|
|
|
"""
|
|
|
|
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')
|
2017-03-20 03:08:31 +01:00
|
|
|
result = script.pip('list', '--format=json')
|
|
|
|
assert {"name": "distutils-install", "version": "0.1"} \
|
|
|
|
in json.loads(result.stdout)
|
2017-03-20 15:18:41 +01:00
|
|
|
result = script.pip('uninstall', 'distutils_install', '-y',
|
|
|
|
expect_stderr=True, expect_error=True)
|
2017-03-21 12:28:22 +01:00
|
|
|
assert (
|
2017-03-20 15:18:41 +01:00
|
|
|
"Cannot uninstall 'distutils-install'. 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."
|
2017-03-21 12:28:22 +01:00
|
|
|
) in result.stderr
|
2016-01-20 06:50:18 +01:00
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2017-12-16 19:13:46 +01:00
|
|
|
def test_basic_uninstall_with_scripts(script):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Uninstall an easy_installed package with scripts.
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2018-10-08 18:09:53 +02:00
|
|
|
result = script.easy_install('PyLogo', expect_stderr=True)
|
2014-01-28 15:17:51 +01:00
|
|
|
easy_install_pth = script.site_packages / 'easy-install.pth'
|
2010-05-26 14:06:27 +02:00
|
|
|
pylogo = sys.platform == 'win32' and 'pylogo' or 'PyLogo'
|
2010-05-03 04:08:03 +02:00
|
|
|
assert(pylogo in result.files_updated[easy_install_pth].bytes)
|
2013-08-22 12:49:40 +02:00
|
|
|
result2 = script.pip('uninstall', 'pylogo', '-y')
|
2014-01-28 15:17:51 +01:00
|
|
|
assert_all_changes(
|
|
|
|
result,
|
|
|
|
result2,
|
2014-02-24 22:52:23 +01:00
|
|
|
[script.venv / 'build', 'cache', easy_install_pth],
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2010-02-24 11:24:55 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2013-08-22 06:40:46 +02:00
|
|
|
def test_uninstall_easy_install_after_import(script):
|
2012-08-19 00:26:17 +02:00
|
|
|
"""
|
|
|
|
Uninstall an easy_installed package after it's been imported
|
|
|
|
|
|
|
|
"""
|
2018-10-08 18:09:53 +02:00
|
|
|
result = script.easy_install('--always-unzip', 'INITools==0.2',
|
|
|
|
expect_stderr=True)
|
2014-01-28 15:17:51 +01:00
|
|
|
# the import forces the generation of __pycache__ if the version of python
|
|
|
|
# supports it
|
2013-08-21 11:16:07 +02:00
|
|
|
script.run('python', '-c', "import initools")
|
|
|
|
result2 = script.pip('uninstall', 'INITools', '-y')
|
2014-01-28 15:17:51 +01:00
|
|
|
assert_all_changes(
|
|
|
|
result,
|
|
|
|
result2,
|
2014-02-24 22:52:23 +01:00
|
|
|
[
|
|
|
|
script.venv / 'build',
|
|
|
|
'cache',
|
|
|
|
script.site_packages / 'easy-install.pth',
|
|
|
|
]
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2012-08-19 00:26:17 +02:00
|
|
|
|
|
|
|
|
2017-11-05 16:36:16 +01:00
|
|
|
@pytest.mark.network
|
|
|
|
def test_uninstall_trailing_newline(script):
|
|
|
|
"""
|
|
|
|
Uninstall behaves appropriately if easy-install.pth
|
|
|
|
lacks a trailing newline
|
|
|
|
|
|
|
|
"""
|
2018-10-08 18:09:53 +02:00
|
|
|
script.easy_install('INITools==0.2', expect_stderr=True)
|
|
|
|
script.easy_install('PyLogo', expect_stderr=True)
|
2017-11-05 16:36:16 +01:00
|
|
|
easy_install_pth = script.site_packages_path / 'easy-install.pth'
|
|
|
|
|
|
|
|
# trim trailing newline from easy-install.pth
|
|
|
|
with open(easy_install_pth) as f:
|
|
|
|
pth_before = f.read()
|
|
|
|
|
|
|
|
with open(easy_install_pth, 'w') as f:
|
|
|
|
f.write(pth_before.rstrip())
|
|
|
|
|
|
|
|
# uninstall initools
|
|
|
|
script.pip('uninstall', 'INITools', '-y')
|
|
|
|
with open(easy_install_pth) as f:
|
|
|
|
pth_after = f.read()
|
|
|
|
|
|
|
|
# verify that only initools is removed
|
|
|
|
before_without_initools = [
|
|
|
|
line for line in pth_before.splitlines()
|
|
|
|
if 'initools' not in line.lower()
|
|
|
|
]
|
|
|
|
lines_after = pth_after.splitlines()
|
|
|
|
|
|
|
|
assert lines_after == before_without_initools
|
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2017-12-16 19:13:46 +01:00
|
|
|
def test_basic_uninstall_namespace_package(script):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2010-02-24 11:24:55 +01:00
|
|
|
Uninstall a distribution with a namespace package without clobbering
|
2010-02-25 00:16:43 +01:00
|
|
|
the namespace and everything in it.
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2013-08-21 11:16:07 +02:00
|
|
|
result = script.pip('install', 'pd.requires==0.0.3', expect_error=True)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(script.site_packages, 'pd') in result.files_created, (
|
|
|
|
sorted(result.files_created.keys())
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('uninstall', 'pd.find', '-y', expect_error=True)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(script.site_packages, 'pd') not in result2.files_deleted, (
|
|
|
|
sorted(result2.files_deleted.keys())
|
|
|
|
)
|
|
|
|
assert join(script.site_packages, 'pd', 'find') in result2.files_deleted, (
|
|
|
|
sorted(result2.files_deleted.keys())
|
|
|
|
)
|
2010-02-24 11:24:55 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2013-08-23 13:12:37 +02:00
|
|
|
def test_uninstall_overlapping_package(script, data):
|
2012-07-09 09:04:46 +02:00
|
|
|
"""
|
|
|
|
Uninstalling a distribution that adds modules to a pre-existing package
|
|
|
|
should only remove those added modules, not the rest of the existing
|
|
|
|
package.
|
|
|
|
|
|
|
|
See: GitHub issue #355 (pip uninstall removes things it didn't install)
|
|
|
|
"""
|
2013-08-23 13:12:37 +02:00
|
|
|
parent_pkg = data.packages.join("parent-0.1.tar.gz")
|
|
|
|
child_pkg = data.packages.join("child-0.1.tar.gz")
|
|
|
|
|
2013-08-21 11:16:07 +02:00
|
|
|
result1 = script.pip('install', parent_pkg, expect_error=False)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(script.site_packages, 'parent') in result1.files_created, (
|
|
|
|
sorted(result1.files_created.keys())
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('install', child_pkg, expect_error=False)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(script.site_packages, 'child') in result2.files_created, (
|
|
|
|
sorted(result2.files_created.keys())
|
|
|
|
)
|
|
|
|
assert normpath(
|
|
|
|
join(script.site_packages, 'parent/plugins/child_plugin.py')
|
|
|
|
) in result2.files_created, sorted(result2.files_created.keys())
|
|
|
|
# The import forces the generation of __pycache__ if the version of python
|
|
|
|
# supports it
|
2013-08-21 11:16:07 +02:00
|
|
|
script.run('python', '-c', "import parent.plugins.child_plugin, child")
|
|
|
|
result3 = script.pip('uninstall', '-y', 'child', expect_error=False)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(script.site_packages, 'child') in result3.files_deleted, (
|
|
|
|
sorted(result3.files_created.keys())
|
|
|
|
)
|
|
|
|
assert normpath(
|
|
|
|
join(script.site_packages, 'parent/plugins/child_plugin.py')
|
|
|
|
) in result3.files_deleted, sorted(result3.files_deleted.keys())
|
|
|
|
assert join(script.site_packages, 'parent') not in result3.files_deleted, (
|
|
|
|
sorted(result3.files_deleted.keys())
|
|
|
|
)
|
2012-07-09 09:04:46 +02:00
|
|
|
# Additional check: uninstalling 'child' should return things to the
|
|
|
|
# previous state, without unintended side effects.
|
|
|
|
assert_all_changes(result2, result3, [])
|
|
|
|
|
|
|
|
|
2016-11-19 00:27:16 +01:00
|
|
|
@pytest.mark.parametrize("console_scripts",
|
|
|
|
["test_ = distutils_install",
|
|
|
|
"test_:test_ = distutils_install"])
|
|
|
|
def test_uninstall_entry_point(script, console_scripts):
|
2016-02-01 10:03:19 +01:00
|
|
|
"""
|
|
|
|
Test uninstall package with two or more entry points in the same section,
|
|
|
|
whose name contain a colon.
|
|
|
|
"""
|
2016-11-19 00:27:16 +01:00
|
|
|
pkg_name = 'ep_install'
|
|
|
|
pkg_path = create_test_package_with_setup(
|
|
|
|
script,
|
|
|
|
name=pkg_name,
|
|
|
|
version='0.1',
|
|
|
|
entry_points={"console_scripts": [console_scripts, ],
|
|
|
|
"pip_test.ep":
|
|
|
|
["ep:name1 = distutils_install",
|
|
|
|
"ep:name2 = distutils_install"]
|
|
|
|
}
|
|
|
|
)
|
|
|
|
script_name = script.bin_path.join(console_scripts.split('=')[0].strip())
|
2017-10-06 21:51:42 +02:00
|
|
|
if sys.platform == 'win32':
|
|
|
|
script_name += '.exe'
|
2016-02-01 10:03:19 +01:00
|
|
|
result = script.pip('install', pkg_path)
|
2016-11-19 00:27:16 +01:00
|
|
|
assert script_name.exists
|
2017-03-20 03:08:31 +01:00
|
|
|
result = script.pip('list', '--format=json')
|
|
|
|
assert {"name": "ep-install", "version": "0.1"} \
|
|
|
|
in json.loads(result.stdout)
|
2016-02-01 23:17:11 +01:00
|
|
|
script.pip('uninstall', 'ep_install', '-y')
|
2016-11-19 00:27:16 +01:00
|
|
|
assert not script_name.exists
|
2017-03-20 03:08:31 +01:00
|
|
|
result2 = script.pip('list', '--format=json')
|
|
|
|
assert {"name": "ep-install", "version": "0.1"} \
|
|
|
|
not in json.loads(result2.stdout)
|
2016-02-01 10:03:19 +01:00
|
|
|
|
|
|
|
|
2016-11-19 00:27:16 +01:00
|
|
|
def test_uninstall_gui_scripts(script):
|
|
|
|
"""
|
|
|
|
Make sure that uninstall removes gui scripts
|
|
|
|
"""
|
|
|
|
pkg_name = "gui_pkg"
|
|
|
|
pkg_path = create_test_package_with_setup(
|
|
|
|
script,
|
|
|
|
name=pkg_name,
|
|
|
|
version='0.1',
|
|
|
|
entry_points={"gui_scripts": ["test_ = distutils_install", ], }
|
|
|
|
)
|
|
|
|
script_name = script.bin_path.join('test_')
|
2017-10-06 21:51:42 +02:00
|
|
|
if sys.platform == 'win32':
|
|
|
|
script_name += '.exe'
|
2016-11-19 00:27:16 +01:00
|
|
|
script.pip('install', pkg_path)
|
|
|
|
assert script_name.exists
|
|
|
|
script.pip('uninstall', pkg_name, '-y')
|
|
|
|
assert not script_name.exists
|
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2013-08-22 06:40:46 +02:00
|
|
|
def test_uninstall_console_scripts(script):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
Test uninstalling a package with more files (console_script entry points,
|
|
|
|
extra directories).
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2011-03-15 20:49:48 +01:00
|
|
|
args = ['install']
|
2011-03-19 06:54:04 +01:00
|
|
|
args.append('discover')
|
2013-08-21 11:16:07 +02:00
|
|
|
result = script.pip(*args, **{"expect_error": True})
|
2014-02-24 22:52:23 +01:00
|
|
|
assert script.bin / 'discover' + script.exe in result.files_created, (
|
2014-01-28 15:17:51 +01:00
|
|
|
sorted(result.files_created.keys())
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('uninstall', 'discover', '-y', expect_error=True)
|
2014-02-24 22:52:23 +01:00
|
|
|
assert_all_changes(result, result2, [script.venv / 'build', 'cache'])
|
2010-02-24 11:24:55 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2013-08-22 06:40:46 +02:00
|
|
|
def test_uninstall_easy_installed_console_scripts(script):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test uninstalling package with console_scripts that is easy_installed.
|
|
|
|
"""
|
2018-10-08 18:09:53 +02:00
|
|
|
result = script.easy_install('discover', expect_error=True)
|
2014-02-24 22:52:23 +01:00
|
|
|
assert script.bin / 'discover' + script.exe in result.files_created, (
|
2014-01-28 15:17:51 +01:00
|
|
|
sorted(result.files_created.keys())
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('uninstall', 'discover', '-y')
|
2014-01-28 15:17:51 +01:00
|
|
|
assert_all_changes(
|
|
|
|
result,
|
|
|
|
result2,
|
2014-02-24 22:52:23 +01:00
|
|
|
[
|
|
|
|
script.venv / 'build',
|
|
|
|
'cache',
|
|
|
|
script.site_packages / 'easy-install.pth',
|
|
|
|
]
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2010-02-24 11:24:55 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2013-08-22 12:14:09 +02:00
|
|
|
def test_uninstall_editable_from_svn(script, tmpdir):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test uninstalling an editable installation from svn.
|
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
result = script.pip(
|
|
|
|
'install', '-e',
|
2017-02-13 10:02:20 +01:00
|
|
|
'%s#egg=initools' % local_checkout(
|
2014-01-28 15:17:51 +01:00
|
|
|
'svn+http://svn.colorstudy.com/INITools/trunk',
|
|
|
|
tmpdir.join("cache"),
|
|
|
|
),
|
|
|
|
)
|
2010-04-28 22:55:10 +02:00
|
|
|
result.assert_installed('INITools')
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('uninstall', '-y', 'initools')
|
2014-02-24 22:52:23 +01:00
|
|
|
assert (script.venv / 'src' / 'initools' in result2.files_after)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert_all_changes(
|
|
|
|
result,
|
|
|
|
result2,
|
|
|
|
[
|
2014-02-24 22:52:23 +01:00
|
|
|
script.venv / 'src',
|
|
|
|
script.venv / 'build',
|
|
|
|
script.site_packages / 'easy-install.pth'
|
2014-01-28 15:17:51 +01:00
|
|
|
],
|
|
|
|
)
|
2010-02-24 11:24:55 +01:00
|
|
|
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2013-08-22 12:14:09 +02:00
|
|
|
def test_uninstall_editable_with_source_outside_venv(script, tmpdir):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test uninstalling editable install from existing source outside the venv.
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2013-08-22 12:14:09 +02:00
|
|
|
cache_dir = tmpdir.join("cache")
|
|
|
|
|
2010-09-13 07:21:10 +02:00
|
|
|
try:
|
|
|
|
temp = mkdtemp()
|
2014-04-16 17:53:56 +02:00
|
|
|
tmpdir = join(temp, 'pip-test-package')
|
2014-01-28 15:17:51 +01:00
|
|
|
_test_uninstall_editable_with_source_outside_venv(
|
|
|
|
script,
|
|
|
|
tmpdir,
|
|
|
|
cache_dir,
|
|
|
|
)
|
2010-09-13 07:21:10 +02:00
|
|
|
finally:
|
2011-03-19 20:57:37 +01:00
|
|
|
rmtree(temp)
|
2010-09-13 07:21:10 +02:00
|
|
|
|
|
|
|
|
2014-01-28 15:17:51 +01:00
|
|
|
def _test_uninstall_editable_with_source_outside_venv(
|
|
|
|
script, tmpdir, cache_dir):
|
|
|
|
result = script.run(
|
|
|
|
'git', 'clone',
|
|
|
|
local_repo(
|
2014-04-16 17:53:56 +02:00
|
|
|
'git+git://github.com/pypa/pip-test-package',
|
2014-01-28 15:17:51 +01:00
|
|
|
cache_dir,
|
|
|
|
),
|
|
|
|
tmpdir,
|
|
|
|
expect_stderr=True,
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('install', '-e', tmpdir)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert join(
|
2014-04-16 17:53:56 +02:00
|
|
|
script.site_packages, 'pip-test-package.egg-link'
|
2014-01-28 15:17:51 +01:00
|
|
|
) in result2.files_created, list(result2.files_created.keys())
|
2014-04-21 04:15:36 +02:00
|
|
|
result3 = script.pip('uninstall', '-y',
|
|
|
|
'pip-test-package', expect_error=True)
|
2014-01-28 15:17:51 +01:00
|
|
|
assert_all_changes(
|
|
|
|
result,
|
|
|
|
result3,
|
2014-02-24 22:52:23 +01:00
|
|
|
[script.venv / 'build', script.site_packages / 'easy-install.pth'],
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2010-06-03 04:25:26 +02:00
|
|
|
|
|
|
|
|
2015-01-15 00:53:15 +01:00
|
|
|
@pytest.mark.network
|
2018-11-10 12:43:20 +01:00
|
|
|
@pytest.mark.svn
|
2013-08-22 12:14:09 +02:00
|
|
|
def test_uninstall_from_reqs_file(script, tmpdir):
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
|
|
|
Test uninstall from a requirements file.
|
2010-06-03 04:25:26 +02:00
|
|
|
|
2010-02-25 00:16:43 +01:00
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
script.scratch_path.join("test-req.txt").write(
|
|
|
|
textwrap.dedent("""
|
2017-02-13 10:02:20 +01:00
|
|
|
-e %s#egg=initools
|
2014-01-28 15:17:51 +01:00
|
|
|
# and something else to test out:
|
|
|
|
PyLogo<0.4
|
|
|
|
""") %
|
|
|
|
local_checkout(
|
|
|
|
'svn+http://svn.colorstudy.com/INITools/trunk',
|
|
|
|
tmpdir.join("cache")
|
|
|
|
)
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result = script.pip('install', '-r', 'test-req.txt')
|
2014-01-28 15:17:51 +01:00
|
|
|
script.scratch_path.join("test-req.txt").write(
|
|
|
|
textwrap.dedent("""
|
|
|
|
# -f, -i, and --extra-index-url should all be ignored by uninstall
|
|
|
|
-f http://www.example.com
|
|
|
|
-i http://www.example.com
|
|
|
|
--extra-index-url http://www.example.com
|
|
|
|
|
2017-02-13 10:02:20 +01:00
|
|
|
-e %s#egg=initools
|
2014-01-28 15:17:51 +01:00
|
|
|
# and something else to test out:
|
|
|
|
PyLogo<0.4
|
|
|
|
""") %
|
|
|
|
local_checkout(
|
|
|
|
'svn+http://svn.colorstudy.com/INITools/trunk',
|
|
|
|
tmpdir.join("cache")
|
|
|
|
)
|
|
|
|
)
|
2013-08-21 11:16:07 +02:00
|
|
|
result2 = script.pip('uninstall', '-r', 'test-req.txt', '-y')
|
2010-05-03 04:08:03 +02:00
|
|
|
assert_all_changes(
|
2014-01-28 15:17:51 +01:00
|
|
|
result,
|
|
|
|
result2,
|
|
|
|
[
|
2014-02-24 22:52:23 +01:00
|
|
|
script.venv / 'build',
|
|
|
|
script.venv / 'src',
|
|
|
|
script.scratch / 'test-req.txt',
|
|
|
|
script.site_packages / 'easy-install.pth',
|
2014-01-28 15:17:51 +01:00
|
|
|
],
|
|
|
|
)
|
2012-05-22 12:54:40 +02:00
|
|
|
|
|
|
|
|
2014-08-31 01:52:28 +02:00
|
|
|
def test_uninstallpathset_no_paths(caplog):
|
2012-06-26 07:35:27 +02:00
|
|
|
"""
|
2014-01-28 15:17:51 +01:00
|
|
|
Test UninstallPathSet logs notification when there are no paths to
|
|
|
|
uninstall
|
2012-06-26 07:35:27 +02:00
|
|
|
"""
|
2017-08-31 17:48:18 +02:00
|
|
|
from pip._internal.req.req_uninstall import UninstallPathSet
|
2012-09-03 19:55:29 +02:00
|
|
|
from pkg_resources import get_distribution
|
2018-06-14 09:02:37 +02:00
|
|
|
|
|
|
|
caplog.set_level(logging.INFO)
|
|
|
|
|
2012-09-03 19:55:29 +02:00
|
|
|
test_dist = get_distribution('pip')
|
2016-01-20 21:25:51 +01:00
|
|
|
uninstall_set = UninstallPathSet(test_dist)
|
|
|
|
uninstall_set.remove() # with no files added to set
|
2014-08-31 01:52:28 +02:00
|
|
|
|
|
|
|
assert (
|
|
|
|
"Can't uninstall 'pip'. No files were found to uninstall."
|
2017-03-20 16:45:29 +01:00
|
|
|
in caplog.text
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2012-09-03 19:55:29 +02:00
|
|
|
|
2012-09-04 21:40:50 +02:00
|
|
|
|
2016-01-20 21:25:51 +01:00
|
|
|
def test_uninstall_non_local_distutils(caplog, monkeypatch, tmpdir):
|
|
|
|
einfo = tmpdir.join("thing-1.0.egg-info")
|
|
|
|
with open(einfo, "wb"):
|
|
|
|
pass
|
2014-08-31 01:52:28 +02:00
|
|
|
|
2016-01-20 21:25:51 +01:00
|
|
|
dist = pretend.stub(
|
|
|
|
key="thing",
|
|
|
|
project_name="thing",
|
|
|
|
egg_info=einfo,
|
|
|
|
location=einfo,
|
|
|
|
_provider=pretend.stub(),
|
2014-01-28 15:17:51 +01:00
|
|
|
)
|
2016-01-20 21:25:51 +01:00
|
|
|
get_dist = pretend.call_recorder(lambda x: dist)
|
|
|
|
monkeypatch.setattr("pip._vendor.pkg_resources.get_distribution", get_dist)
|
|
|
|
|
2018-08-21 17:07:40 +02:00
|
|
|
req = install_req_from_line("thing")
|
2016-01-20 21:25:51 +01:00
|
|
|
req.uninstall()
|
|
|
|
|
|
|
|
assert os.path.exists(einfo)
|
2014-04-22 08:07:25 +02:00
|
|
|
|
2014-04-25 23:42:14 +02:00
|
|
|
|
2014-04-22 08:07:25 +02:00
|
|
|
def test_uninstall_wheel(script, data):
|
|
|
|
"""
|
|
|
|
Test uninstalling a wheel
|
|
|
|
"""
|
|
|
|
package = data.packages.join("simple.dist-0.1-py2.py3-none-any.whl")
|
|
|
|
result = script.pip('install', package, '--no-index')
|
|
|
|
dist_info_folder = script.site_packages / 'simple.dist-0.1.dist-info'
|
|
|
|
assert dist_info_folder in result.files_created
|
|
|
|
result2 = script.pip('uninstall', 'simple.dist', '-y')
|
|
|
|
assert_all_changes(result, result2, [])
|
2015-02-24 15:53:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_uninstall_setuptools_develop_install(script, data):
|
|
|
|
"""Try uninstall after setup.py develop followed of setup.py install"""
|
|
|
|
pkg_path = data.packages.join("FSPkg")
|
|
|
|
script.run('python', 'setup.py', 'develop',
|
|
|
|
expect_stderr=True, cwd=pkg_path)
|
|
|
|
script.run('python', 'setup.py', 'install',
|
|
|
|
expect_stderr=True, cwd=pkg_path)
|
2017-03-20 03:08:31 +01:00
|
|
|
list_result = script.pip('list', '--format=json')
|
2017-10-06 21:51:42 +02:00
|
|
|
assert {"name": os.path.normcase("FSPkg"), "version": "0.1.dev0"} \
|
|
|
|
in json.loads(list_result.stdout), str(list_result)
|
2015-02-24 15:53:25 +01:00
|
|
|
# Uninstall both develop and install
|
|
|
|
uninstall = script.pip('uninstall', 'FSPkg', '-y')
|
|
|
|
assert any(filename.endswith('.egg')
|
|
|
|
for filename in uninstall.files_deleted.keys())
|
|
|
|
uninstall2 = script.pip('uninstall', 'FSPkg', '-y')
|
|
|
|
assert join(
|
|
|
|
script.site_packages, 'FSPkg.egg-link'
|
|
|
|
) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys())
|
2017-03-20 03:08:31 +01:00
|
|
|
list_result2 = script.pip('list', '--format=json')
|
|
|
|
assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)}
|
2016-08-26 12:03:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_uninstall_editable_and_pip_install(script, data):
|
|
|
|
"""Try uninstall after pip install -e after pip install"""
|
|
|
|
# SETUPTOOLS_SYS_PATH_TECHNIQUE=raw removes the assumption that `-e`
|
|
|
|
# installs are always higher priority than regular installs.
|
|
|
|
# This becomes the default behavior in setuptools 25.
|
|
|
|
script.environ['SETUPTOOLS_SYS_PATH_TECHNIQUE'] = 'raw'
|
|
|
|
|
|
|
|
pkg_path = data.packages.join("FSPkg")
|
|
|
|
script.pip('install', '-e', '.',
|
|
|
|
expect_stderr=True, cwd=pkg_path)
|
|
|
|
# ensure both are installed with --ignore-installed:
|
|
|
|
script.pip('install', '--ignore-installed', '.',
|
|
|
|
expect_stderr=True, cwd=pkg_path)
|
2017-03-20 03:08:31 +01:00
|
|
|
list_result = script.pip('list', '--format=json')
|
|
|
|
assert {"name": "FSPkg", "version": "0.1.dev0"} \
|
|
|
|
in json.loads(list_result.stdout)
|
2016-08-26 12:03:35 +02:00
|
|
|
# Uninstall both develop and install
|
|
|
|
uninstall = script.pip('uninstall', 'FSPkg', '-y')
|
|
|
|
assert not any(filename.endswith('.egg-link')
|
|
|
|
for filename in uninstall.files_deleted.keys())
|
|
|
|
uninstall2 = script.pip('uninstall', 'FSPkg', '-y')
|
|
|
|
assert join(
|
|
|
|
script.site_packages, 'FSPkg.egg-link'
|
|
|
|
) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys())
|
2017-03-20 03:08:31 +01:00
|
|
|
list_result2 = script.pip('list', '--format=json')
|
|
|
|
assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)}
|
2017-08-03 01:25:21 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_uninstall_ignores_missing_packages(script, data):
|
|
|
|
"""Uninstall of a non existent package prints a warning and exits cleanly
|
|
|
|
"""
|
|
|
|
result = script.pip(
|
|
|
|
'uninstall', '-y', 'non-existent-pkg', expect_stderr=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert "Skipping non-existent-pkg as it is not installed." in result.stderr
|
|
|
|
assert result.returncode == 0, "Expected clean exit"
|
|
|
|
|
|
|
|
|
|
|
|
def test_uninstall_ignores_missing_packages_and_uninstalls_rest(script, data):
|
|
|
|
script.pip_install_local('simple')
|
|
|
|
result = script.pip(
|
|
|
|
'uninstall', '-y', 'non-existent-pkg', 'simple', expect_stderr=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert "Skipping non-existent-pkg as it is not installed." in result.stderr
|
|
|
|
assert "Successfully uninstalled simple" in result.stdout
|
|
|
|
assert result.returncode == 0, "Expected clean exit"
|