We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
-vv is not passed to build env install subprocesses
### Description

While using `-vv` I noticed seeing a big pause between these two output lines:

`
      Installing backend dependencies: started
      Installing backend dependencies: finished with status 'done'
`

Clearly a lot of stuff was happening - like wheel building - but there was no output

It turns out that when -vv was introduced in #9450 this higher verbosity level was not passed onto these subprocesses

### Expected behavior

_No response_

### pip version

24.0

### Python version

3.9

### OS

RHEL

### How to Reproduce

Compare the logging output from

```
rm -rf ~/.cache/pip && rm -f *.whl && pip -vv wheel --no-binary :all: hatchling
```

before and after the patch. I'm seeing 1k lines before and 12k lines after.

### Output

_No response_

### Code of Conduct

- [X] I agree to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/).

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pip/_internal/build_env.py`
Content:
```
1 """Build Environment used for isolation during sdist building
2 """
3 
4 import logging
5 import os
6 import pathlib
7 import site
8 import sys
9 import textwrap
10 from collections import OrderedDict
11 from types import TracebackType
12 from typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type, Union
13 
14 from pip._vendor.certifi import where
15 from pip._vendor.packaging.requirements import Requirement
16 from pip._vendor.packaging.version import Version
17 
18 from pip import __file__ as pip_location
19 from pip._internal.cli.spinners import open_spinner
20 from pip._internal.locations import get_platlib, get_purelib, get_scheme
21 from pip._internal.metadata import get_default_environment, get_environment
22 from pip._internal.utils.subprocess import call_subprocess
23 from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
24 
25 if TYPE_CHECKING:
26     from pip._internal.index.package_finder import PackageFinder
27 
28 logger = logging.getLogger(__name__)
29 
30 
31 def _dedup(a: str, b: str) -> Union[Tuple[str], Tuple[str, str]]:
32     return (a, b) if a != b else (a,)
33 
34 
35 class _Prefix:
36     def __init__(self, path: str) -> None:
37         self.path = path
38         self.setup = False
39         scheme = get_scheme("", prefix=path)
40         self.bin_dir = scheme.scripts
41         self.lib_dirs = _dedup(scheme.purelib, scheme.platlib)
42 
43 
44 def get_runnable_pip() -> str:
45     """Get a file to pass to a Python executable, to run the currently-running pip.
46 
47     This is used to run a pip subprocess, for installing requirements into the build
48     environment.
49     """
50     source = pathlib.Path(pip_location).resolve().parent
51 
52     if not source.is_dir():
53         # This would happen if someone is using pip from inside a zip file. In that
54         # case, we can use that directly.
55         return str(source)
56 
57     return os.fsdecode(source / "__pip-runner__.py")
58 
59 
60 def _get_system_sitepackages() -> Set[str]:
61     """Get system site packages
62 
63     Usually from site.getsitepackages,
64     but fallback on `get_purelib()/get_platlib()` if unavailable
65     (e.g. in a virtualenv created by virtualenv<20)
66 
67     Returns normalized set of strings.
68     """
69     if hasattr(site, "getsitepackages"):
70         system_sites = site.getsitepackages()
71     else:
72         # virtualenv < 20 overwrites site.py without getsitepackages
73         # fallback on get_purelib/get_platlib.
74         # this is known to miss things, but shouldn't in the cases
75         # where getsitepackages() has been removed (inside a virtualenv)
76         system_sites = [get_purelib(), get_platlib()]
77     return {os.path.normcase(path) for path in system_sites}
78 
79 
80 class BuildEnvironment:
81     """Creates and manages an isolated environment to install build deps"""
82 
83     def __init__(self) -> None:
84         temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)
85 
86         self._prefixes = OrderedDict(
87             (name, _Prefix(os.path.join(temp_dir.path, name)))
88             for name in ("normal", "overlay")
89         )
90 
91         self._bin_dirs: List[str] = []
92         self._lib_dirs: List[str] = []
93         for prefix in reversed(list(self._prefixes.values())):
94             self._bin_dirs.append(prefix.bin_dir)
95             self._lib_dirs.extend(prefix.lib_dirs)
96 
97         # Customize site to:
98         # - ensure .pth files are honored
99         # - prevent access to system site packages
100         system_sites = _get_system_sitepackages()
101 
102         self._site_dir = os.path.join(temp_dir.path, "site")
103         if not os.path.exists(self._site_dir):
104             os.mkdir(self._site_dir)
105         with open(
106             os.path.join(self._site_dir, "sitecustomize.py"), "w", encoding="utf-8"
107         ) as fp:
108             fp.write(
109                 textwrap.dedent(
110                     """
111                 import os, site, sys
112 
113                 # First, drop system-sites related paths.
114                 original_sys_path = sys.path[:]
115                 known_paths = set()
116                 for path in {system_sites!r}:
117                     site.addsitedir(path, known_paths=known_paths)
118                 system_paths = set(
119                     os.path.normcase(path)
120                     for path in sys.path[len(original_sys_path):]
121                 )
122                 original_sys_path = [
123                     path for path in original_sys_path
124                     if os.path.normcase(path) not in system_paths
125                 ]
126                 sys.path = original_sys_path
127 
128                 # Second, add lib directories.
129                 # ensuring .pth file are processed.
130                 for path in {lib_dirs!r}:
131                     assert not path in sys.path
132                     site.addsitedir(path)
133                 """
134                 ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)
135             )
136 
137     def __enter__(self) -> None:
138         self._save_env = {
139             name: os.environ.get(name, None)
140             for name in ("PATH", "PYTHONNOUSERSITE", "PYTHONPATH")
141         }
142 
143         path = self._bin_dirs[:]
144         old_path = self._save_env["PATH"]
145         if old_path:
146             path.extend(old_path.split(os.pathsep))
147 
148         pythonpath = [self._site_dir]
149 
150         os.environ.update(
151             {
152                 "PATH": os.pathsep.join(path),
153                 "PYTHONNOUSERSITE": "1",
154                 "PYTHONPATH": os.pathsep.join(pythonpath),
155             }
156         )
157 
158     def __exit__(
159         self,
160         exc_type: Optional[Type[BaseException]],
161         exc_val: Optional[BaseException],
162         exc_tb: Optional[TracebackType],
163     ) -> None:
164         for varname, old_value in self._save_env.items():
165             if old_value is None:
166                 os.environ.pop(varname, None)
167             else:
168                 os.environ[varname] = old_value
169 
170     def check_requirements(
171         self, reqs: Iterable[str]
172     ) -> Tuple[Set[Tuple[str, str]], Set[str]]:
173         """Return 2 sets:
174         - conflicting requirements: set of (installed, wanted) reqs tuples
175         - missing requirements: set of reqs
176         """
177         missing = set()
178         conflicting = set()
179         if reqs:
180             env = (
181                 get_environment(self._lib_dirs)
182                 if hasattr(self, "_lib_dirs")
183                 else get_default_environment()
184             )
185             for req_str in reqs:
186                 req = Requirement(req_str)
187                 # We're explicitly evaluating with an empty extra value, since build
188                 # environments are not provided any mechanism to select specific extras.
189                 if req.marker is not None and not req.marker.evaluate({"extra": ""}):
190                     continue
191                 dist = env.get_distribution(req.name)
192                 if not dist:
193                     missing.add(req_str)
194                     continue
195                 if isinstance(dist.version, Version):
196                     installed_req_str = f"{req.name}=={dist.version}"
197                 else:
198                     installed_req_str = f"{req.name}==={dist.version}"
199                 if not req.specifier.contains(dist.version, prereleases=True):
200                     conflicting.add((installed_req_str, req_str))
201                 # FIXME: Consider direct URL?
202         return conflicting, missing
203 
204     def install_requirements(
205         self,
206         finder: "PackageFinder",
207         requirements: Iterable[str],
208         prefix_as_string: str,
209         *,
210         kind: str,
211     ) -> None:
212         prefix = self._prefixes[prefix_as_string]
213         assert not prefix.setup
214         prefix.setup = True
215         if not requirements:
216             return
217         self._install_requirements(
218             get_runnable_pip(),
219             finder,
220             requirements,
221             prefix,
222             kind=kind,
223         )
224 
225     @staticmethod
226     def _install_requirements(
227         pip_runnable: str,
228         finder: "PackageFinder",
229         requirements: Iterable[str],
230         prefix: _Prefix,
231         *,
232         kind: str,
233     ) -> None:
234         args: List[str] = [
235             sys.executable,
236             pip_runnable,
237             "install",
238             "--ignore-installed",
239             "--no-user",
240             "--prefix",
241             prefix.path,
242             "--no-warn-script-location",
243         ]
244         if logger.getEffectiveLevel() <= logging.DEBUG:
245             args.append("-v")
246         for format_control in ("no_binary", "only_binary"):
247             formats = getattr(finder.format_control, format_control)
248             args.extend(
249                 (
250                     "--" + format_control.replace("_", "-"),
251                     ",".join(sorted(formats or {":none:"})),
252                 )
253             )
254 
255         index_urls = finder.index_urls
256         if index_urls:
257             args.extend(["-i", index_urls[0]])
258             for extra_index in index_urls[1:]:
259                 args.extend(["--extra-index-url", extra_index])
260         else:
261             args.append("--no-index")
262         for link in finder.find_links:
263             args.extend(["--find-links", link])
264 
265         for host in finder.trusted_hosts:
266             args.extend(["--trusted-host", host])
267         if finder.allow_all_prereleases:
268             args.append("--pre")
269         if finder.prefer_binary:
270             args.append("--prefer-binary")
271         args.append("--")
272         args.extend(requirements)
273         extra_environ = {"_PIP_STANDALONE_CERT": where()}
274         with open_spinner(f"Installing {kind}") as spinner:
275             call_subprocess(
276                 args,
277                 command_desc=f"pip subprocess to install {kind}",
278                 spinner=spinner,
279                 extra_environ=extra_environ,
280             )
281 
282 
283 class NoOpBuildEnvironment(BuildEnvironment):
284     """A no-op drop-in replacement for BuildEnvironment"""
285 
286     def __init__(self) -> None:
287         pass
288 
289     def __enter__(self) -> None:
290         pass
291 
292     def __exit__(
293         self,
294         exc_type: Optional[Type[BaseException]],
295         exc_val: Optional[BaseException],
296         exc_tb: Optional[TracebackType],
297     ) -> None:
298         pass
299 
300     def cleanup(self) -> None:
301         pass
302 
303     def install_requirements(
304         self,
305         finder: "PackageFinder",
306         requirements: Iterable[str],
307         prefix_as_string: str,
308         *,
309         kind: str,
310     ) -> None:
311         raise NotImplementedError()
312
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/pip/_internal/build_env.py b/src/pip/_internal/build_env.py
--- a/src/pip/_internal/build_env.py
+++ b/src/pip/_internal/build_env.py
@@ -19,6 +19,7 @@
 from pip._internal.cli.spinners import open_spinner
 from pip._internal.locations import get_platlib, get_purelib, get_scheme
 from pip._internal.metadata import get_default_environment, get_environment
