2222from ._util import check_dependency
2323
2424
25+ if typing .TYPE_CHECKING :
26+ from ._compat .importlib import metadata as importlib_metadata
27+
28+
2529Installer = typing .Literal ['pip' , 'uv' ]
2630
2731INSTALLERS = 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
6373class 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