64a31a382b
Adds pyrightconfig.json (strict, Python 3.11) covering cli.py, claude_bottle/, and tests/. Fixes the 49 strict-mode errors: - Type DockerBottle.teardown as Callable[[], None]. - ResolvedEnv default_factory uses parameterized list[str] / dict[str, str]. - Erase BottleBackend generics at the registry boundary (BottleBackend[Any, Any]) since selection is runtime-driven and callers use the unparameterized interface. - DockerBottleBackend.launch returns Generator[DockerBottle, None, None]; @contextmanager now flags Iterator returns as deprecated. - Sidestep cli.list submodule shadowing builtins.list in main()'s argv annotation via an aliased re-import in cli/__init__.py. - Cast cfg[...] results in test_pipelock_yaml at the dict[str, object] boundary. - Annotate write_fixture's fn parameter and _manifest_with_runtime's return type.
53 lines
1.4 KiB
Python
53 lines
1.4 KiB
Python
"""DockerBottle — concrete Bottle handle yielded by
|
|
DockerBottleBackend.launch.
|
|
|
|
Holds the container name plus the in-container prompt path so
|
|
exec_claude can transparently add --append-system-prompt-file when a
|
|
prompt was provisioned.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
from typing import Callable
|
|
|
|
from .. import Bottle
|
|
|
|
|
|
class DockerBottle(Bottle):
|
|
"""Concrete Bottle for Docker."""
|
|
|
|
def __init__(
|
|
self,
|
|
container: str,
|
|
teardown: Callable[[], None],
|
|
prompt_path_in_container: str | None,
|
|
):
|
|
self.name = container
|
|
self._teardown = teardown
|
|
self._prompt_path = prompt_path_in_container
|
|
self._closed = False
|
|
|
|
def exec_claude(self, argv: list[str], *, tty: bool = True) -> int:
|
|
full_argv = list(argv)
|
|
if self._prompt_path:
|
|
full_argv.extend(["--append-system-prompt-file", self._prompt_path])
|
|
cmd = ["docker", "exec"]
|
|
if tty:
|
|
cmd.append("-it")
|
|
cmd.extend([self.name, "claude", *full_argv])
|
|
return subprocess.run(cmd).returncode
|
|
|
|
def cp_in(self, host_path: str, container_path: str) -> None:
|
|
subprocess.run(
|
|
["docker", "cp", host_path, f"{self.name}:{container_path}"],
|
|
stdout=subprocess.DEVNULL,
|
|
check=True,
|
|
)
|
|
|
|
def close(self) -> None:
|
|
if self._closed:
|
|
return
|
|
self._closed = True
|
|
self._teardown()
|