1
1
import os
2
- import os .path
3
2
import subprocess
4
3
import sys
5
4
import sysconfig
6
5
import tempfile
6
+ from contextlib import nullcontext , suppress
7
7
from importlib import resources
8
+ from pathlib import Path
9
+ from shutil import copy2
8
10
9
11
10
12
__all__ = ["version" , "bootstrap" ]
14
16
# policies recommend against bundling dependencies. For example, Fedora
15
17
# installs wheel packages in the /usr/share/python-wheels/ directory and don't
16
18
# install the ensurepip._bundled package.
17
- _WHEEL_PKG_DIR = sysconfig .get_config_var ('WHEEL_PKG_DIR' )
19
+ _WHEEL_PKG_DIR = (
20
+ whl_pkg_dir_str := sysconfig .get_config_var ('WHEEL_PKG_DIR' )
21
+ ) is not None and Path (whl_pkg_dir_str ).resolve () or None
18
22
19
23
20
24
def _find_wheel_pkg_dir_pip ():
21
25
if _WHEEL_PKG_DIR is None :
22
- return None
26
+ raise LookupError (
27
+ 'The compile-time `WHEEL_PKG_DIR` is unset so there is '
28
+ 'no place for looking up the wheels.' ,
29
+ ) from None
30
+
31
+
32
+ dist_matching_wheels = _WHEEL_PKG_DIR .glob (f'pip-*.whl' )
23
33
try :
24
- filenames = os .listdir (_WHEEL_PKG_DIR )
25
- except OSError :
26
- # Ignore: path doesn't exist or permission error
27
- return None
28
- # Make the code deterministic if a directory contains multiple wheel files
29
- # of the same package, but don't attempt to implement correct version
30
- # comparison since this case should not happen.
31
- filenames = sorted (filenames , reverse = True )
32
- for filename in filenames :
33
- # filename is like 'pip-21.2.4-py3-none-any.whl'
34
- if not filename .startswith ("pip-" ) or not filename .endswith (".whl" ):
35
- continue
36
-
37
- # Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl'
38
- version = filename .removeprefix ("pip-" ).partition ("-" )[0 ]
39
- return {"version" : version , "filename" : filename , "bundled" : False }
40
-
41
- return None
42
-
43
-
44
- def _get_pip_info ():
34
+ last_matching_dist_wheel = sorted (dist_matching_wheels )[- 1 ]
35
+ except IndexError as index_err :
36
+ raise LookupError (
37
+ '`WHEEL_PKG_DIR` does not contain any wheel files for `pip`.' ,
38
+ ) from index_err
39
+
40
+ return nullcontext (last_matching_dist_wheel )
41
+
42
+
43
+ def _get_pip_whl_path_ctx ():
45
44
# 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 }
45
+ with suppress (LookupError ):
46
+ return _find_wheel_pkg_dir_pip ()
47
+
48
+ return resources .as_file (
49
+ resources .files ('ensurepip' )
50
+ / '_bundled'
51
+ / f'pip-{ _PIP_VERSION } -py3-none-any.whl'
52
+ )
53
+
54
+
55
+ def _get_pip_version ():
56
+ with _get_pip_whl_path_ctx () as bundled_wheel_path :
57
+ wheel_name = bundled_wheel_path .name
58
+ return (
59
+ # Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl'
60
+ wheel_name .
61
+ removeprefix ('pip-' ).
62
+ partition ('-' )[0 ]
63
+ )
50
64
51
65
52
66
def _run_pip (args , additional_paths = None ):
@@ -79,7 +93,7 @@ def version():
79
93
"""
80
94
Returns a string specifying the bundled version of pip.
81
95
"""
82
- return _get_pip_info ()[ "version" ]
96
+ return _get_pip_version ()
83
97
84
98
85
99
def _disable_pip_configuration_settings ():
@@ -141,20 +155,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
141
155
with tempfile .TemporaryDirectory () as tmpdir :
142
156
# Put our bundled wheels into a temporary directory and construct the
143
157
# additional paths that need added to sys.path
144
- package = _get_pip_info ()
145
- wheel_name = package ["filename" ]
146
- if package ["bundled" ]:
147
- # Use bundled wheel package
148
- wheel_path = resources .files ("ensurepip" ) / "_bundled" / wheel_name
149
- whl = wheel_path .read_bytes ()
150
- else :
151
- # Use the wheel package directory
152
- with open (os .path .join (_WHEEL_PKG_DIR , wheel_name ), "rb" ) as fp :
153
- whl = fp .read ()
154
-
155
- filename = os .path .join (tmpdir , wheel_name )
156
- with open (filename , "wb" ) as fp :
157
- fp .write (whl )
158
+ tmpdir_path = Path (tmpdir )
159
+ with _get_pip_whl_path_ctx () as bundled_wheel_path :
160
+ tmp_wheel_path = tmpdir_path / bundled_wheel_path .name
161
+ copy2 (bundled_wheel_path , tmp_wheel_path )
158
162
159
163
# Construct the arguments to be passed to the pip command
160
164
args = ["install" , "--no-cache-dir" , "--no-index" , "--find-links" , tmpdir ]
@@ -167,7 +171,7 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
167
171
if verbosity :
168
172
args += ["-" + "v" * verbosity ]
169
173
170
- return _run_pip ([* args , "pip" ], [filename ])
174
+ return _run_pip ([* args , "pip" ], [os . fsencode ( tmp_wheel_path ) ])
171
175
172
176
173
177
def _uninstall_helper (* , verbosity = 0 ):
0 commit comments