bootstrap¶
otto’s composition root: repo discovery + contained user-code registration.
Replaces configmodule’s import-time side effects. Phase 1 (discovery)
parses the environment and repo settings.toml files — no user code runs.
Phase 2 (registration) imports each repo’s init modules and test files,
wrapping every user-module exec so one broken file becomes a framed
BootstrapError instead of bricking the process. Lab loading is
deliberately NOT part of bootstrap — it happens lazily at first access.
bootstrap() is idempotent: the CLI entrypoint calls it before argv
parsing, open_context() calls it lazily, and repeated calls return the
same BootstrapResult.
- exception otto.bootstrap.BootstrapError(sut_dir: Any, source: str, cause: BaseException)¶
Bases:
ExceptionOne user file failed to load during bootstrap registration.
- class otto.bootstrap.BootstrapResult(env: OttoEnvSettings, repos: list[Repo], errors: list[~otto.bootstrap.BootstrapError] = <factory>)¶
Bases:
objectEverything bootstrap produced: environment, repos, contained errors.
- env : OttoEnvSettings¶
- errors : list[BootstrapError]¶
- otto.bootstrap.discover() tuple[OttoEnvSettings, list[Repo]]¶
Phase 1: env + repo discovery (settings parse only — no user code). Cached.
Per-repo config-data failures (unreadable or malformed
settings.toml) get the same containment as phase-2 user-code failures: the repo is skipped and a framedBootstrapErroris recorded, surfacing viabootstrap().errors(help degrades, real dispatch fails loud). Env-level failures (badOTTO_SUT_DIRS/ OTTO_* values) still raise — with no environment there is nothing to degrade to.
- otto.bootstrap.bootstrap() BootstrapResult¶
Run the composition root (idempotent): discovery + contained registration.