Skip to content

Commit

Permalink
Replace --rewrite-prefix-* with plain --prefix option
Browse files Browse the repository at this point in the history
Replace the prefix rewriting logic with plain prefix override.  This way
we get consistent arguments between `build-wheel` and `install-wheel`
commands.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
  • Loading branch information
mgorny committed Aug 25, 2023
1 parent 5aaab20 commit 212eac8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 76 deletions.
78 changes: 26 additions & 52 deletions gpep517/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,16 @@ def override_writestr(self, zinfo_or_arcname, data,

@contextlib.contextmanager
def patch_sysconfig(sysroot: Path,
prefix_from: typing.Optional[Path],
prefix_to: typing.Optional[Path],
prefix: typing.Optional[Path],
):
stdlib_path = Path(sysconfig.get_path("stdlib"))
get_vars = {}
if prefix is not None:
get_vars["installed_base"] = prefix

stdlib_path = Path(sysconfig.get_path("stdlib", vars=get_vars))
if not stdlib_path.is_absolute():
raise RuntimeError(f"stdlib path {stdlib_path} is not absolute")
try:
unprefixed_stdlib = stdlib_path.relative_to(prefix_from or "/")
except ValueError:
raise RuntimeError(f"stdlib path {stdlib_path!r} does not start with "
f"specified prefix {prefix_from!r}; was correct "
"path passed to --rewrite-prefix-from")
prefixed_stdlib = Path(prefix_to or "/") / unprefixed_stdlib
sysroot_stdlib = sysroot / prefixed_stdlib.relative_to("/")
sysroot_stdlib = sysroot / stdlib_path.relative_to("/")
logger.info(f"Searching for sysconfig in {sysroot_stdlib}")
data_paths = list(sysroot_stdlib.glob("_sysconfigdata_*.py"))
if len(data_paths) != 1:
Expand Down Expand Up @@ -184,16 +180,7 @@ def build_wheel_impl(args, wheel_dir: Path):

if args.sysroot is not None:
sysconfig_ctx = patch_sysconfig(args.sysroot,
args.rewrite_prefix_from,
args.rewrite_prefix_to)
elif args.rewrite_prefix_from is not None:
raise RuntimeError(
"The --rewrite-prefix-from argument must only be specified "
"together with the --sysroot option")
elif args.rewrite_prefix_to is not None:
raise RuntimeError(
"The --rewrite-prefix-to argument must only be specified "
"together with the --sysroot option")
args.prefix)
else:
sysconfig_ctx = contextlib.nullcontext()

Expand Down Expand Up @@ -255,7 +242,8 @@ def install_wheel_impl(args, wheel: Path):

with WheelFile.open(wheel) as source:
dest = SchemeDictionaryDestination(
install_scheme_dict(args.prefix, source.distribution),
install_scheme_dict(args.prefix or DEFAULT_PREFIX,
source.distribution),
str(args.interpreter),
get_launcher_kind(),
bytecode_optimization_levels=args.optimize,
Expand Down Expand Up @@ -284,7 +272,7 @@ def install_from_source(args):
def verify_pyc(args):
from gpep517.qa import qa_verify_pyc

install_dict = install_scheme_dict(args.prefix, "")
install_dict = install_scheme_dict(args.prefix or DEFAULT_PREFIX, "")
sitedirs = frozenset(Path(install_dict[x]) for x in ("purelib", "platlib"))
result = qa_verify_pyc(args.destdir, sitedirs)

Expand All @@ -299,29 +287,19 @@ def fpath(p):
return 1 if any(v for v in result.values()) else 0


def add_install_path_args(parser):
group = parser.add_argument_group("install paths")
group.add_argument("--destdir",
type=Path,
help="Staging directory for the install (it will "
"be prepended to all paths)",
required=True)
group.add_argument("--prefix",
type=Path,
default=DEFAULT_PREFIX,
help="Prefix to install to "
f"(default: {DEFAULT_PREFIX})")

def add_prefix_args(parser):
parser.add_argument("--prefix",
type=Path,
help="Prefix to install to "
f"(default: {DEFAULT_PREFIX})")

def PrefixPath(value: str) -> Path:
if value == "":
return Path("/")

path = Path(value)
if not path.is_absolute():
raise argparse.ArgumentTypeError(
f"argument is not an absolute path: {value!r}")
return path
def add_install_path_args(parser):
parser.add_argument("--destdir",
type=Path,
help="Staging directory for the install (it will "
"be prepended to all paths)",
required=True)


def add_build_args(parser):
Expand Down Expand Up @@ -359,14 +337,6 @@ def add_build_args(parser):
help="Patch sysconfig paths to use specified sysroot "
"(experimental cross-compilation support)",
type=Path)
group.add_argument("--rewrite-prefix-from",
help="Additional prefix applied to the build host "
"(only applicable with --sysroot option)",
type=PrefixPath)
group.add_argument("--rewrite-prefix-to",
help="Additional prefix applied to the target host "
"(only applicable with --sysroot option)",
type=PrefixPath)


