Files
bot-bottle/bot_bottle/backend/docker/__init__.py
T
didericis 923d44bc09
tracker-policy-pr / check-pr (pull_request) Successful in 15s
test / integration-docker (pull_request) Successful in 20s
lint / lint (push) Successful in 53s
test / unit (pull_request) Failing after 2m5s
test / integration-firecracker (pull_request) Successful in 3m27s
test / coverage (pull_request) Has been skipped
test / publish-infra (pull_request) Has been skipped
refactor(backend): thin the docker/firecracker/macos-container package inits
The three concrete-backend package inits eagerly imported their
`*BottleBackend` (which pulls the whole framework), so importing any leaf under
them (e.g. `backend.docker.util`) paid ~78 modules. Give each the same thin
`__getattr__` treatment as the top-level backend package: re-export the public
class(es) lazily on first access, with a TYPE_CHECKING block for checkers.

`import bot_bottle.backend.docker.util` drops from 78 -> 6 bot_bottle modules;
the docker/firecracker/macos-container packages themselves are ~3 each. All
`from bot_bottle.backend.docker import DockerBottleBackend` call-sites and the
lazy selection path keep working.

This is what makes backend leaves cheap — and unblocks moving docker_cmd into
backend/docker/util if we want.

Full unit suite green (2243).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 15:53:48 -04:00

57 lines
1.8 KiB
Python

"""Docker bottle backend.
The bulk of the implementation lives in sibling modules:
- util: thin Docker subprocess wrappers
- network: Docker network plumbing
- bottle_plan: DockerBottlePlan
- bottle_cleanup_plan: DockerBottleCleanupPlan
- bottle: DockerBottle handle
- prepare: host-side resolution into a DockerBottlePlan
- launch: bring-up + teardown context manager
- cleanup: orphan enumeration, removal, active listing
- backend: DockerBottleBackend façade wiring the above
- infra: DockerInfraService (the per-host infra container)
Thin by design: the public names are re-exported lazily via `__getattr__`, so
importing a leaf like `backend.docker.util` doesn't drag `DockerBottleBackend`
(and the whole framework it pulls) into memory.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from .backend import DockerBottleBackend
from .bottle import DockerBottle
from .bottle_cleanup_plan import DockerBottleCleanupPlan
from .bottle_plan import DockerBottlePlan
_LAZY_MODULES: dict[str, str] = {
"DockerBottleBackend": "backend",
"DockerBottle": "bottle",
"DockerBottleCleanupPlan": "bottle_cleanup_plan",
"DockerBottlePlan": "bottle_plan",
}
def __getattr__(name: str) -> Any:
mod = _LAZY_MODULES.get(name)
if mod is None:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
from importlib import import_module
value = getattr(import_module(f"{__name__}.{mod}"), name)
globals()[name] = value
return value
__all__ = [
"DockerBottle",
"DockerBottleBackend",
"DockerBottleCleanupPlan",
"DockerBottlePlan",
]