diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2022-07-01 15:34:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-01 15:34:11 (GMT) |
commit | 259dd7ee8af54e3328ebf41131364b811c055814 (patch) | |
tree | efe90da9d950e8246ee506f70f847b00a27209e6 /Lib/test/test_venv.py | |
parent | b8544e18e61a0f4a873b3f4b4b2211822584b63f (diff) | |
download | cpython-259dd7ee8af54e3328ebf41131364b811c055814.zip cpython-259dd7ee8af54e3328ebf41131364b811c055814.tar.gz cpython-259dd7ee8af54e3328ebf41131364b811c055814.tar.bz2 |
[3.10] gh-93975: Provide nicer error reporting from subprocesses in test_venv.EnsurePipTest.test_with_pip (GH-93959) (GH-94004)
This change does three things:
1. Extract a function for trapping output in subprocesses.
2. Emit both stdout and stderr when encountering an error.
3. Apply the change to `ensurepip._uninstall` check.
(cherry picked from commit 6066f450b91f1cbebf33a245c14e660052ccd90a)
Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
Diffstat (limited to 'Lib/test/test_venv.py')
-rw-r--r-- | Lib/test/test_venv.py | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 94d6265..eca35ec 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -5,6 +5,7 @@ Copyright (C) 2011-2012 Vinay Sajip. Licensed to the PSF under a contributor agreement. """ +import contextlib import ensurepip import os import os.path @@ -478,16 +479,10 @@ class EnsurePipTest(BaseTest): # Actually run the create command with all that unhelpful # config in place to ensure we ignore it - try: + with self.nicer_error(): self.run_with_capture(venv.create, self.env_dir, system_site_packages=system_site_packages, with_pip=True) - except subprocess.CalledProcessError as exc: - # The output this produces can be a little hard to read, - # but at least it has all the details - details = exc.output.decode(errors="replace") - msg = "{}\n\n**Subprocess Output**\n{}" - self.fail(msg.format(exc, details)) # Ensure pip is available in the virtual environment envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) # Ignore DeprecationWarning since pip code is not part of Python @@ -508,13 +503,14 @@ class EnsurePipTest(BaseTest): # Check the private uninstall command provided for the Windows # installers works (at least in a virtual environment) with EnvironmentVarGuard() as envvars: - # It seems ensurepip._uninstall calls subprocesses which do not - # inherit the interpreter settings. - envvars["PYTHONWARNINGS"] = "ignore" - out, err = check_output([envpy, - '-W', 'ignore::DeprecationWarning', - '-W', 'ignore::ImportWarning', '-I', - '-m', 'ensurepip._uninstall']) + with self.nicer_error(): + # It seems ensurepip._uninstall calls subprocesses which do not + # inherit the interpreter settings. + envvars["PYTHONWARNINGS"] = "ignore" + out, err = check_output([envpy, + '-W', 'ignore::DeprecationWarning', + '-W', 'ignore::ImportWarning', '-I', + '-m', 'ensurepip._uninstall']) # We force everything to text, so unittest gives the detailed diff # if we get unexpected results err = err.decode("latin-1") # Force to text, prevent decoding errors @@ -540,6 +536,25 @@ class EnsurePipTest(BaseTest): if not system_site_packages: self.assert_pip_not_installed() + @contextlib.contextmanager + def nicer_error(self): + """ + Capture output from a failed subprocess for easier debugging. + + The output this handler produces can be a little hard to read, + but at least it has all the details. + """ + try: + yield + except subprocess.CalledProcessError as exc: + out = exc.output.decode(errors="replace") + err = exc.stderr.decode(errors="replace") + self.fail( + f"{exc}\n\n" + f"**Subprocess Output**\n{out}\n\n" + f"**Subprocess Error**\n{err}" + ) + # Issue #26610: pip/pep425tags.py requires ctypes @unittest.skipUnless(ctypes, 'pip requires ctypes') @requires_zlib() @@ -547,5 +562,6 @@ class EnsurePipTest(BaseTest): self.do_test_with_pip(False) self.do_test_with_pip(True) + if __name__ == "__main__": unittest.main() |