+from pip._internal.utils.logging import VERBOSE
 from pip._internal.utils.subprocess import call_subprocess
 from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
 
@@ -242,6 +243,8 @@
             "--no-warn-script-location",
         ]
         if logger.getEffectiveLevel() <= logging.DEBUG:
+            args.append("-vv")
+        elif logger.getEffectiveLevel() <= VERBOSE:
             args.append("-v")
         for format_control in ("no_binary", "only_binary"):
             formats = getattr(finder.format_control, format_control)

{"golden_diff": "diff --git a/src/pip/_internal/build_env.py b/src/pip/_internal/build_env.py\n--- a/src/pip/_internal/build_env.py\n+++ b/src/pip/_internal/build_env.py\n@@ -19,6 +19,7 @@\n from pip._internal.cli.spinners import open_spinner\n from pip._internal.locations import get_platlib, get_purelib, get_scheme\n from pip._internal.metadata import get_default_environment, get_environment\n+from pip._internal.utils.logging import VERBOSE\n from pip._internal.utils.subprocess import call_subprocess\n from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds\n \n@@ -242,6 +243,8 @@\n             \"--no-warn-script-location\",\n         ]\n         if logger.getEffectiveLevel() <= logging.DEBUG:\n+            args.append(\"-vv\")\n+        elif logger.getEffectiveLevel() <= VERBOSE:\n             args.append(\"-v\")\n         for format_control in (\"no_binary\", \"only_binary\"):\n             formats = getattr(finder.format_control, format_control)\n", "issue": "-vv is not passed to build env install subprocesses\n### Description\n\nWhile using `-vv` I noticed seeing a big pause between these two output lines:\r\n\r\n`\r\n      Installing backend dependencies: started\r\n      Installing backend dependencies: finished with status 'done'\r\n`\r\n\r\nClearly a lot of stuff was happening - like wheel building - but there was no output\r\n\r\nIt turns out that when -vv was introduced in #9450 this higher verbosity level was not passed onto these subprocesses\n\n### Expected behavior\n\n_No response_\n\n### pip version\n\n24.0\n\n### Python version\n\n3.9\n\n### OS\n\nRHEL\n\n### How to Reproduce\n\nCompare the logging output from\r\n\r\n```\r\nrm -rf ~/.cache/pip && rm -f *.whl && pip -vv wheel --no-binary :all: hatchling\r\n```\r\n\r\nbefore and after the patch. I'm seeing 1k lines before and 12k lines after.\n\n### Output\n\n_No response_\n\n### Code of Conduct\n\n- [X] I agree to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/).\n", "before_files": [{"content": "\"\"\"Build Environment used for isolation during sdist building\n\"\"\"\n\nimport logging\nimport os\nimport pathlib\nimport site\nimport sys\nimport textwrap\nfrom collections import OrderedDict\nfrom types import TracebackType\nfrom typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type, Union\n\nfrom pip._vendor.certifi import where\nfrom pip._vendor.packaging.requirements import Requirement\nfrom pip._vendor.packaging.version import Version\n\nfrom pip import __file__ as pip_location\nfrom pip._internal.cli.spinners import open_spinner\nfrom pip._internal.locations import get_platlib, get_purelib, get_scheme\nfrom pip._internal.metadata import get_default_environment, get_environment\nfrom pip._internal.utils.subprocess import call_subprocess\nfrom pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds\n\nif TYPE_CHECKING:\n    from pip._internal.index.package_finder import PackageFinder\n\nlogger = logging.getLogger(__name__)\n\n\ndef _dedup(a: str, b: str) -> Union[Tuple[str], Tuple[str, str]]:\n    return (a, b) if a != b else (a,)\n\n\nclass _Prefix:\n    def __init__(self, path: str) -> None:\n        self.path = path\n        self.setup = False\n        scheme = get_scheme(\"\", prefix=path)\n        self.bin_dir = scheme.scripts\n        self.lib_dirs = _dedup(scheme.purelib, scheme.platlib)\n\n\ndef get_runnable_pip() -> str:\n    \"\"\"Get a file to pass to a Python executable, to run the currently-running pip.\n\n    This is used to run a pip subprocess, for installing requirements into the build\n    environment.\n    \"\"\"\n    source = pathlib.Path(pip_location).resolve().parent\n\n    if not source.is_dir():\n        # This would happen if someone is using pip from inside a zip file. In that\n        # case, we can use that directly.\n        return str(source)\n\n    return os.fsdecode(source / \"__pip-runner__.py\")\n\n\ndef _get_system_sitepackages() -> Set[str]:\n    \"\"\"Get system site packages\n\n    Usually from site.getsitepackages,\n    but fallback on `get_purelib()/get_platlib()` if unavailable\n    (e.g. in a virtualenv created by virtualenv<20)\n\n    Returns normalized set of strings.\n    \"\"\"\n    if hasattr(site, \"getsitepackages\"):\n        system_sites = site.getsitepackages()\n    else:\n        # virtualenv < 20 overwrites site.py without getsitepackages\n        # fallback on get_purelib/get_platlib.\n        # this is known to miss things, but shouldn't in the cases\n        # where getsitepackages() has been removed (inside a virtualenv)\n        system_sites = [get_purelib(), get_platlib()]\n    return {os.path.normcase(path) for path in system_sites}\n\n\nclass BuildEnvironment:\n    \"\"\"Creates and manages an isolated environment to install build deps\"\"\"\n\n    def __init__(self) -> None:\n        temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)\n\n        self._prefixes = OrderedDict(\n            (name, _Prefix(os.path.join(temp_dir.path, name)))\n            for name in (\"normal\", \"overlay\")\n        )\n\n        self._bin_dirs: List[str] = []\n        self._lib_dirs: List[str] = []\n        for prefix in reversed(list(self._prefixes.values())):\n            self._bin_dirs.append(prefix.bin_dir)\n            self._lib_dirs.extend(prefix.lib_dirs)\n\n        # Customize site to:\n        # - ensure .pth files are honored\n        # - prevent access to system site packages\n        system_sites = _get_system_sitepackages()\n\n        self._site_dir = os.path.join(temp_dir.path, \"site\")\n        if not os.path.exists(self._site_dir):\n            os.mkdir(self._site_dir)\n        with open(\n            os.path.join(self._site_dir, \"sitecustomize.py\"), \"w\", encoding=\"utf-8\"\n        ) as fp:\n            fp.write(\n                textwrap.dedent(\n                    \"\"\"\n                import os, site, sys\n\n                # First, drop system-sites related paths.\n                original_sys_path = sys.path[:]\n                known_paths = set()\n                for path in {system_sites!r}:\n                    site.addsitedir(path, known_paths=known_paths)\n                system_paths = set(\n                    os.path.normcase(path)\n                    for path in sys.path[len(original_sys_path):]\n                )\n                original_sys_path = [\n                    path for path in original_sys_path\n                    if os.path.normcase(path) not in system_paths\n                ]\n                sys.path = original_sys_path\n\n                # Second, add lib directories.\n                # ensuring .pth file are processed.\n                for path in {lib_dirs!r}:\n                    assert not path in sys.path\n                    site.addsitedir(path)\n                \"\"\"\n                ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)\n            )\n\n    def __enter__(self) -> None:\n        self._save_env = {\n            name: os.environ.get(name, None)\n            for name in (\"PATH\", \"PYTHONNOUSERSITE\", \"PYTHONPATH\")\n        }\n\n        path = self._bin_dirs[:]\n        old_path = self._save_env[\"PATH\"]\n        if old_path:\n            path.extend(old_path.split(os.pathsep))\n\n        pythonpath = [self._site_dir]\n\n        os.environ.update(\n            {\n                \"PATH\": os.pathsep.join(path),\n                \"PYTHONNOUSERSITE\": \"1\",\n                \"PYTHONPATH\": os.pathsep.join(pythonpath),\n            }\n        )\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        for varname, old_value in self._save_env.items():\n            if old_value is None:\n                os.environ.pop(varname, None)\n            else:\n                os.environ[varname] = old_value\n\n    def check_requirements(\n        self, reqs: Iterable[str]\n    ) -> Tuple[Set[Tuple[str, str]], Set[str]]:\n        \"\"\"Return 2 sets:\n        - conflicting requirements: set of (installed, wanted) reqs tuples\n        - missing requirements: set of reqs\n        \"\"\"\n        missing = set()\n        conflicting = set()\n        if reqs:\n            env = (\n                get_environment(self._lib_dirs)\n                if hasattr(self, \"_lib_dirs\")\n                else get_default_environment()\n            )\n            for req_str in reqs:\n                req = Requirement(req_str)\n                # We're explicitly evaluating with an empty extra value, since build\n                # environments are not provided any mechanism to select specific extras.\n                if req.marker is not None and not req.marker.evaluate({\"extra\": \"\"}):\n                    continue\n                dist = env.get_distribution(req.name)\n                if not dist:\n                    missing.add(req_str)\n                    continue\n                if isinstance(dist.version, Version):\n                    installed_req_str = f\"{req.name}=={dist.version}\"\n                else:\n                    installed_req_str = f\"{req.name}==={dist.version}\"\n                if not req.specifier.contains(dist.version, prereleases=True):\n                    conflicting.add((installed_req_str, req_str))\n                # FIXME: Consider direct URL?\n        return conflicting, missing\n\n    def install_requirements(\n        self,\n        finder: \"PackageFinder\",\n        requirements: Iterable[str],\n        prefix_as_string: str,\n        *,\n        kind: str,\n    ) -> None:\n        prefix = self._prefixes[prefix_as_string]\n        assert not prefix.setup\n        prefix.setup = True\n        if not requirements:\n            return\n        self._install_requirements(\n            get_runnable_pip(),\n            finder,\n            requirements,\n            prefix,\n            kind=kind,\n        )\n\n    @staticmethod\n    def _install_requirements(\n        pip_runnable: str,\n        finder: \"PackageFinder\",\n        requirements: Iterable[str],\n        prefix: _Prefix,\n        *,\n        kind: str,\n    ) -> None:\n        args: List[str] = [\n            sys.executable,\n            pip_runnable,\n            \"install\",\n            \"--ignore-installed\",\n            \"--no-user\",\n            \"--prefix\",\n            prefix.path,\n            \"--no-warn-script-location\",\n        ]\n        if logger.getEffectiveLevel() <= logging.DEBUG:\n            args.append(\"-v\")\n        for format_control in (\"no_binary\", \"only_binary\"):\n            formats = getattr(finder.format_control, format_control)\n            args.extend(\n                (\n                    \"--\" + format_control.replace(\"_\", \"-\"),\n                    \",\".join(sorted(formats or {\":none:\"})),\n                )\n            )\n\n        index_urls = finder.index_urls\n        if index_urls:\n            args.extend([\"-i\", index_urls[0]])\n            for extra_index in index_urls[1:]:\n                args.extend([\"--extra-index-url\", extra_index])\n        else:\n            args.append(\"--no-index\")\n        for link in finder.find_links:\n            args.extend([\"--find-links\", link])\n\n        for host in finder.trusted_hosts:\n            args.extend([\"--trusted-host\", host])\n        if finder.allow_all_prereleases:\n            args.append(\"--pre\")\n        if finder.prefer_binary:\n            args.append(\"--prefer-binary\")\n        args.append(\"--\")\n        args.extend(requirements)\n        extra_environ = {\"_PIP_STANDALONE_CERT\": where()}\n        with open_spinner(f\"Installing {kind}\") as spinner:\n            call_subprocess(\n                args,\n                command_desc=f\"pip subprocess to install {kind}\",\n                spinner=spinner,\n                extra_environ=extra_environ,\n            )\n\n\nclass NoOpBuildEnvironment(BuildEnvironment):\n    \"\"\"A no-op drop-in replacement for BuildEnvironment\"\"\"\n\n    def __init__(self) -> None:\n        pass\n\n    def __enter__(self) -> None:\n        pass\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        pass\n\n    def cleanup(self) -> None:\n        pass\n\n    def install_requirements(\n        self,\n        finder: \"PackageFinder\",\n        requirements: Iterable[str],\n        prefix_as_string: str,\n        *,\n        kind: str,\n    ) -> None:\n        raise NotImplementedError()\n", "path": "src/pip/_internal/build_env.py"}], "after_files": [{"content": "\"\"\"Build Environment used for isolation during sdist building\n\"\"\"\n\nimport logging\nimport os\nimport pathlib\nimport site\nimport sys\nimport textwrap\nfrom collections import OrderedDict\nfrom types import TracebackType\nfrom typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type, Union\n\nfrom pip._vendor.certifi import where\nfrom pip._vendor.packaging.requirements import Requirement\nfrom pip._vendor.packaging.version import Version\n\nfrom pip import __file__ as pip_location\nfrom pip._internal.cli.spinners import open_spinner\nfrom pip._internal.locations import get_platlib, get_purelib, get_scheme\nfrom pip._internal.metadata import get_default_environment, get_environment\nfrom pip._internal.utils.logging import VERBOSE\nfrom pip._internal.utils.subprocess import call_subprocess\nfrom pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds\n\nif TYPE_CHECKING:\n    from pip._internal.index.package_finder import PackageFinder\n\nlogger = logging.getLogger(__name__)\n\n\ndef _dedup(a: str, b: str) -> Union[Tuple[str], Tuple[str, str]]:\n    return (a, b) if a != b else (a,)\n\n\nclass _Prefix:\n    def __init__(self, path: str) -> None:\n        self.path = path\n        self.setup = False\n        scheme = get_scheme(\"\", prefix=path)\n        self.bin_dir = scheme.scripts\n        self.lib_dirs = _dedup(scheme.purelib, scheme.platlib)\n\n\ndef get_runnable_pip() -> str:\n    \"\"\"Get a file to pass to a Python executable, to run the currently-running pip.\n\n    This is used to run a pip subprocess, for installing requirements into the build\n    environment.\n    \"\"\"\n    source = pathlib.Path(pip_location).resolve().parent\n\n    if not source.is_dir():\n        # This would happen if someone is using pip from inside a zip file. In that\n        # case, we can use that directly.\n        return str(source)\n\n    return os.fsdecode(source / \"__pip-runner__.py\")\n\n\ndef _get_system_sitepackages() -> Set[str]:\n    \"\"\"Get system site packages\n\n    Usually from site.getsitepackages,\n    but fallback on `get_purelib()/get_platlib()` if unavailable\n    (e.g. in a virtualenv created by virtualenv<20)\n\n    Returns normalized set of strings.\n    \"\"\"\n    if hasattr(site, \"getsitepackages\"):\n        system_sites = site.getsitepackages()\n    else:\n        # virtualenv < 20 overwrites site.py without getsitepackages\n        # fallback on get_purelib/get_platlib.\n        # this is known to miss things, but shouldn't in the cases\n        # where getsitepackages() has been removed (inside a virtualenv)\n        system_sites = [get_purelib(), get_platlib()]\n    return {os.path.normcase(path) for path in system_sites}\n\n\nclass BuildEnvironment:\n    \"\"\"Creates and manages an isolated environment to install build deps\"\"\"\n\n    def __init__(self) -> None:\n        temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)\n\n        self._prefixes = OrderedDict(\n            (name, _Prefix(os.path.join(temp_dir.path, name)))\n            for name in (\"normal\", \"overlay\")\n        )\n\n        self._bin_dirs: List[str] = []\n        self._lib_dirs: List[str] = []\n        for prefix in reversed(list(self._prefixes.values())):\n            self._bin_dirs.append(prefix.bin_dir)\n            self._lib_dirs.extend(prefix.lib_dirs)\n\n        # Customize site to:\n        # - ensure .pth files are honored\n        # - prevent access to system site packages\n        system_sites = _get_system_sitepackages()\n\n        self._site_dir = os.path.join(temp_dir.path, \"site\")\n        if not os.path.exists(self._site_dir):\n            os.mkdir(self._site_dir)\n        with open(\n            os.path.join(self._site_dir, \"sitecustomize.py\"), \"w\", encoding=\"utf-8\"\n        ) as fp:\n            fp.write(\n                textwrap.dedent(\n                    \"\"\"\n                import os, site, sys\n\n                # First, drop system-sites related paths.\n                original_sys_path = sys.path[:]\n                known_paths = set()\n                for path in {system_sites!r}:\n                    site.addsitedir(path, known_paths=known_paths)\n                system_paths = set(\n                    os.path.normcase(path)\n                    for path in sys.path[len(original_sys_path):]\n                )\n                original_sys_path = [\n                    path for path in original_sys_path\n                    if os.path.normcase(path) not in system_paths\n                ]\n                sys.path = original_sys_path\n\n                # Second, add lib directories.\n                # ensuring .pth file are processed.\n                for path in {lib_dirs!r}:\n                    assert not path in sys.path\n                    site.addsitedir(path)\n                \"\"\"\n                ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)\n            )\n\n    def __enter__(self) -> None:\n        self._save_env = {\n            name: os.environ.get(name, None)\n            for name in (\"PATH\", \"PYTHONNOUSERSITE\", \"PYTHONPATH\")\n        }\n\n        path = self._bin_dirs[:]\n        old_path = self._save_env[\"PATH\"]\n        if old_path:\n            path.extend(old_path.split(os.pathsep))\n\n        pythonpath = [self._site_dir]\n\n        os.environ.update(\n            {\n                \"PATH\": os.pathsep.join(path),\n                \"PYTHONNOUSERSITE\": \"1\",\n                \"PYTHONPATH\": os.pathsep.join(pythonpath),\n            }\n        )\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        for varname, old_value in self._save_env.items():\n            if old_value is None:\n                os.environ.pop(varname, None)\n            else:\n                os.environ[varname] = old_value\n\n    def check_requirements(\n        self, reqs: Iterable[str]\n    ) -> Tuple[Set[Tuple[str, str]], Set[str]]:\n        \"\"\"Return 2 sets:\n        - conflicting requirements: set of (installed, wanted) reqs tuples\n        - missing requirements: set of reqs\n        \"\"\"\n        missing = set()\n        conflicting = set()\n        if reqs:\n            env = (\n                get_environment(self._lib_dirs)\n                if hasattr(self, \"_lib_dirs\")\n                else get_default_environment()\n            )\n            for req_str in reqs:\n                req = Requirement(req_str)\n                # We're explicitly evaluating with an empty extra value, since build\n                # environments are not provided any mechanism to select specific extras.\n                if req.marker is not None and not req.marker.evaluate({\"extra\": \"\"}):\n                    continue\n                dist = env.get_distribution(req.name)\n                if not dist:\n                    missing.add(req_str)\n                    continue\n                if isinstance(dist.version, Version):\n                    installed_req_str = f\"{req.name}=={dist.version}\"\n                else:\n                    installed_req_str = f\"{req.name}==={dist.version}\"\n                if not req.specifier.contains(dist.version, prereleases=True):\n                    conflicting.add((installed_req_str, req_str))\n                # FIXME: Consider direct URL?\n        return conflicting, missing\n\n    def install_requirements(\n        self,\n        finder: \"PackageFinder\",\n        requirements: Iterable[str],\n        prefix_as_string: str,\n        *,\n        kind: str,\n    ) -> None:\n        prefix = self._prefixes[prefix_as_string]\n        assert not prefix.setup\n        prefix.setup = True\n        if not requirements:\n            return\n        self._install_requirements(\n            get_runnable_pip(),\n            finder,\n            requirements,\n            prefix,\n            kind=kind,\n        )\n\n    @staticmethod\n    def _install_requirements(\n        pip_runnable: str,\n        finder: \"PackageFinder\",\n        requirements: Iterable[str],\n        prefix: _Prefix,\n        *,\n        kind: str,\n    ) -> None:\n        args: List[str] = [\n            sys.executable,\n            pip_runnable,\n            \"install\",\n            \"--ignore-installed\",\n            \"--no-user\",\n            \"--prefix\",\n            prefix.path,\n            \"--no-warn-script-location\",\n        ]\n        if logger.getEffectiveLevel() <= logging.DEBUG:\n            args.append(\"-vv\")\n        elif logger.getEffectiveLevel() <= VERBOSE:\n            args.append(\"-v\")\n        for format_control in (\"no_binary\", \"only_binary\"):\n            formats = getattr(finder.format_control, format_control)\n            args.extend(\n                (\n                    \"--\" + format_control.replace(\"_\", \"-\"),\n                    \",\".join(sorted(formats or {\":none:\"})),\n                )\n            )\n\n        index_urls = finder.index_urls\n        if index_urls:\n            args.extend([\"-i\", index_urls[0]])\n            for extra_index in index_urls[1:]:\n                args.extend([\"--extra-index-url\", extra_index])\n        else:\n            args.append(\"--no-index\")\n        for link in finder.find_links:\n            args.extend([\"--find-links\", link])\n\n        for host in finder.trusted_hosts:\n            args.extend([\"--trusted-host\", host])\n        if finder.allow_all_prereleases:\n            args.append(\"--pre\")\n        if finder.prefer_binary:\n            args.append(\"--prefer-binary\")\n        args.append(\"--\")\n        args.extend(requirements)\n        extra_environ = {\"_PIP_STANDALONE_CERT\": where()}\n        with open_spinner(f\"Installing {kind}\") as spinner:\n            call_subprocess(\n                args,\n                command_desc=f\"pip subprocess to install {kind}\",\n                spinner=spinner,\n                extra_environ=extra_environ,\n            )\n\n\nclass NoOpBuildEnvironment(BuildEnvironment):\n    \"\"\"A no-op drop-in replacement for BuildEnvironment\"\"\"\n\n    def __init__(self) -> None:\n        pass\n\n    def __enter__(self) -> None:\n        pass\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],\n    ) -> None:\n        pass\n\n    def cleanup(self) -> None:\n        pass\n\n    def install_requirements(\n        self,\n        finder: \"PackageFinder\",\n        requirements: Iterable[str],\n        prefix_as_string: str,\n        *,\n        kind: str,\n    ) -> None:\n        raise NotImplementedError()\n", "path": "src/pip/_internal/build_env.py"}]}