From 78adb750f3ef1defce4fe71a6b253ea631527bef Mon Sep 17 00:00:00 2001 From: Radostin Stoyanov Date: Sat, 17 Aug 2024 14:30:21 +0100 Subject: [PATCH] scripts/uninstall_module: fix package discovery The `uninstall_module.py` script is a wrapper for the `pip uninstall` command that enables support for specifying installation prefix (i.e., `--prefix`). When this functionality is used, we intentionally set `sys.path` to include only search paths for the specified prefix to avoid unintentional uninstallation of packages in system paths. Since `importlib_metadata` version 8.1.0, the `Distribution.from_name()` method has been modified [1] to perform additional pre-processing of Distribution objects [2] that requires loading distribution metadata and results in the following error: File "/usr/local/lib/python3.12/site-packages/importlib_metadata/__init__.py", line 422, in buckets = bucket(dists, lambda dist: bool(dist.metadata)) ^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/importlib_metadata/__init__.py", line 454, in metadata from . import _adapters File "/usr/local/lib/python3.12/site-packages/importlib_metadata/_adapters.py", line 3, in import email.message File "/usr/lib64/python3.12/email/message.py", line 11, in import quopri ModuleNotFoundError: No module named 'quopri' This error occurs because we have excluded system paths from the list of search paths (`sys.path`). However, this pre-processing is not required for our use case, as we only use the discovery mechanism of importlib_metadata to resolve the metadata directory path of the module being uninstalled. [1] https://github.com/python/importlib_metadata/commit/a65c29adc027b3615154cab73aaedd58a6aa23da [2] https://github.com/python/importlib_metadata/blob/a65c29ad/importlib_metadata/__init__.py#L391 Fixes: #2468 Signed-off-by: Radostin Stoyanov --- scripts/uninstall_module.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/uninstall_module.py b/scripts/uninstall_module.py index 439fca18a1..8a9b70892b 100755 --- a/scripts/uninstall_module.py +++ b/scripts/uninstall_module.py @@ -38,8 +38,9 @@ def uninstall_module(package_name: str, prefix=None): if prefix: add_site_dir(prefix) try: - dist_info_path = str(importlib_metadata.distribution(package_name)._path) - except importlib_metadata.PackageNotFoundError: + distribution = next(importlib_metadata.Distribution.discover(name=package_name)) + dist_info_path = str(distribution._path) + except StopIteration: print(f"Skipping {package_name} as it is not installed.") sys.exit(0)