Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/installer/destinations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io
import os
import sysconfig
from typing import TYPE_CHECKING, BinaryIO, Dict, Iterable, Optional, Tuple, Union

from installer.records import Hash, RecordEntry
Expand All @@ -12,6 +13,7 @@
copyfileobj_with_hashing,
fix_shebang,
)
from src.installer.utils import SCHEME_NAMES, change_root

if TYPE_CHECKING:
from installer.scripts import LauncherKind, ScriptSection
Expand Down Expand Up @@ -89,10 +91,11 @@ class SchemeDictionaryDestination(WheelDestination):

def __init__(
self,
scheme_dict: Dict[str, str],
scheme_dict: Optional[Dict[str, str]],
interpreter: str,
script_kind: "LauncherKind",
hash_algorithm: str = "sha256",
root: Optional["os.PathLike[str]"] = None,
) -> None:
"""Construct a ``SchemeDictionaryDestination`` object.

Expand All @@ -103,10 +106,16 @@ def __init__(
of :any:`hashlib.algorithms_available` (ideally from
:any:`hashlib.algorithms_guaranteed`).
"""
self.scheme_dict = scheme_dict
if scheme_dict is not None:
self.scheme_dict = scheme_dict
else:
self.scheme_dict = sysconfig.get_paths()
self.interpreter = interpreter
self.script_kind = script_kind
self.hash_algorithm = hash_algorithm
if root is not None:
for scheme in SCHEME_NAMES:
self.scheme_dict[scheme] = change_root(root, self.scheme_dict[scheme])

def write_to_fs(self, scheme: Scheme, path: str, stream: BinaryIO) -> RecordEntry:
"""Write contents of ``stream`` to the correct location on the filesystem.
Expand Down
23 changes: 23 additions & 0 deletions src/installer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,26 @@ def parse_entrypoints(text: str) -> Iterable[Tuple[str, str, str, "ScriptSection
script_section = cast("ScriptSection", section[: -len("_scripts")])

yield name, module, attrs, script_section


def change_root(new_root: os.PathLike[str], pathname) -> str:
"""Return 'pathname' with 'new_root' prepended.

If 'pathname' is relative, this is equivalent to "os.path.join(new_root,pathname)".
Otherwise, it requires making 'pathname' relative and then joining the
two, which is tricky on DOS/Windows and Mac OS.
"""
if os.name == "posix":
if not os.path.isabs(pathname):
return os.path.join(new_root, pathname)
else:
return os.path.join(new_root, pathname[1:])

elif os.name == "nt":
(drive, path) = os.path.splitdrive(pathname)
if path[0] == "\\":
path = path[1:]
return os.path.join(new_root, path)

else:
raise NotImplementedError("nothing known about platform '%s'" % os.name)