Skip to content

Commit 6bc184f

Browse files
authored
fix: pip hack workaround (#980)
1 parent cea8dcd commit 6bc184f

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

src/build/env.py

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
from ._util import check_dependency
2323

2424

25+
if typing.TYPE_CHECKING:
26+
from ._compat.importlib import metadata as importlib_metadata
27+
28+
2529
Installer = typing.Literal['pip', 'uv']
2630

2731
INSTALLERS = typing.get_args(Installer)
@@ -40,10 +44,13 @@ def make_extra_environ(self) -> Mapping[str, str] | None:
4044
"""Generate additional env vars specific to the isolated environment."""
4145

4246

43-
def _has_dependency(name: str, minimum_version_str: str | None = None, /, **distargs: object) -> bool | None:
47+
def _has_dependency(
48+
name: str, minimum_version_str: str | None = None, /, **distargs: object
49+
) -> importlib_metadata.Distribution | None:
4450
"""
45-
Given a distribution name, see if it is present and return True if the version is
46-
sufficient for build, False if it is not, None if the package is missing.
51+
Given a distribution name, see if it is present and return the distribution
52+
if the version is sufficient for build, None if the package is missing or
53+
too old.
4754
"""
4855
from packaging.version import Version
4956

@@ -55,9 +62,12 @@ def _has_dependency(name: str, minimum_version_str: str | None = None, /, **dist
5562
return None
5663

5764
if minimum_version_str is None:
58-
return True
65+
return distribution
66+
67+
if Version(distribution.version) < Version(minimum_version_str):
68+
return None
5969

60-
return Version(distribution.version) >= Version(minimum_version_str)
70+
return distribution
6171

6272

6373
class DefaultIsolatedEnv(IsolatedEnv):
@@ -158,21 +168,25 @@ def __init__(self) -> None:
158168
def _has_valid_outer_pip(self) -> bool | None:
159169
"""
160170
This checks for a valid global pip. Returns None if pip is missing, False
161-
if pip is too old, and True if it can be used.
171+
if pip is too old or debundled, and True if it can be used.
162172
"""
163173

164174
# Version to have added the `--python` option.
165-
if not _has_dependency('pip', '22.3'): # pragma: no cover
166-
return False
167-
168175
# `pip install --python` is nonfunctional on Gentoo debundled pip.
169-
# Detect that by checking if pip._vendor` module exists. However,
170-
# searching for pip could yield warnings from _distutils_hack,
171-
# so silence them.
172-
with warnings.catch_warnings():
173-
warnings.simplefilter('ignore')
174-
if importlib.util.find_spec('pip._vendor') is None:
175-
return False # pragma: no cover
176+
if dist := _has_dependency('pip', '22.3'): # pragma: no cover
177+
files = dist.files
178+
if files:
179+
return any(str(f).startswith('pip/_vendor') for f in files)
180+
# The distribution package manager deleted the RECORD file,
181+
# generally to force pip to be unable to uninstall itself
182+
# Only try this on 3.12+ since it can have side effects before 3.12
183+
# due to _distutils_hack and pip interacting.
184+
if sys.version_info >= (3, 12):
185+
with warnings.catch_warnings():
186+
warnings.simplefilter('ignore')
187+
if importlib.util.find_spec('pip._vendor') is not None:
188+
return True
189+
return False
176190

177191
return True
178192

0 commit comments

Comments
 (0)