Skip to content

Commit

Permalink
added feature to confirm dependencies of uninstalling packages
Browse files Browse the repository at this point in the history
  • Loading branch information
aodag committed Jul 14, 2017
1 parent 26c5c4e commit 17bc4b7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions news/4245.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
added confirming dependencies to ``uninstall`` command.
5 changes: 5 additions & 0 deletions pip/commands/uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pip.basecommand import Command
from pip.exceptions import InstallationError
from pip.req import InstallRequirement, parse_requirements
from pip.utils import get_installed_distributions, confirm_dependencies


class UninstallCommand(Command):
Expand Down Expand Up @@ -63,7 +64,11 @@ def run(self, options, args):
'You must give at least one requirement to %(name)s (see '
'"pip help %(name)s")' % dict(name=self.name)
)
installed_packages = get_installed_distributions()
for req in reqs_to_uninstall.values():
if not (options.yes or
confirm_dependencies(req, installed_packages)):
continue
req.uninstall(
auto_confirm=options.yes, verbose=options.verbose != 0
)
Expand Down
14 changes: 14 additions & 0 deletions pip/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,3 +862,17 @@ def enum(*sequential, **named):
reverse = dict((value, key) for key, value in enums.items())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)


def confirm_dependencies(req, installed_packages):
dep_keys = set()
for dist in installed_packages:
dep_keys.update(
[dist for d in dist.requires() if d.key == req.req.name])
if not dep_keys:
return True
logger.info("%s is depended from:" % req.req)
for dep in dep_keys:
logger.info(dep)
response = ask('Proceed (y/n)? ', ('y', 'n'))
return response == 'y'
35 changes: 35 additions & 0 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
from pip.utils.hashes import Hashes, MissingHashes
from pip.utils.packaging import check_dist_requires_python
from pip.utils.temp_dir import TempDirectory
from pip._vendor.six import BytesIO
from pip._vendor.packaging.requirements import Requirement
from pip.req.req_install import InstallRequirement


class Tests_EgglinkPath:
Expand Down Expand Up @@ -592,3 +595,35 @@ def test_check_requires(self, metadata, should_raise):
check_dist_requires_python(fake_dist)
else:
check_dist_requires_python(fake_dist)


@pytest.mark.parametrize(
"installed_requires,confirm_answer",
[
((), None),
(("dummy",), 'y'),
pytest.mark.xfail((("dummy",), 'n')),
],
)
def test_confirm_dependencies(installed_requires, confirm_answer):
from pip.commands.uninstall import confirm_dependencies
with patch('pip.utils.ask') as mock_ask:
mock_ask.return_value = confirm_answer

class req(Requirement):
def __init__(self, key):
self.key = key

class installed(object):

def __init__(self, requires):
self._requires = [req(r) for r in requires]

def requires(self):
return self._requires

requirement = InstallRequirement(Requirement("dummy"), None)
installed_packages = [installed(installed_requires)]
assert confirm_dependencies(requirement, installed_packages)
if confirm_answer:
mock_ask.assert_called_with('Proceed (y/n)? ', ('y', 'n'))

0 comments on commit 17bc4b7

Please sign in to comment.