Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f71cae0

Browse files
committed
Issue #19728: fix ensurepip name clash with submodule
Also added refactoring and added basic tests for the argument parsing in both ensurepip._main and ensurepip._uninstall._main.
1 parent 23f597e commit f71cae0

4 files changed

Lines changed: 127 additions & 91 deletions

File tree

Lib/ensurepip/__init__.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def bootstrap(*, root=None, upgrade=False, user=False,
104104

105105
_run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
106106

107-
def _uninstall(*, verbosity=0):
107+
def _uninstall_helper(*, verbosity=0):
108108
"""Helper to support a clean default uninstall process on Windows
109109
110110
Note that calling this function may alter os.environ.
@@ -129,3 +129,64 @@ def _uninstall(*, verbosity=0):
129129
args += ["-" + "v" * verbosity]
130130

131131
_run_pip(args + [p[0] for p in reversed(_PROJECTS)])
132+
133+
134+
def _main(argv=None):
135+
import argparse
136+
parser = argparse.ArgumentParser(prog="python -m ensurepip")
137+
parser.add_argument(
138+
"--version",
139+
action="version",
140+
version="pip {}".format(version()),
141+
help="Show the version of pip that is bundled with this Python.",
142+
)
143+
parser.add_argument(
144+
"-v", "--verbose",
145+
action="count",
146+
default=0,
147+
dest="verbosity",
148+
help=("Give more output. Option is additive, and can be used up to 3 "
149+
"times."),
150+
)
151+
parser.add_argument(
152+
"-U", "--upgrade",
153+
action="store_true",
154+
default=False,
155+
help="Upgrade pip and dependencies, even if already installed.",
156+
)
157+
parser.add_argument(
158+
"--user",
159+
action="store_true",
160+
default=False,
161+
help="Install using the user scheme.",
162+
)
163+
parser.add_argument(
164+
"--root",
165+
default=None,
166+
help="Install everything relative to this alternate root directory.",
167+
)
168+
parser.add_argument(
169+
"--altinstall",
170+
action="store_true",
171+
default=False,
172+
help=("Make an alternate install, installing only the X.Y versioned"
173+
"scripts (Default: pipX, pipX.Y, easy_install-X.Y)"),
174+
)
175+
parser.add_argument(
176+
"--default-pip",
177+
action="store_true",
178+
default=False,
179+
help=("Make a default pip install, installing the unqualified pip "
180+
"and easy_install in addition to the versioned scripts"),
181+
)
182+
183+
args = parser.parse_args(argv)
184+
185+
bootstrap(
186+
root=args.root,
187+
upgrade=args.upgrade,
188+
user=args.user,
189+
verbosity=args.verbosity,
190+
altinstall=args.altinstall,
191+
default_pip=args.default_pip,
192+
)

Lib/ensurepip/__main__.py

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,4 @@
1-
import argparse
21
import ensurepip
32

4-
5-
def main():
6-
parser = argparse.ArgumentParser(prog="python -m ensurepip")
7-
parser.add_argument(
8-
"--version",
9-
action="version",
10-
version="pip {}".format(ensurepip.version()),
11-
help="Show the version of pip that is bundled with this Python.",
12-
)
13-
parser.add_argument(
14-
"-v", "--verbose",
15-
action="count",
16-
default=0,
17-
dest="verbosity",
18-
help=("Give more output. Option is additive, and can be used up to 3 "
19-
"times."),
20-
)
21-
parser.add_argument(
22-
"-U", "--upgrade",
23-
action="store_true",
24-
default=False,
25-
help="Upgrade pip and dependencies, even if already installed.",
26-
)
27-
parser.add_argument(
28-
"--user",
29-
action="store_true",
30-
default=False,
31-
help="Install using the user scheme.",
32-
)
33-
parser.add_argument(
34-
"--root",
35-
default=None,
36-
help="Install everything relative to this alternate root directory.",
37-
)
38-
parser.add_argument(
39-
"--altinstall",
40-
action="store_true",
41-
default=False,
42-
help=("Make an alternate install, installing only the X.Y versioned"
43-
"scripts (Default: pipX, pipX.Y, easy_install-X.Y)"),
44-
)
45-
parser.add_argument(
46-
"--default-pip",
47-
action="store_true",
48-
default=False,
49-
help=("Make a default pip install, installing the unqualified pip "
50-
"and easy_install in addition to the versioned scripts"),
51-
)
52-
53-
args = parser.parse_args()
54-
55-
ensurepip.bootstrap(
56-
root=args.root,
57-
upgrade=args.upgrade,
58-
user=args.user,
59-
verbosity=args.verbosity,
60-
altinstall=args.altinstall,
61-
default_pip=args.default_pip,
62-
)
63-
64-
653
if __name__ == "__main__":
66-
main()
4+
ensurepip._main()

Lib/ensurepip/_uninstall.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import ensurepip
55

66

7-
def main():
7+
def _main(argv=None):
88
parser = argparse.ArgumentParser(prog="python -m ensurepip._uninstall")
99
parser.add_argument(
1010
"--version",
@@ -21,10 +21,10 @@ def main():
2121
"times."),
2222
)
2323

24-
args = parser.parse_args()
24+
args = parser.parse_args(argv)
2525

26-
ensurepip._uninstall(verbosity=args.verbosity)
26+
ensurepip._uninstall_helper(verbosity=args.verbosity)
2727

2828

2929
if __name__ == "__main__":
30-
main()
30+
_main()

Lib/test/test_ensurepip.py

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import unittest
22
import unittest.mock
3-
import ensurepip
43
import test.support
54
import os
65
import os.path
76
import contextlib
87
import sys
98

9+
import ensurepip
10+
import ensurepip._uninstall
1011

1112
class TestEnsurePipVersion(unittest.TestCase):
1213

1314
def test_returns_version(self):
1415
self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version())
1516

16-
17-
class TestBootstrap(unittest.TestCase):
17+
class EnsurepipMixin:
1818

1919
def setUp(self):
2020
run_pip_patch = unittest.mock.patch("ensurepip._run_pip")
@@ -28,6 +28,8 @@ def setUp(self):
2828
patched_os.path = os.path
2929
self.os_environ = patched_os.environ = os.environ.copy()
3030

31+
class TestBootstrap(EnsurepipMixin, unittest.TestCase):
32+
3133
def test_basic_bootstrapping(self):
3234
ensurepip.bootstrap()
3335

@@ -153,59 +155,47 @@ class FakePip():
153155
else:
154156
sys.modules["pip"] = orig_pip
155157

156-
class TestUninstall(unittest.TestCase):
157-
158-
def setUp(self):
159-
run_pip_patch = unittest.mock.patch("ensurepip._run_pip")
160-
self.run_pip = run_pip_patch.start()
161-
self.addCleanup(run_pip_patch.stop)
162-
163-
# Avoid side effects on the actual os module
164-
os_patch = unittest.mock.patch("ensurepip.os")
165-
patched_os = os_patch.start()
166-
self.addCleanup(os_patch.stop)
167-
patched_os.path = os.path
168-
self.os_environ = patched_os.environ = os.environ.copy()
158+
class TestUninstall(EnsurepipMixin, unittest.TestCase):
169159

170160
def test_uninstall_skipped_when_not_installed(self):
171161
with fake_pip(None):
172-
ensurepip._uninstall()
162+
ensurepip._uninstall_helper()
173163
self.run_pip.assert_not_called()
174164

175165
def test_uninstall_fails_with_wrong_version(self):
176166
with fake_pip("not a valid version"):
177167
with self.assertRaises(RuntimeError):
178-
ensurepip._uninstall()
168+
ensurepip._uninstall_helper()
179169
self.run_pip.assert_not_called()
180170

181171

182172
def test_uninstall(self):
183173
with fake_pip():
184-
ensurepip._uninstall()
174+
ensurepip._uninstall_helper()
185175

186176
self.run_pip.assert_called_once_with(
187177
["uninstall", "-y", "pip", "setuptools"]
188178
)
189179

190180
def test_uninstall_with_verbosity_1(self):
191181
with fake_pip():
192-
ensurepip._uninstall(verbosity=1)
182+
ensurepip._uninstall_helper(verbosity=1)
193183

194184
self.run_pip.assert_called_once_with(
195185
["uninstall", "-y", "-v", "pip", "setuptools"]
196186
)
197187

198188
def test_uninstall_with_verbosity_2(self):
199189
with fake_pip():
200-
ensurepip._uninstall(verbosity=2)
190+
ensurepip._uninstall_helper(verbosity=2)
201191

202192
self.run_pip.assert_called_once_with(
203193
["uninstall", "-y", "-vv", "pip", "setuptools"]
204194
)
205195

206196
def test_uninstall_with_verbosity_3(self):
207197
with fake_pip():
208-
ensurepip._uninstall(verbosity=3)
198+
ensurepip._uninstall_helper(verbosity=3)
209199

210200
self.run_pip.assert_called_once_with(
211201
["uninstall", "-y", "-vvv", "pip", "setuptools"]
@@ -216,10 +206,57 @@ def test_pip_environment_variables_removed(self):
216206
# See http://bugs.python.org/issue19734 for details
217207
self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
218208
with fake_pip():
219-
ensurepip._uninstall()
209+
ensurepip._uninstall_helper()
220210
self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
221211

222212

213+
# Basic testing of the main functions and their argument parsing
214+
215+
EXPECTED_VERSION_OUTPUT = "pip " + ensurepip._PIP_VERSION
216+
217+
class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
218+
219+
def test_bootstrap_version(self):
220+
with test.support.captured_stdout() as stdout:
221+
with self.assertRaises(SystemExit):
222+
ensurepip._main(["--version"])
223+
result = stdout.getvalue().strip()
224+
self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
225+
self.run_pip.assert_not_called()
226+
227+
def test_basic_bootstrapping(self):
228+
ensurepip._main([])
229+
230+
self.run_pip.assert_called_once_with(
231+
[
232+
"install", "--no-index", "--find-links",
233+
unittest.mock.ANY, "--pre", "setuptools", "pip",
234+
],
235+
unittest.mock.ANY,
236+
)
237+
238+
additional_paths = self.run_pip.call_args[0][1]
239+
self.assertEqual(len(additional_paths), 2)
240+
241+
class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
242+
243+
def test_uninstall_version(self):
244+
with test.support.captured_stdout() as stdout:
245+
with self.assertRaises(SystemExit):
246+
ensurepip._uninstall._main(["--version"])
247+
result = stdout.getvalue().strip()
248+
self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
249+
self.run_pip.assert_not_called()
250+
251+
def test_basic_uninstall(self):
252+
with fake_pip():
253+
ensurepip._uninstall._main([])
254+
255+
self.run_pip.assert_called_once_with(
256+
["uninstall", "-y", "pip", "setuptools"]
257+
)
258+
259+
223260

224261
if __name__ == "__main__":
225262
test.support.run_unittest(__name__)

0 commit comments

Comments
 (0)