Skip to content

Commit 7b04736

Browse files
AA-Turnerwebknjaz
authored andcommitted
Simplify the pip wheel info
- Return a dict with consistent fields - Remove caching - Remove type annotations - Leverage the known wheel package dir value to calculate full paths
1 parent 96b8b9e commit 7b04736

File tree

2 files changed

+32
-80
lines changed

2 files changed

+32
-80
lines changed

Lib/ensurepip/__init__.py

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
1-
import collections
21
import os
32
import os.path
43
import subprocess
54
import sys
65
import sysconfig
76
import tempfile
8-
from contextlib import suppress
9-
from functools import cache
107
from importlib import resources
118

129

1310
__all__ = ["version", "bootstrap"]
1411
_PIP_VERSION = "23.3.2"
1512

16-
# Packages bundled in ensurepip._bundled have wheel_name set.
17-
# Packages from WHEEL_PKG_DIR have wheel_path set.
18-
_Package = collections.namedtuple('Package',
19-
('version', 'wheel_name', 'wheel_path'))
20-
2113
# Directory of system wheel packages. Some Linux distribution packaging
2214
# policies recommend against bundling dependencies. For example, Fedora
2315
# installs wheel packages in the /usr/share/python-wheels/ directory and don't
@@ -44,22 +36,17 @@ def _find_wheel_pkg_dir_pip():
4436

4537
# Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl'
4638
version = filename.removeprefix("pip-").partition("-")[0]
47-
wheel_path = os.path.join(_WHEEL_PKG_DIR, filename)
48-
return _Package(version, None, wheel_path)
39+
return {"version": version, "filename": filename, "bundled": False}
4940

5041
return None
5142

5243

53-
@cache
54-
def _get_usable_pip_package() -> _Package:
55-
wheel_name = f"pip-{_PIP_VERSION}-py3-none-any.whl"
56-
pip_pkg = _Package(_PIP_VERSION, wheel_name, None)
57-
58-
with suppress(LookupError):
59-
# only use the wheel package directory if pip wheel is found there
60-
pip_pkg = _find_wheel_pkg_dir_pip(_WHEEL_PKG_DIR)
61-
62-
return pip_pkg
44+
def _get_pip_info():
45+
# Prefer pip from the wheel package directory, if present.
46+
if (pip_info := _find_wheel_pkg_dir_pip()) is not None:
47+
return pip_info
48+
filename = f"pip-{_PIP_VERSION}-py3-none-any.whl"
49+
return {"version": _PIP_VERSION, "filename": filename, "bundled": True}
6350

6451

6552
def _run_pip(args, additional_paths=None):
@@ -92,7 +79,7 @@ def version():
9279
"""
9380
Returns a string specifying the bundled version of pip.
9481
"""
95-
return _get_usable_pip_package().version
82+
return _get_pip_info()["version"]
9683

9784

9885
def _disable_pip_configuration_settings():
@@ -154,17 +141,16 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
154141
with tempfile.TemporaryDirectory() as tmpdir:
155142
# Put our bundled wheels into a temporary directory and construct the
156143
# additional paths that need added to sys.path
157-
package = _get_usable_pip_package()
158-
if package.wheel_name:
144+
package = _get_pip_info()
145+
wheel_name = package["filename"]
146+
if package["bundled"]:
159147
# Use bundled wheel package
160-
wheel_name = package.wheel_name
161148
wheel_path = resources.files("ensurepip") / "_bundled" / wheel_name
162149
whl = wheel_path.read_bytes()
163150
else:
164151
# Use the wheel package directory
165-
with open(package.wheel_path, "rb") as fp:
152+
with open(os.path.join(_WHEEL_PKG_DIR, wheel_name), "rb") as fp:
166153
whl = fp.read()
167-
wheel_name = os.path.basename(package.wheel_path)
168154

169155
filename = os.path.join(tmpdir, wheel_name)
170156
with open(filename, "wb") as fp:
@@ -183,6 +169,7 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
183169

184170
return _run_pip([*args, "pip"], [filename])
185171

