mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Merge pull request #11466 from minrk/build_env_isolation
This commit is contained in:
commit
0a21080411
3 changed files with 38 additions and 4 deletions
1
news/6264.bugfix.rst
Normal file
1
news/6264.bugfix.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Fix build environment isolation on some system Pythons.
|
|
@ -4,6 +4,7 @@
|
|||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import site
|
||||
import sys
|
||||
import textwrap
|
||||
from collections import OrderedDict
|
||||
|
@ -55,6 +56,26 @@ def get_runnable_pip() -> str:
|
|||
return os.fsdecode(source / "__pip-runner__.py")
|
||||
|
||||
|
||||
def _get_system_sitepackages() -> Set[str]:
|
||||
"""Get system site packages
|
||||
|
||||
Usually from site.getsitepackages,
|
||||
but fallback on `get_purelib()/get_platlib()` if unavailable
|
||||
(e.g. in a virtualenv created by virtualenv<20)
|
||||
|
||||
Returns normalized set of strings.
|
||||
"""
|
||||
if hasattr(site, "getsitepackages"):
|
||||
system_sites = site.getsitepackages()
|
||||
else:
|
||||
# virtualenv < 20 overwrites site.py without getsitepackages
|
||||
# fallback on get_purelib/get_platlib.
|
||||
# this is known to miss things, but shouldn't in the cases
|
||||
# where getsitepackages() has been removed (inside a virtualenv)
|
||||
system_sites = [get_purelib(), get_platlib()]
|
||||
return {os.path.normcase(path) for path in system_sites}
|
||||
|
||||
|
||||
class BuildEnvironment:
|
||||
"""Creates and manages an isolated environment to install build deps"""
|
||||
|
||||
|
@ -75,9 +96,8 @@ class BuildEnvironment:
|
|||
# Customize site to:
|
||||
# - ensure .pth files are honored
|
||||
# - prevent access to system site packages
|
||||
system_sites = {
|
||||
os.path.normcase(site) for site in (get_purelib(), get_platlib())
|
||||
}
|
||||
system_sites = _get_system_sitepackages()
|
||||
|
||||
self._site_dir = os.path.join(temp_dir.path, "site")
|
||||
if not os.path.exists(self._site_dir):
|
||||
os.mkdir(self._site_dir)
|
||||
|
|
|
@ -4,7 +4,7 @@ from typing import Optional
|
|||
|
||||
import pytest
|
||||
|
||||
from pip._internal.build_env import BuildEnvironment
|
||||
from pip._internal.build_env import BuildEnvironment, _get_system_sitepackages
|
||||
from tests.lib import (
|
||||
PipTestEnvironment,
|
||||
TestPipResult,
|
||||
|
@ -226,6 +226,10 @@ def test_build_env_isolation(script: PipTestEnvironment) -> None:
|
|||
script.pip_install_local("-t", target, pkg_whl)
|
||||
script.environ["PYTHONPATH"] = target
|
||||
|
||||
system_sites = _get_system_sitepackages()
|
||||
# there should always be something to exclude
|
||||
assert system_sites
|
||||
|
||||
run_with_build_env(
|
||||
script,
|
||||
"",
|
||||
|
@ -247,5 +251,14 @@ def test_build_env_isolation(script: PipTestEnvironment) -> None:
|
|||
})), file=sys.stderr)
|
||||
print('sys.path:\n ' + '\n '.join(sys.path), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
"""
|
||||
f"""
|
||||
# second check: direct check of exclusion of system site packages
|
||||
import os
|
||||
|
||||
normalized_path = [os.path.normcase(path) for path in sys.path]
|
||||
for system_path in {system_sites!r}:
|
||||
assert system_path not in normalized_path, \
|
||||
f"{{system_path}} found in {{normalized_path}}"
|
||||
""",
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue