refactor(pm): extract worker command and error mapping from _request

Choosing the worker command (including the cold-runtime lazy refusal and
its receipt) and mapping a worker error back to a caller exception move
out of pm.client._request. Behaviour is unchanged; CC drops from 40 to 26.
This commit is contained in:
ethernet
2026-09-24 14:00:23 -04:00
parent 3e256363a4
commit 477565073a

View File

@@ -26,10 +26,71 @@ def _missing_or_refuse(name):
return missing
def _refuse_cold_runtime(cold: InstallError, arguments) -> InstallError:
"""Record a lazy sync refused because PM's own runtime is missing; return the error to raise."""
from pm import receipt
exc = cold
if arguments.get("extras"):
# The user asked for an extra, not for PM's own runtime: name
# the command that provisions both.
from pm.extras import install_hint
exc = InstallError(cold.package, f"{cold.cause} while enabling {list(arguments['extras'])}",
"run `" + "`, `".join(install_hint(extra) for extra in arguments["extras"]) + "`")
token = receipt.begin("sync")
try:
receipt.record_refusal("lazy-install", str(exc))
receipt.record_step("dependency-sync", False, f"{type(exc).__name__}: {exc}")
finally:
receipt.finalize("failed", 1, token=token)
return exc
def _worker_command(spec, arguments, worker: Path, environment: dict) -> list[str]:
"""How to start the worker; may disable lazy installs in *environment*."""
from pm.install import lazy_installs_allowed
from pm.registry import get_package
# Bootstrap precedes dispatch and must share the operation's selected cache.
cache = Path(arguments["cache"]) if arguments.get("cache") is not None else None
state_sync = spec.bootstrap == "policy" or (
spec.bootstrap == "state" and isinstance(get_package(arguments["name"]), StatePackage))
if (state_sync and not arguments.get("explicit") and not arguments.get("repair")
and not lazy_installs_allowed()):
# A ready PM still decides no-op/refusal under its install lock. A cold
# PM is itself a missing prerequisite, not permission to bootstrap tools.
try:
command = runtime_command(worker, bootstrap=False, cache=cache)
except InstallError as cold:
raise _refuse_cold_runtime(cold, arguments) from None
environment["HERMES_DISABLE_LAZY_INSTALLS"] = "1"
return command
if spec.bootstrap == "never":
return runtime_command(worker, bootstrap=False, cache=cache)
return runtime_command(worker, cache=cache)
_WORKER_ERRORS = {"ValueError": ValueError, "TypeError": TypeError, "KeyError": KeyError,
"OSError": OSError, "FileExistsError": FileExistsError,
"FileNotFoundError": FileNotFoundError, "PermissionError": PermissionError}
def _raise_worker_error(error: dict):
"""Re-raise a worker failure as the caller-side exception it names."""
if "package" in error:
from pm.workspace import ResolutionConflict
kind = ResolutionConflict if error["type"] == "ResolutionConflict" else InstallError
raise kind(error["package"], error["cause"], error["remedy"])
if error["type"] == "DownloadPaused":
from pm.downloader import DownloadPaused
raise DownloadPaused(error["message"])
raise _WORKER_ERRORS.get(error["type"], RuntimeError)(error["message"])
def _request(operation, arguments, *, callbacks=None, pause_event=None, project_root=None):
from pm import receipt
from pm.install import lazy_installs_allowed
from pm.registry import get_package, package_definitions
from pm.registry import package_definitions
request_id = uuid.uuid4().hex
update_id = receipt._ambient_update_id()
@@ -46,38 +107,8 @@ def _request(operation, arguments, *, callbacks=None, pause_event=None, project_
"lockfile": str(paths.lockfile_path())},
}
worker = Path(__file__).with_name("worker.py").resolve()
# Bootstrap precedes dispatch and must share the operation's selected cache.
cache = Path(arguments["cache"]) if arguments.get("cache") is not None else None
environment = runtime_environment()
state_sync = spec.bootstrap == "policy" or (
spec.bootstrap == "state" and isinstance(get_package(arguments["name"]), StatePackage))
if (state_sync and not arguments.get("explicit") and not arguments.get("repair")
and not lazy_installs_allowed()):
# A ready PM still decides no-op/refusal under its install lock. A cold
# PM is itself a missing prerequisite, not permission to bootstrap tools.
try:
command = runtime_command(worker, bootstrap=False, cache=cache)
except InstallError as cold:
exc = cold
if arguments.get("extras"):
# The user asked for an extra, not for PM's own runtime: name
# the command that provisions both.
from pm.extras import install_hint
exc = InstallError(cold.package, f"{cold.cause} while enabling {list(arguments['extras'])}",
"run `" + "`, `".join(install_hint(extra) for extra in arguments["extras"]) + "`")
token = receipt.begin("sync")
try:
receipt.record_refusal("lazy-install", str(exc))
receipt.record_step("dependency-sync", False, f"{type(exc).__name__}: {exc}")
finally:
receipt.finalize("failed", 1, token=token)
raise exc from None
environment["HERMES_DISABLE_LAZY_INSTALLS"] = "1"
elif spec.bootstrap == "never":
command = runtime_command(worker, bootstrap=False, cache=cache)
else:
command = runtime_command(worker, cache=cache)
command = _worker_command(spec, arguments, worker, environment)
callback_error = None
stopped = threading.Event()
write_lock = threading.Lock()
@@ -136,18 +167,7 @@ def _request(operation, arguments, *, callbacks=None, pause_event=None, project_
if callback_error is not None:
raise callback_error
if "error" in response:
error = response["error"]
if "package" in error:
from pm.workspace import ResolutionConflict
kind = ResolutionConflict if error["type"] == "ResolutionConflict" else InstallError
raise kind(error["package"], error["cause"], error["remedy"])
if error["type"] == "DownloadPaused":
from pm.downloader import DownloadPaused
raise DownloadPaused(error["message"])
kind = {"ValueError": ValueError, "TypeError": TypeError, "KeyError": KeyError,
"OSError": OSError, "FileExistsError": FileExistsError,
"FileNotFoundError": FileNotFoundError, "PermissionError": PermissionError}.get(error["type"], RuntimeError)
raise kind(error["message"])
_raise_worker_error(response["error"])
return response["result"]
finally:
stopped.set()