A sealed Windows payload copied its pinned Python to %LOCALAPPDATA% so uv-built venvs had a reachable redirector target. Every process started from that copy then sat outside the package and could not start the package's executables (WinError 5): bundled git, rg, the PM worker. Build generations on the bundled interpreter instead and never run a venv's own executables there. pm.environments.venv_command returns the argv that enters a venv: on a sealed payload, the payload Python with -S plus pm/_venv_entry.py, which attaches the venv's site-packages (and its .pth files) and runs a script, -c or -m; elsewhere the venv interpreter. Recovery's startup validation and the plugin capability probe use it. A sealed payload's venv Scripts dir stays off PATH. Verified (macOS): new venv_command contract tests run scripts, -c and -m through a payload layout whose venv interpreter is a trap that exits 99. tests/pm + plugin/source/update-completion suites: 1175 passed; the 5 failures also fail on origin/main in this environment. Not verified: a real MSIX. uv execs the venv interpreter to query it during sync/pip (confirmed on macOS by trapping venv/bin/python), so plugin installs depend on uv, a child of the in-package PM worker, keeping package access to that redirector.
43 lines
1.7 KiB
Python
43 lines
1.7 KiB
Python
"""Pinned tool acquisition for PM's private Python engine; never worker API."""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from pm.filesystem import native
|
|
from pm.package import InstallError
|
|
from pm.registry import get_package
|
|
from pm.store import current_target
|
|
|
|
|
|
def _toolchain(*, realize: bool = True, explicit: bool = False) -> tuple[Path, Path] | None:
|
|
"""Resolve uv and Python without host discovery or recursive worker dispatch.
|
|
|
|
A read-only probe never installs. A sealed payload builds on its own
|
|
interpreter: a venv's redirectors then name a path inside the package, so
|
|
nothing may run them (``pm.environments.venv_command`` enters such a venv).
|
|
"""
|
|
from pm.install import _installed_location, _lockfile, ensure
|
|
|
|
if realize:
|
|
ensure("uv", explicit=explicit)
|
|
|
|
lockfile = _lockfile()
|
|
target = current_target()
|
|
binaries = {}
|
|
for name in ("uv", "python"):
|
|
package = get_package(name)
|
|
location = _installed_location(package, lockfile, target)
|
|
if location is None:
|
|
if not realize:
|
|
return None
|
|
raise InstallError(name, "pinned tool is unavailable", "run `hermes pm install`")
|
|
facts, store = location
|
|
binary = package.binary(store.entry(facts.get(name)["entry"]), target)
|
|
if binary is None or not binary.is_file():
|
|
if not realize:
|
|
return None
|
|
raise InstallError(name, "installed binary is missing", "run `hermes pm install`")
|
|
binaries[name] = binary
|
|
# Callers execute and compare these outside PM's own file calls: the ordinary spelling, not the store's.
|
|
return Path(native(binaries["uv"])), Path(native(binaries["python"]))
|