From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Warner Losh" <imp@bsdimp.com>, "Beraldo Leal" <bleal@redhat.com>,
"John Snow" <jsnow@redhat.com>, "Kyle Evans" <kevans@freebsd.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Daniel Berrange" <berrange@redhat.com>,
"Reinoud Zandijk" <reinoud@netbsd.org>,
"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
"Cleber Rosa" <crosa@redhat.com>,
"Ryo ONODERA" <ryoon@netbsd.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Ani Sinha" <ani@anisinha.ca>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>
Subject: [RFC PATCH v3 06/20] mkvenv: work around broken pip installations on Debian 10
Date: Mon, 24 Apr 2023 16:02:34 -0400 [thread overview]
Message-ID: <20230424200248.1183394-7-jsnow@redhat.com> (raw)
In-Reply-To: <20230424200248.1183394-1-jsnow@redhat.com>
This is a workaround intended for Debian 10, where the debian-patched
pip does not function correctly if accessed from within a virtual
environment.
We don't support Debian 10 any longer, but it's possible that this bug
might appear on other derivative platforms and this workaround may prove
useful.
RFC, a note from Paolo:
"BTW, another way to repair Debian 10's pip is to create a symbolic link
to sys.base_prefix + '/share/python-wheels' in sys.prefix +
'/share/python-wheels'. Since this is much faster, perhaps it can be
done unconditionally [...] ?"
I was slightly apprehensive about this as it felt "hackier", but it is
indeed a lot less code and much faster. It's probably low-risk. Should
we do that instead, or should we just scrap any fix at all under the
premise that Debian 10 support is dropped anyway?
Signed-off-by: John Snow <jsnow@redhat.com>
---
python/scripts/mkvenv.py | 67 +++++++++++++++++++++++++++++++---------
1 file changed, 52 insertions(+), 15 deletions(-)
diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index 4daa652f12..445f4eb092 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -151,26 +151,26 @@ def need_ensurepip() -> bool:
return True
-def check_ensurepip(with_pip: bool) -> None:
+def check_ensurepip(prefix: str = "", suggest_remedy: bool = False) -> None:
"""
Check that we have ensurepip.
Raise a fatal exception with a helpful hint if it isn't available.
"""
- if not with_pip:
- return
-
if not find_spec("ensurepip"):
msg = (
"Python's ensurepip module is not found.\n"
"It's normally part of the Python standard library, "
"maybe your distribution packages it separately?\n"
- "Either install ensurepip, or alleviate the need for it in the "
- "first place by installing pip and setuptools for "
- f"'{sys.executable}'.\n"
- "(Hint: Debian puts ensurepip in its python3-venv package.)"
+ "(Debian puts ensurepip in its python3-venv package.)\n"
)
- raise Ouch(msg)
+ if suggest_remedy:
+ msg += (
+ "Either install ensurepip, or alleviate the need for it in the"
+ " first place by installing pip and setuptools for "
+ f"'{sys.executable}'.\n"
+ )
+ raise Ouch(prefix + msg)
# ensurepip uses pyexpat, which can also go missing on us:
if not find_spec("pyexpat"):
@@ -178,12 +178,15 @@ def check_ensurepip(with_pip: bool) -> None:
"Python's pyexpat module is not found.\n"
"It's normally part of the Python standard library, "
"maybe your distribution packages it separately?\n"
- "Either install pyexpat, or alleviate the need for it in the "
- "first place by installing pip and setuptools for "
- f"'{sys.executable}'.\n\n"
- "(Hint: NetBSD's pkgsrc debundles this to e.g. 'py310-expat'.)"
+ "(NetBSD's pkgsrc debundles this to e.g. 'py310-expat'.)\n"
)
- raise Ouch(msg)
+ if suggest_remedy:
+ msg += (
+ "Either install pyexpat, or alleviate the need for it in the "
+ "first place by installing pip and setuptools for "
+ f"'{sys.executable}'.\n"
+ )
+ raise Ouch(prefix + msg)
def make_venv( # pylint: disable=too-many-arguments
@@ -238,7 +241,8 @@ def make_venv( # pylint: disable=too-many-arguments
with_pip = True if not system_site_packages else need_ensurepip()
logger.debug("with_pip unset, choosing %s", with_pip)
- check_ensurepip(with_pip)
+ if with_pip:
+ check_ensurepip(suggest_remedy=True)
if symlinks is None:
# Default behavior of standard venv CLI
@@ -430,6 +434,36 @@ def _get_entry_points() -> Iterator[Dict[str, str]]:
logger.debug("wrote '%s'", script_path)
+def checkpip() -> None:
+ """
+ Debian10 has a pip that's broken when used inside of a virtual environment.
+
+ We try to detect and correct that case here.
+ """
+ try:
+ # pylint: disable=import-outside-toplevel, unused-import
+ import pip._internal # noqa: F401
+
+ logger.debug("pip appears to be working correctly.")
+ return
+ except ModuleNotFoundError as exc:
+ if exc.name == "pip._internal":
+ # Uh, fair enough. They did say "internal".
+ # Let's just assume it's fine.
+ return
+ logger.warning("pip appears to be malfunctioning: %s", str(exc))
+
+ check_ensurepip("pip appears to be non-functional, and ")
+
+ logging.debug("Attempting to repair pip ...")
+ subprocess.run(
+ (sys.executable, "-m", "ensurepip"),
+ stdout=subprocess.DEVNULL,
+ check=True,
+ )
+ logging.debug("Pip is now (hopefully) repaired!")
+
+
def post_venv_setup(bin_path: str, packages: Sequence[str] = ()) -> None:
"""
This is intended to be run *inside the venv* after it is created.
@@ -440,6 +474,9 @@ def post_venv_setup(bin_path: str, packages: Sequence[str] = ()) -> None:
)
generate_console_scripts(python_path, bin_path, packages)
+ # Test for a broken pip (Debian 10 or derivative?) and fix it if needed
+ checkpip()
+
def _add_create_subcommand(subparsers: Any) -> None:
subparser = subparsers.add_parser("create", help="create a venv")
--
2.39.2
next prev parent reply other threads:[~2023-04-24 20:05 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-24 20:02 [RFC PATCH v3 00/20] configure: create a python venv and ensure meson, sphinx John Snow
2023-04-24 20:02 ` [RFC PATCH v3 01/20] python: update pylint configuration John Snow
2023-04-25 16:38 ` Daniel P. Berrangé
2023-04-24 20:02 ` [RFC PATCH v3 02/20] python: add mkvenv.py John Snow
2023-04-24 20:02 ` [RFC PATCH v3 03/20] mkvenv: add console script entry point generation John Snow
2023-04-24 20:02 ` [RFC PATCH v3 04/20] mkvenv: Add better error message for missing pyexpat module John Snow
2023-04-24 20:02 ` [RFC PATCH v3 05/20] mkvenv: generate console entry shims from inside the venv John Snow
2023-04-24 20:02 ` John Snow [this message]
2023-04-24 20:02 ` [RFC PATCH v3 07/20] mkvenv: add nested venv workaround John Snow
2023-04-24 20:02 ` [RFC PATCH v3 08/20] mkvenv: add ensure subcommand John Snow
2023-04-24 20:02 ` [RFC PATCH v3 09/20] tests/docker: add python3-venv dependency John Snow
2023-04-25 16:42 ` Daniel P. Berrangé
2023-04-24 20:02 ` [RFC PATCH v3 10/20] tests/vm: Configure netbsd to use Python 3.10 John Snow
2023-04-25 16:43 ` Daniel P. Berrangé
2023-04-24 20:02 ` [RFC PATCH v3 11/20] tests/vm: add py310-expat to NetBSD John Snow
2023-04-25 16:45 ` Daniel P. Berrangé
2023-04-25 16:57 ` John Snow
2023-04-24 20:02 ` [RFC PATCH v3 12/20] scripts/make-release: download meson==0.61.5 .whl John Snow
2023-04-24 20:02 ` [RFC PATCH v3 13/20] configure: create a python venv unconditionally John Snow
2023-04-24 20:02 ` [RFC PATCH v3 14/20] configure: use 'mkvenv ensure meson' to bootstrap meson John Snow
2023-04-24 20:35 ` Warner Losh
2023-04-24 20:41 ` John Snow
2023-04-24 21:20 ` Warner Losh
2023-04-24 20:02 ` [RFC PATCH v3 15/20] configure: add --enable-pypi and --disable-pypi John Snow
2023-04-24 20:02 ` [RFC PATCH v3 16/20] tests: Use configure-provided pyvenv for tests John Snow
2023-04-24 20:02 ` [RFC PATCH v3 17/20] configure: move --enable-docs and --disable-docs back to configure John Snow
2023-04-24 20:02 ` [RFC PATCH v3 18/20] mkvenv: add diagnose() method for ensure() failures John Snow
2023-04-24 20:02 ` [RFC PATCH v3 19/20] configure: use --diagnose option with meson ensure John Snow
2023-04-24 20:02 ` [RFC PATCH v3 20/20] configure: bootstrap sphinx with mkvenv John Snow
2023-04-25 17:17 ` [RFC PATCH v3 00/20] configure: create a python venv and ensure meson, sphinx Daniel P. Berrangé
2023-04-25 17:22 ` John Snow
2023-04-25 17:34 ` John Snow
2023-04-25 18:10 ` Daniel P. Berrangé
2023-04-25 18:58 ` John Snow
2023-04-26 8:21 ` Daniel P. Berrangé
2023-04-26 8:35 ` Paolo Bonzini
2023-04-25 18:03 ` Daniel P. Berrangé
2023-04-26 8:05 ` Paolo Bonzini
2023-04-26 8:49 ` Paolo Bonzini
2023-04-26 16:16 ` John Snow
2023-04-26 19:10 ` Paolo Bonzini
2023-04-26 8:53 ` Daniel P. Berrangé
2023-04-26 9:08 ` Paolo Bonzini
2023-04-26 16:32 ` John Snow
2023-04-26 19:23 ` Paolo Bonzini
2023-05-01 19:20 ` John Snow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230424200248.1183394-7-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=ani@anisinha.ca \
--cc=berrange@redhat.com \
--cc=bleal@redhat.com \
--cc=crosa@redhat.com \
--cc=imp@bsdimp.com \
--cc=kevans@freebsd.org \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=reinoud@netbsd.org \
--cc=ryoon@netbsd.org \
--cc=thuth@redhat.com \
--cc=wainersm@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.