172+
186173
def _uninstall_helper(*, verbosity=0):
187174
"""Helper to support a clean default uninstall process on Windows
188175

Lib/test/test_ensurepip.py

Lines changed: 19 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,12 @@
66
import test.support
77
import unittest
88
import unittest.mock
9-
from pathlib import Path
109

1110
import ensurepip
1211
import ensurepip._uninstall
1312

1413

1514
class TestPackages(unittest.TestCase):
16-
def setUp(self):
17-
ensurepip._get_usable_pip_package.cache_clear()
18-
19-
def tearDown(self):
20-
ensurepip._get_usable_pip_package.cache_clear()
21-
2215
def touch(self, directory, filename):
2316
fullname = os.path.join(directory, filename)
2417
open(fullname, "wb").close()
@@ -27,43 +20,39 @@ def test_version(self):
2720
# Test version()
2821
with tempfile.TemporaryDirectory() as tmpdir:
2922
self.touch(tmpdir, "pip-1.2.3b1-py2.py3-none-any.whl")
30-
with unittest.mock.patch.object(
31-
ensurepip, '_WHEEL_PKG_DIR', tmpdir,
32-
):
23+
with unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', tmpdir):
3324
self.assertEqual(ensurepip.version(), '1.2.3b1')
3425

35-
def test_get_packages_no_dir(self):
36-
# Test _get_packages() without a wheel package directory
26+
def test_get_pip_info_no_dir(self):
27+
# Test _get_pip_info() without a wheel package directory
3728
with unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', None):
38-
pip_pkg = ensurepip._get_usable_pip_package()
29+
pip_info = ensurepip._get_pip_info()
3930

40-
# when bundled pip wheel package is used, we get _PIP_VERSION
31+
# when the bundled pip wheel is used, we get _PIP_VERSION
4132
self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version())
4233

43-
# use bundled pip wheel package
44-
self.assertIsNotNone(pip_pkg.wheel_name)
34+
# use the bundled pip wheel
35+
pip_filename = f'pip-{ensurepip._PIP_VERSION}-py3-none-any.whl'
36+
expected = {"version": ensurepip._PIP_VERSION, "filename": pip_filename,
37+
"bundled": True}
38+
self.assertDictEqual(pip_info, expected)
4539

46-
def test_get_packages_with_dir(self):
47-
# Test _get_packages() with a wheel package directory
48-
older_pip_filename = "pip-1.2.3-py2.py3-none-any.whl"
40+
def test_get_pip_info_with_dir(self):
41+
# Test _get_pip_info() with a wheel package directory
4942
pip_filename = "pip-20.2.2-py2.py3-none-any.whl"
5043

5144
with tempfile.TemporaryDirectory() as tmpdir:
52-
self.touch(tmpdir, older_pip_filename)
5345
self.touch(tmpdir, pip_filename)
54-
# not used, make sure that it's ignored
46+
# not used, make sure that they're ignored
47+
self.touch(tmpdir, "pip-1.2.3-py2.py3-none-any.whl")
5548
self.touch(tmpdir, "wheel-0.34.2-py2.py3-none-any.whl")
56-
# not used, make sure that it's ignored
57-
self.touch(tmpdir, "non-whl")
49+
self.touch(tmpdir, "pip-script.py")
5850

59-
with unittest.mock.patch.object(
60-
ensurepip, '_WHEEL_PKG_DIR', tmpdir,
61-
):
62-
pip_pkg = ensurepip._get_usable_pip_package()
51+
with unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', tmpdir):
52+
pip_info = ensurepip._get_pip_info()
6353

64-
self.assertEqual(pip_pkg.version, '20.2.2')
65-
self.assertEqual(pip_pkg.wheel_path,
66-
os.path.join(tmpdir, pip_filename))
54+
expected = {"version": '20.2.2', "filename": pip_filename, "bundled": False}
55+
self.assertDictEqual(pip_info, expected)
6756

6857

6958
class EnsurepipMixin:
@@ -102,30 +91,6 @@ def test_basic_bootstrapping(self):
10291
additional_paths = self.run_pip.call_args[0][1]
10392
self.assertEqual(len(additional_paths), 1)
10493

105-
106-
def test_replacement_wheel_bootstrapping(self):
107-
ensurepip._get_usable_pip_package.cache_clear()
108-
109-
pip_wheel_name = (
110-
f'pip-{ensurepip._PIP_VERSION !s}-'
111-
'py3-none-any.whl'
112-
)
113-
114-
with tempfile.TemporaryDirectory() as tmpdir:
115-
tmp_path = Path(tmpdir)
116-
tmp_wheel_path = tmp_path / pip_wheel_name
117-
tmp_wheel_path.touch()
118-
119-
with unittest.mock.patch.object(
120-
ensurepip, '_WHEEL_PKG_DIR', tmpdir,
121-
):
122-
ensurepip.bootstrap()
123-
124-
ensurepip._get_usable_pip_package.cache_clear()
125-
126-
additional_paths = self.run_pip.call_args[0][1]
127-
self.assertEqual(Path(additional_paths[-1]).name, pip_wheel_name)
128-
12994
def test_bootstrapping_with_root(self):
13095
ensurepip.bootstrap(root="/foo/bar/")
13196

0 commit comments

Comments
 (0)