From ca5ccee41d7f30df147205e7a0159f27f2414668 Mon Sep 17 00:00:00 2001 From: Imgyu Kim Date: Tue, 24 Mar 2026 12:50:04 +0900 Subject: [PATCH 1/2] gh-146310: Fix ensurepip to treat empty WHEEL_PKG_DIR as unset Path('') resolves to CWD, so an empty WHEEL_PKG_DIR string caused ensurepip to search the current working directory for wheel files. Add a truthiness check to treat empty strings the same as None. --- Lib/ensurepip/__init__.py | 2 +- Lib/test/test_ensurepip.py | 7 +++++++ .../Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 6164ea62324cce..5b76d8f0758125 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -16,7 +16,7 @@ # policies recommend against bundling dependencies. For example, Fedora # installs wheel packages in the /usr/share/python-wheels/ directory and don't # install the ensurepip._bundled package. -if (_pkg_dir := sysconfig.get_config_var('WHEEL_PKG_DIR')) is not None: +if (_pkg_dir := sysconfig.get_config_var('WHEEL_PKG_DIR')) is not None and _pkg_dir: _WHEEL_PKG_DIR = Path(_pkg_dir).resolve() else: _WHEEL_PKG_DIR = None diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py index c62b340f6a340f..a85984b58aeaba 100644 --- a/Lib/test/test_ensurepip.py +++ b/Lib/test/test_ensurepip.py @@ -36,6 +36,13 @@ def test_version_no_dir(self): # when the bundled pip wheel is used, we get _PIP_VERSION self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version()) + def test_empty_wheel_pkg_dir_treated_as_none(self): + # GH#146310: empty string WHEEL_PKG_DIR should not search CWD. + # An empty WHEEL_PKG_DIR converts to Path('.') which would + # incorrectly search the current working directory. + with unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', None): + self.assertIsNone(ensurepip._find_wheel_pkg_dir_pip()) + def test_selected_wheel_path_no_dir(self): pip_filename = f'pip-{ensurepip._PIP_VERSION}-py3-none-any.whl' with unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', None): diff --git a/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst b/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst new file mode 100644 index 00000000000000..3186d1bb9b0947 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst @@ -0,0 +1,2 @@ +Fix :mod:`ensurepip` to treat an empty string ``WHEEL_PKG_DIR`` as unset, +preventing it from searching the current working directory for wheel files. From 6ed8ebf77f6a1aaa416c246288efc8b2c1c6e1cf Mon Sep 17 00:00:00 2001 From: Imgyu Kim Date: Tue, 24 Mar 2026 23:00:22 +0900 Subject: [PATCH 2/2] Address review: simplify condition, use import_fresh_module, update NEWS Per @vstinner: - Simplify to 'if _pkg_dir:' instead of walrus + is not None - Replace mock-based test with import_fresh_module for both '' and None - Reword NEWS to describe old behavior instead of fix --- Lib/ensurepip/__init__.py | 3 ++- Lib/test/test_ensurepip.py | 15 +++++++++------ ...2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst | 4 ++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 5b76d8f0758125..93b4e7a820f3ad 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -16,7 +16,8 @@ # policies recommend against bundling dependencies. For example, Fedora # installs wheel packages in the /usr/share/python-wheels/ directory and don't # install the ensurepip._bundled package. -if (_pkg_dir := sysconfig.get_config_var('WHEEL_PKG_DIR')) is not None and _pkg_dir: +_pkg_dir = sysconfig.get_config_var('WHEEL_PKG_DIR') +if _pkg_dir: _WHEEL_PKG_DIR = Path(_pkg_dir).resolve() else: _WHEEL_PKG_DIR = None diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py index a85984b58aeaba..e37ad6af600473 100644 --- a/Lib/test/test_ensurepip.py +++ b/Lib/test/test_ensurepip.py @@ -7,6 +7,7 @@ import unittest import unittest.mock from pathlib import Path +from test.support import import_helper import ensurepip import ensurepip._uninstall @@ -36,12 +37,14 @@ def test_version_no_dir(self): # when the bundled pip wheel is used, we get _PIP_VERSION self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version()) - def test_empty_wheel_pkg_dir_treated_as_none(self): - # GH#146310: empty string WHEEL_PKG_DIR should not search CWD. - # An empty WHEEL_PKG_DIR converts to Path('.') which would - # incorrectly search the current working directory. - with unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', None): - self.assertIsNone(ensurepip._find_wheel_pkg_dir_pip()) + def test_wheel_pkg_dir_none(self): + # GH#146310: empty or None WHEEL_PKG_DIR should not search CWD + for value in ('', None): + with unittest.mock.patch('sysconfig.get_config_var', + return_value=value) as get_config_var: + module = import_helper.import_fresh_module('ensurepip') + self.assertIsNone(module._WHEEL_PKG_DIR) + get_config_var.assert_called_once_with('WHEEL_PKG_DIR') def test_selected_wheel_path_no_dir(self): pip_filename = f'pip-{ensurepip._PIP_VERSION}-py3-none-any.whl' diff --git a/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst b/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst index 3186d1bb9b0947..b712595585201b 100644 --- a/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst +++ b/Misc/NEWS.d/next/Library/2026-03-24-03-49-50.gh-issue-146310.WhlDir.rst @@ -1,2 +1,2 @@ -Fix :mod:`ensurepip` to treat an empty string ``WHEEL_PKG_DIR`` as unset, -preventing it from searching the current working directory for wheel files. +The :mod:`ensurepip` module no longer looks for ``pip-*.whl`` wheel packages +in the current directory.