python (3.12.0)
1 import logging
2 from optparse import Values
3 from typing import List
4
5 from pip._vendor.packaging.utils import canonicalize_name
6
7 from pip._internal.cli import cmdoptions
8 from pip._internal.cli.base_command import Command
9 from pip._internal.cli.req_command import SessionCommandMixin, warn_if_run_as_root
10 from pip._internal.cli.status_codes import SUCCESS
11 from pip._internal.exceptions import InstallationError
12 from pip._internal.req import parse_requirements
13 from pip._internal.req.constructors import (
14 install_req_from_line,
15 install_req_from_parsed_requirement,
16 )
17 from pip._internal.utils.misc import (
18 check_externally_managed,
19 protect_pip_from_modification_on_windows,
20 )
21
22 logger = logging.getLogger(__name__)
23
24
25 class ESC[4;38;5;81mUninstallCommand(ESC[4;38;5;149mCommand, ESC[4;38;5;149mSessionCommandMixin):
26 """
27 Uninstall packages.
28
29 pip is able to uninstall most installed packages. Known exceptions are:
30
31 - Pure distutils packages installed with ``python setup.py install``, which
32 leave behind no metadata to determine what files were installed.
33 - Script wrappers installed by ``python setup.py develop``.
34 """
35
36 usage = """
37 %prog [options] <package> ...
38 %prog [options] -r <requirements file> ..."""
39
40 def add_options(self) -> None:
41 self.cmd_opts.add_option(
42 "-r",
43 "--requirement",
44 dest="requirements",
45 action="append",
46 default=[],
47 metavar="file",
48 help=(
49 "Uninstall all the packages listed in the given requirements "
50 "file. This option can be used multiple times."
51 ),
52 )
53 self.cmd_opts.add_option(
54 "-y",
55 "--yes",
56 dest="yes",
57 action="store_true",
58 help="Don't ask for confirmation of uninstall deletions.",
59 )
60 self.cmd_opts.add_option(cmdoptions.root_user_action())
61 self.cmd_opts.add_option(cmdoptions.override_externally_managed())
62 self.parser.insert_option_group(0, self.cmd_opts)
63
64 def run(self, options: Values, args: List[str]) -> int:
65 session = self.get_default_session(options)
66
67 reqs_to_uninstall = {}
68 for name in args:
69 req = install_req_from_line(
70 name,
71 isolated=options.isolated_mode,
72 )
73 if req.name:
74 reqs_to_uninstall[canonicalize_name(req.name)] = req
75 else:
76 logger.warning(
77 "Invalid requirement: %r ignored -"
78 " the uninstall command expects named"
79 " requirements.",
80 name,
81 )
82 for filename in options.requirements:
83 for parsed_req in parse_requirements(
84 filename, options=options, session=session
85 ):
86 req = install_req_from_parsed_requirement(
87 parsed_req, isolated=options.isolated_mode
88 )
89 if req.name:
90 reqs_to_uninstall[canonicalize_name(req.name)] = req
91 if not reqs_to_uninstall:
92 raise InstallationError(
93 f"You must give at least one requirement to {self.name} (see "
94 f'"pip help {self.name}")'
95 )
96
97 if not options.override_externally_managed:
98 check_externally_managed()
99
100 protect_pip_from_modification_on_windows(
101 modifying_pip="pip" in reqs_to_uninstall
102 )
103
104 for req in reqs_to_uninstall.values():
105 uninstall_pathset = req.uninstall(
106 auto_confirm=options.yes,
107 verbose=self.verbosity > 0,
108 )
109 if uninstall_pathset:
110 uninstall_pathset.commit()
111 if options.root_user_action == "warn":
112 warn_if_run_as_root()
113 return SUCCESS