def add_install_args(parser):
Expand Down Expand Up @@ -421,16 +391,19 @@ def main(argv=sys.argv):
type=Path,
help="Directory to write the wheel into",
required=True)
add_prefix_args(parser)
add_build_args(parser)

parser = subp.add_parser("install-from-source",
help="Build and install wheel from sources "
"(without preserving the wheel)")
add_prefix_args(parser)
add_build_args(parser)
add_install_args(parser)

parser = subp.add_parser("install-wheel",
help="Install the specified wheel")
add_prefix_args(parser)
add_install_args(parser)
parser.add_argument("wheel",
type=Path,
Expand All @@ -440,6 +413,7 @@ def main(argv=sys.argv):
help="Verify that all installed modules were "
"byte-compiled and there are no stray .pyc "
"files")
add_prefix_args(parser)
add_install_path_args(parser)

args = argp.parse_args(argv[1:])
Expand Down
38 changes: 14 additions & 24 deletions test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import shutil
import sys
import sysconfig
import unittest.mock
import zipfile

import pytest
Expand Down Expand Up @@ -425,41 +424,32 @@ def test_backend_opening_zipfile(tmp_path, capfd, backend, verify_mod_cleanup,
== {x.compress_type for x in zipf.infolist()})


@pytest.mark.parametrize("prefix_from", [None, "", "/", "/old_prefix",
"/old_prefix/"])
@pytest.mark.parametrize("prefix_to", [None, "", "/", "/new_prefix",
"/new_prefix/"])
@pytest.mark.parametrize("prefix", [None, "/usr", "/new_prefix/usr"])
def test_sysroot(tmp_path, capfd, verify_mod_cleanup, distutils_cache_cleanup,
prefix_from, prefix_to):
prefix):
with open(tmp_path / "pyproject.toml", "w") as f:
f.write(ZIP_BACKEND_TOML.format(backend="sysroot_backend"))

default_prefix = sysconfig.get_config_var("installed_base")
base_stdlib_path = (
pathlib.Path(sysconfig.get_path("stdlib")).relative_to("/"))
prefix_from_stdlib_path = (
(prefix_from or "").lstrip("/") / base_stdlib_path)
pathlib.Path(sysconfig.get_path("stdlib")).relative_to(default_prefix))

norm_prefix_to = (prefix_to or "").rstrip("/")
tmp_prefix = tmp_path / norm_prefix_to.lstrip("/")
norm_prefix_to = (prefix or default_prefix)
tmp_prefix = tmp_path / pathlib.Path(norm_prefix_to).relative_to("/")
stdlib_path = tmp_prefix / base_stdlib_path
stdlib_path.mkdir(parents=True)
(tmp_prefix / "foo/include/python3.11").mkdir(parents=True)
with open(stdlib_path / "_sysconfigdata__linux_i386-linux-gnu.py",
"w") as f:
f.write(SYSCONFIG_DATA.replace("/foo", norm_prefix_to + "/foo"))
f.write(SYSCONFIG_DATA.replace("/foo", f"{norm_prefix_to}/foo"))

with unittest.mock.patch("sysconfig.get_path") as patched_get_path:
patched_get_path.return_value = "/" + str(prefix_from_stdlib_path)
assert 0 == main(["", "build-wheel",
"--allow-compressed",
"--output-fd", "1",
"--pyproject-toml", str(tmp_path / "pyproject.toml"),
"--sysroot", str(tmp_path),
"--wheel-dir", str(tmp_path)] +
(["--rewrite-prefix-from", prefix_from]
if prefix_from is not None else []) +
(["--rewrite-prefix-to", prefix_to]
if prefix_to is not None else []))
assert 0 == main(["", "build-wheel",
"--allow-compressed",
"--output-fd", "1",
"--pyproject-toml", str(tmp_path / "pyproject.toml"),
"--sysroot", str(tmp_path),
"--wheel-dir", str(tmp_path)] +
(["--prefix", prefix] if prefix is not None else []))
assert "data.json\n" == capfd.readouterr().out

with open(tmp_path / "data.json", "r") as f:
Expand Down

0 comments on commit 212eac8

Please sign in to comment.