Skip to content

Commit

Permalink
fix(env): ensure all system site paths are used
Browse files Browse the repository at this point in the history
With this change, when using newer Python versions (>=3.12), Poetry
correctly detects and considers read-only system site packages when
an environment is loaded.

Resolves: python-poetry#9878
  • Loading branch information
abn committed Jan 6, 2025
1 parent 090480a commit 8506021
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
16 changes: 11 additions & 5 deletions src/poetry/utils/env/base_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def __init__(self, path: Path, base: Path | None = None) -> None:
self._supported_tags: list[Tag] | None = None
self._purelib: Path | None = None
self._platlib: Path | None = None
self._fallbacks: list[Path] | None = None
self._script_dirs: list[Path] | None = None

self._embedded_pip_path: Path | None = None
Expand Down Expand Up @@ -175,13 +176,10 @@ def os(self) -> str:
@property
def site_packages(self) -> SitePackages:
if self._site_packages is None:
# we disable write checks if no user site exist
fallbacks = [self.usersite] if self.usersite else []
self._site_packages = SitePackages(
self.purelib,
self.platlib,
fallbacks,
skip_write_checks=not fallbacks,
self.fallbacks,
)
return self._site_packages

Expand Down Expand Up @@ -214,8 +212,16 @@ def platlib(self) -> Path:

return self._platlib

@property
def fallbacks(self) -> list[Path]:
if self._fallbacks is None:
self._fallbacks = [Path(path) for path in self.paths.get("fallbacks", [])]
self._fallbacks += [self.usersite] if self.usersite else []

return self._fallbacks

def _get_lib_dirs(self) -> list[Path]:
return [self.purelib, self.platlib]
return [self.purelib, self.platlib, *self.fallbacks]

def is_path_relative_to_lib(self, path: Path) -> bool:
for lib_path in self._get_lib_dirs():
Expand Down
5 changes: 5 additions & 0 deletions src/poetry/utils/env/script_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ def _version_nodot(version):
paths = sysconfig.get_paths().copy()
paths["fallbacks"] = [
p for p in site.getsitepackages()
if p and p not in {paths.get("purelib"), paths.get("platlib")}
]
if site.check_enableusersite():
paths["usersite"] = site.getusersitepackages()
paths["userbase"] = site.getuserbase()
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/env/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def test_env_system_packages_are_relative_to_lib(

# These are the virtual environments' base env packages,
# in this case the system site packages.
for dist in metadata.distributions(path=[str(env.parent_env.site_packages.path)]):
for dist in env.parent_env.site_packages.distributions():
assert (
env.is_path_relative_to_lib(
Path(str(dist._path)) # type: ignore[attr-defined]
Expand Down

0 comments on commit 8506021

Please sign in to comment.