Commit 9adda0cd authored by Igor Filatov's avatar Igor Filatov Committed by Nick Coghlan

bpo-31351: Set return code in ensurepip when pip fails (GH-3626)

Previously ensurepip would always report success, even if the
pip installation failed.
parent a96c96f5
......@@ -78,6 +78,9 @@ options:
Providing both of the script selection options will trigger an exception.
.. versionchanged:: 3.7.0
The exit status is non-zero if the command fails.
Module API
----------
......
......@@ -25,7 +25,7 @@ def _run_pip(args, additional_paths=None):
# Install the bundled software
import pip
pip.main(args)
return pip.main(args)
def version():
......@@ -53,6 +53,21 @@ def bootstrap(*, root=None, upgrade=False, user=False,
Bootstrap pip into the current Python installation (or the given root
directory).
Note that calling this function will alter both sys.path and os.environ.
"""
# Discard the return value
_bootstrap(root=root, upgrade=upgrade, user=user,
altinstall=altinstall, default_pip=default_pip,
verbosity=verbosity)
def _bootstrap(*, root=None, upgrade=False, user=False,
altinstall=False, default_pip=False,
verbosity=0):
"""
Bootstrap pip into the current Python installation (or the given root
directory). Returns pip command status code.
Note that calling this function will alter both sys.path and os.environ.
"""
if altinstall and default_pip:
......@@ -99,7 +114,7 @@ def bootstrap(*, root=None, upgrade=False, user=False,
if verbosity:
args += ["-" + "v" * verbosity]
_run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
def _uninstall_helper(*, verbosity=0):
"""Helper to support a clean default uninstall process on Windows
......@@ -126,7 +141,7 @@ def _uninstall_helper(*, verbosity=0):
if verbosity:
args += ["-" + "v" * verbosity]
_run_pip(args + [p[0] for p in reversed(_PROJECTS)])
return _run_pip(args + [p[0] for p in reversed(_PROJECTS)])
def _main(argv=None):
......@@ -180,7 +195,7 @@ def _main(argv=None):
args = parser.parse_args(argv)
bootstrap(
return _bootstrap(
root=args.root,
upgrade=args.upgrade,
user=args.user,
......
import ensurepip
import sys
if __name__ == "__main__":
ensurepip._main()
sys.exit(ensurepip._main())
......@@ -2,6 +2,7 @@
import argparse
import ensurepip
import sys
def _main(argv=None):
......@@ -23,8 +24,8 @@ def _main(argv=None):
args = parser.parse_args(argv)
ensurepip._uninstall_helper(verbosity=args.verbosity)
return ensurepip._uninstall_helper(verbosity=args.verbosity)
if __name__ == "__main__":
_main()
sys.exit(_main())
......@@ -20,6 +20,7 @@ class EnsurepipMixin:
def setUp(self):
run_pip_patch = unittest.mock.patch("ensurepip._run_pip")
self.run_pip = run_pip_patch.start()
self.run_pip.return_value = 0
self.addCleanup(run_pip_patch.stop)
# Avoid side effects on the actual os module
......@@ -255,7 +256,7 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
self.assertFalse(self.run_pip.called)
def test_basic_bootstrapping(self):
ensurepip._main([])
exit_code = ensurepip._main([])
self.run_pip.assert_called_once_with(
[
......@@ -267,6 +268,13 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
additional_paths = self.run_pip.call_args[0][1]
self.assertEqual(len(additional_paths), 2)
self.assertEqual(exit_code, 0)
def test_bootstrapping_error_code(self):
self.run_pip.return_value = 2
exit_code = ensurepip._main([])
self.assertEqual(exit_code, 2)
class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
......@@ -280,7 +288,7 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
def test_basic_uninstall(self):
with fake_pip():
ensurepip._uninstall._main([])
exit_code = ensurepip._uninstall._main([])
self.run_pip.assert_called_once_with(
[
......@@ -289,6 +297,13 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
]
)
self.assertEqual(exit_code, 0)
def test_uninstall_error_code(self):
with fake_pip():
self.run_pip.return_value = 2
exit_code = ensurepip._uninstall._main([])
self.assertEqual(exit_code, 2)
if __name__ == "__main__":
......
python -m ensurepip now exits with non-zero exit code if pip bootstrapping
has failed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment